[cig-commits] commit: Add in original muparserx

Mercurial hg at geodynamics.org
Wed Nov 9 00:47:47 PST 2011


changeset:   388:5a4d909d9533
user:        Walter Landry <wlandry at caltech.edu>
date:        Tue Nov 08 10:39:59 2011 -0800
files:       muparserx/COPYING.txt muparserx/Makefile muparserx/Readme.txt muparserx/doc/custom/Main.txt muparserx/doc/custom/calc.cpp muparserx/doc/custom/example.txt muparserx/doc/custom/features.txt muparserx/doc/custom/footer.html muparserx/doc/custom/list_expr_var.cpp muparserx/doc/custom/listvar.cpp muparserx/doc/doxyfile.dox muparserx/doc/muParserX.jpg muparserx/doc/muParserX.png muparserx/doc/muParserX_2.png muparserx/parser/Lib_Parser.vcproj muparserx/parser/mpDefines.h muparserx/parser/mpError.cpp muparserx/parser/mpError.h muparserx/parser/mpFuncCmplx.cpp muparserx/parser/mpFuncCmplx.h muparserx/parser/mpFuncCommon.cpp muparserx/parser/mpFuncCommon.h muparserx/parser/mpFuncMatrix.cpp muparserx/parser/mpFuncMatrix.h muparserx/parser/mpFuncNonCmplx.cpp muparserx/parser/mpFuncNonCmplx.h muparserx/parser/mpFuncStr.cpp muparserx/parser/mpFuncStr.h muparserx/parser/mpFwdDecl.h muparserx/parser/mpICallback.cpp muparserx/parser/mpICallback.h muparserx/parser/mpIOprt.cpp muparserx/parser/mpIOprt.h muparserx/parser/mpIPackage.cpp muparserx/parser/mpIPackage.h muparserx/parser/mpIPrecedence.h muparserx/parser/mpIToken.cpp muparserx/parser/mpIToken.h muparserx/parser/mpIValReader.cpp muparserx/parser/mpIValReader.h muparserx/parser/mpIValue.cpp muparserx/parser/mpIValue.h muparserx/parser/mpIfThenElse.cpp muparserx/parser/mpIfThenElse.h muparserx/parser/mpMatrix.h muparserx/parser/mpMatrixError.h muparserx/parser/mpOprtBinAssign.cpp muparserx/parser/mpOprtBinAssign.h muparserx/parser/mpOprtBinCommon.cpp muparserx/parser/mpOprtBinCommon.h muparserx/parser/mpOprtCmplx.cpp muparserx/parser/mpOprtCmplx.h muparserx/parser/mpOprtIndex.cpp muparserx/parser/mpOprtIndex.h muparserx/parser/mpOprtMatrix.cpp muparserx/parser/mpOprtMatrix.h muparserx/parser/mpOprtNonCmplx.cpp muparserx/parser/mpOprtNonCmplx.h muparserx/parser/mpPackageCmplx.cpp muparserx/parser/mpPackageCmplx.h muparserx/parser/mpPackageCommon.cpp muparserx/parser/mpPackageCommon.h muparserx/parser/mpPackageMatrix.cpp muparserx/parser/mpPackageMatrix.h muparserx/parser/mpPackageNonCmplx.cpp muparserx/parser/mpPackageNonCmplx.h muparserx/parser/mpPackageStr.cpp muparserx/parser/mpPackageStr.h muparserx/parser/mpPackageUnit.cpp muparserx/parser/mpPackageUnit.h muparserx/parser/mpParser.cpp muparserx/parser/mpParser.h muparserx/parser/mpParserBase.cpp muparserx/parser/mpParserBase.h muparserx/parser/mpRPN.cpp muparserx/parser/mpRPN.h muparserx/parser/mpScriptTokens.cpp muparserx/parser/mpScriptTokens.h muparserx/parser/mpStack.h muparserx/parser/mpTest.cpp muparserx/parser/mpTest.h muparserx/parser/mpTokenReader.cpp muparserx/parser/mpTokenReader.h muparserx/parser/mpTypes.h muparserx/parser/mpValReader.cpp muparserx/parser/mpValReader.h muparserx/parser/mpValue.cpp muparserx/parser/mpValue.h muparserx/parser/mpValueCache.cpp muparserx/parser/mpValueCache.h muparserx/parser/mpVariable.cpp muparserx/parser/mpVariable.h muparserx/parser/muParser.suo muparserx/parser/suSortPred.h muparserx/parser/utGeneric.h muparserx/sample/example.cpp muparserx/sample/timer.cpp muparserx/sample/timer.h muparserx/value_test/AssemblyInfo.cpp muparserx/value_test/ReadMe.txt muparserx/value_test/UpgradeLog.XML muparserx/value_test/app.ico muparserx/value_test/app.rc muparserx/value_test/mpDefines.h muparserx/value_test/mpError.cpp muparserx/value_test/mpError.h muparserx/value_test/mpFwdDecl.h muparserx/value_test/mpIPrecedence.h muparserx/value_test/mpIToken.cpp muparserx/value_test/mpIToken.h muparserx/value_test/mpIValReader.h muparserx/value_test/mpIValue.cpp muparserx/value_test/mpIValue.h muparserx/value_test/mpTypes.h muparserx/value_test/mpValue.cpp muparserx/value_test/mpValue.h muparserx/value_test/mpValueCache.cpp muparserx/value_test/mpValueCache.h muparserx/value_test/mpVariable.cpp muparserx/value_test/mpVariable.h muparserx/value_test/muMatrix.h muparserx/value_test/muMatrixError.h muparserx/value_test/muMatrixTest.cpp muparserx/value_test/muMatrixTest.h muparserx/value_test/resource.h muparserx/value_test/stdafx.cpp muparserx/value_test/stdafx.h muparserx/value_test/suSortPred.h muparserx/value_test/value_test.cpp muparserx/value_test/value_test.sln muparserx/value_test/value_test.sln.old muparserx/value_test/value_test.suo.old muparserx/value_test/value_test.vcproj muparserx/value_test/value_test.vcproj.NB1.user.user muparserx/value_test/value_test.vcxproj muparserx/value_test/value_test.vcxproj.filters muparserx/value_test/value_test.vcxproj.user muparserx/vs8/muparserX.sln muparserx/vs8/muparserx.vcproj
description:
Add in original muparserx


diff -r 458e51062300 -r 5a4d909d9533 muparserx/COPYING.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/COPYING.txt	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,165 @@
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff -r 458e51062300 -r 5a4d909d9533 muparserx/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/Makefile	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,74 @@
+CC	=	g++
+# debug version
+#CFLAGS  = -Wall -ggdb  
+# release version:
+CFLAGS	=	-O3 -ffast-math -fomit-frame-pointer 
+
+PATH_BIN = ./bin
+
+########################################################################################################
+# muParser library sources
+PATH_LIB = ./parser
+PATH_OBJ = ./obj
+LIB_SRC = mpError.cpp mpRPN.cpp mpICallback.cpp mpIValReader.cpp mpParserBase.cpp mpTokenReader.cpp\
+          mpVariable.cpp mpIOprt.cpp mpIValue.cpp mpParser.cpp mpValReader.cpp mpFuncStr.cpp\
+		  mpFuncCommon.cpp mpFuncNonCmplx.cpp mpFuncCmplx.cpp mpIToken.cpp mpOprtCmplx.cpp \
+		  mpOprtNonCmplx.cpp mpOprtBinCommon.cpp mpOprtBinAssign.cpp mpOprtMatrix.cpp\
+          mpIPackage.cpp mpPackageCommon.cpp mpPackageStr.cpp mpPackageCmplx.cpp mpPackageNonCmplx.cpp\
+          mpPackageMatrix.cpp mpPackageUnit.cpp mpIfThenElse.cpp mpValueCache.cpp mpValue.cpp mpTest.cpp\
+		  mpScriptTokens.cpp mpFuncMatrix.cpp mpOprtIndex.cpp
+LIB_OBJ = ${LIB_SRC:.cpp=.o}
+NAME_LIB = libmuparserx.a
+
+########################################################################################################
+# example application
+PATH_SAMPLE = ./sample
+
+
+all:	example
+
+new:  clean example
+
+$(NAME_LIB):	$(LIB_OBJ)
+	@echo ""
+	@echo "#########################################################"
+	@echo "#                                                       #"
+	@echo "#   Building libmuparserX                               #"
+	@echo "#                                                       #"
+	@echo "#########################################################"
+	@echo ""
+
+	ar ru $(NAME_LIB) $(LIB_OBJ:%.o=$(PATH_OBJ)/%.o)
+	ranlib $(NAME_LIB)
+	mv $(NAME_LIB) bin/
+
+$(LIB_OBJ):
+	$(CC) $(CFLAGS) -c $(PATH_LIB)/${@:.o=.cpp} -o $(PATH_OBJ)/$@
+
+example:	$(NAME_LIB)
+	@echo ""
+	@echo "#########################################################"
+	@echo "#                                                       #"
+	@echo "#   Building sample                                     #"
+	@echo "#                                                       #"
+	@echo "#########################################################"
+	@echo ""
+	$(CC) $(CFLAGS) -I$(PATH_LIB) -L$(PATH_BIN) -o $(PATH_BIN)/$@ $(PATH_SAMPLE)/example.cpp $(PATH_SAMPLE)/timer.cpp -lmuparserx -lm
+
+clean:
+	#@clear
+	@echo "########################################################"
+	@echo "#                                                      #"
+	@echo "#  Cleaning up                                         #"
+	@echo "#                                                      #"
+	@echo "########################################################"
+	@echo ""
+	rm -rf *.o 
+	rm -rf *~
+	rm -rf libmuparserx.a
+	rm -rf $(PATH_OBJ)/*
+	rm -rf $(PATH_BIN)/*
+
+new:	
+	$(MAKE) clean
+	$(MAKE) all
diff -r 458e51062300 -r 5a4d909d9533 muparserx/Readme.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/Readme.txt	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,198 @@
+#########################################################################
+#                                                                       #
+#                                                                       #
+#                                                                       #
+#               __________                                 ____  ___    #
+#    _____  __ _\______   \_____ _______  ______ __________\   \/  /    #
+#   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     /     #
+#  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \     #
+#  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \    #
+#        \/                     \/           \/     \/           \_/    #
+#                                                                       #
+#  http://muparserx.beltoforion.de                                      #
+#  (C) 2011 Ingo Berg                                                   #
+#                                                                       #
+#########################################################################
+
+#########################################################################
+#                                                                       #
+#  Version history                                                      #
+#                                                                       #
+#########################################################################
+
+V2.0.1 (20111014)
+-----------------
+Bugfixes:
+  - Issue 1 fixed: Assertion when using a function with multiple arguments 
+    in the same expression twice with different number of arguments.
+    (Reference: http://code.google.com/p/muparserx/issues/detail?id=1)
+
+V2.0.0 (20111009)
+-----------------
+
+Changes:
+- Fundamental datatype changed to a matrix type instead of a vector type
+- Multidimensional index operator added
+  old:
+	"m[1][2] = 1"
+  new:
+	"m[1,2] = 1"
+
+- type identifier for matrices is now 'm', formerly 'a' was used to 
+  indicate arrays. An arrays are now seen as subsets of matrices, there is no 
+  special type for arrays.
+
+Bugfixes:
+- Matrix addition and subtraction work properly now.
+
+
+V1.10.2 (20110911)
+------------------
+Bugfixes:
+- Fix for changed behaviour of tellg in GCC 4.6.1. A Space is now appended 
+  to every expression in order to avoid problems.
+
+
+V1.10 (20110310)
+----------------
+Warning:
+The API of this version is not backwards compatible and requires minor 
+changes to client code!
+
+Changes:
+- Static type checking removed entirely
+  (All type checking must be made at runtime by the callbacks themself)
+- Optimizer removed. The optimizer had only limited effect since it only
+  implemented a very simple constant folding mechanism. It collided with 
+  the new if-then-else logic and had to go. It will probably be reintroduced
+  in one of the next versions using a different implementation.
+- Expressions can now span multiple lines. This only makes sense when used
+  together with the assignment operator i.e.:
+
+		a=1
+		b=2
+		c=3
+		sin(a+b+c)
+
+
+Bugfixes:
+- Nested if-then-else did not work properly
+- Sign operators extended to work with arrays
+- Operators "==" and "!=" did not work properly for arrays
+- Relational operators "<", ">", "<=", ">=" did not work for complex numbers
+- GCC makefile was broken in V1.09
+- complex multiplication did not work correctly; 
+  was:
+	 (a+ib)(c+id)=>re=ac-bd;im=ad-bc 
+  instead of:
+         (a+ib)(c+id)=>re=ac-bd;im=ad+bc 
+- Expressions with parameterless functions like a=foo() did not evaluate properly.
+
+
+V1.09 (20101120)
+----------------
+Changes:
+- Performance increased by factor 4 due to introducing a simple memory pool for value items.
+- C++ like if-then-else operator added ( "(a<b) ? c : d")
+
+Bugfixes:
+- Memory leak fixed which prevented operator and funtion items from beeing released.
+
+
+V1.08 (20100902)
+----------------
+Changes:
+- Implicit creation of unknown variables at parser runtime is now possibe
+  (i.e. expressions like "a=0"; with a beeing a undefined variable).
+- Callbacks can now be organized in packages
+- Callbacks split into a complex and a non complex package
+- Complex power operator added
+
+Bugfixes:
+- Assignment operators did not work properly for complex values
+- Complex sign operator fixed in order not to mess up 0 by
+  multiplying it with -1 (-0 and 0 ar not the same according to
+  IEEE754) 
+
+
+V1.07 (20100818)
+----------------
+Changes:
+- Parsing performance improved by 20 - 30 % due to removing unnecessary 
+  copy constructor calls when returning the final result.
+- License changed from GPLv3 to LGPLv3
+- Assignment to vector elements is now possible (i.e.: va[1]=9)
+
+Bugfixes:
+- The Value type could not properly handle matrices (vector of vector)
+  uses the reverse polish notation of an expression for the evaluation.
+- Error messages did not display the proper type id's when compiled 
+  with UNICODE support.
+
+
+V1.06 (20100710)
+----------------
+- Parsing performance improved by factor 2-3 due to a change which
+  uses the reverse polish notation of an expression for the evaluation.
+
+
+V1.05 (20100530)
+----------------
+- The parser now handles the associativity of binary operators properly
+- Parsing performance improved by factor 7 due to caching tokens 
+  once an expression is parsed. Successive evaluations will use 
+  the cached tokens instead of parsing from string again.
+
+
+V1.04 (20100516):
+-----------------
+- Querying of expression variables implemented
+- Bugfix for incorrect evaluation of expressions using the index 
+  operator added
+- nil values removed
+- Support for functions without parameters added
+- UNICODE support added
+
+
+V1.03:
+------
+- basic functions rewritten to complex valued functions
+- Unit postfix operators added to the standard setup
+
+
+V1.02:
+------
+- Index operator added
+- addition/subtraction of vectors added
+
+
+V1.01:
+------
+- Complex numbers added with support for basic binary operators
+- Vector type added with support for basic operations (v*v, v+v)
+- Variable class changed to take a pointer to a value class instead
+  of base types like int or double.
+
+
+#########################################################################
+#                                                                       #
+#  Licence                                                              #
+#                                                                       #
+#########################################################################
+
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/Main.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/Main.txt	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,16 @@
+/** \mainpage
+
+<div>
+  <img src="../muParserX.png"/>
+</div>
+
+	\section intro_sec Introduction
+
+	muParserX is a mathematical expression parser with support for complex numbers and matrix calculations.	This is the API documentation of muParserX. 
+	For additional documentation consult the <a href="http://code.google.com/p/muparserx/">project home page at google code</a>.
+
+	\section toc Table of content
+	\ref page_features<br/>
+*/
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/calc.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/calc.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,59 @@
+#include "mpParser.h"
+
+
+void Calc()
+{
+  char line[100];
+  try
+  {
+    // Create value objects that will be bound to parser variables
+    Value fVal = 1.11;
+    Value sVal = "hello world";
+    Value arr1(3, 0);
+    arr1[0] = 1.11, 
+    arr1[1] = 2.22;
+    arr1[2] = 3.33;
+
+    Parser  parser;
+    
+    // Define parser variables and bind them to their value objects
+    parser.DefineVar("va", Variable(&arr1));
+    parser.DefineVar("a",  Variable(&fVal));
+    parser.DefineVar("sa", Variable(&sVal));
+
+    parser.SetExpr("sin(a)+b");
+
+    // The returned result is of type Value, value is a Variant like
+    // type that can be either a boolean an integer or a floating point value
+    Value result = parser.Eval();
+
+    // Value supports C++ streaming like this:
+    cout << "Result:\n" << result << "\n";
+
+    // Or if you need the specific type use this:
+    switch (result.GetType())
+    {
+    case 's': cout << result.GetString() << " (string)" << "\n"; break;
+    case 'i': cout << result.GetInt() << " (int)" << "\n"; break;
+    case 'f': cout << result.GetFloat() << " (float)" << "\n"; break;
+    case 'c': cout << result.GetFloat() << "+" << result.GetImag() << "i (complex)" << "\n"; break;
+    case 'b': break;
+    }
+  }
+  catch(ParserError &e)
+  {
+    cout << e.GetMsg() << "\n\n";
+
+    if (e.GetContext().Ident.length()) 
+      cout << "Ident.: " << e.GetContext().Ident << "\n";
+
+    if (e.GetExpr().length()) 
+      cout << "Expr.: " << e.GetExpr() << "\n";
+
+    if (e.GetToken().length()) 
+      cout << "Token: " << e.GetToken() << "\n";
+
+    cout << "Pos:   " << e.GetPos() << "\n";
+    cout << "Errc:  " << e.GetCode() << "\n";
+  }
+} // Calc()
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/example.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/example.txt	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,15 @@
+/** \example listvar.cpp
+    This example shows how to list parser variables.
+*/
+
+/** \example list_expr_var.cpp
+  This example shows how to list variables used in an expression.
+*/
+
+/** \example calc.cpp
+    This example shows a typical use case of muParser. It sets up the parser 
+    engine and is defining several variables.
+*/
+}    
+*/
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/features.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/features.txt	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,69 @@
+/*! \page page_features Features
+\section fea_overview Feature overview
+
+<ul>
+<li>Supported data types: <b>double, integer, complex, boolean, string, array</b></li>
+<li>Extensible with custom operators (<b>binary, infix or postfix</b>)</li>
+<li>Extensible with custom functions with an arbitrary number of function arguments</li>
+<li>Support for an unlimited number of variables and constants</li>
+<li>No limit on expression complexity</li>
+<li>Reads binary, hexadecimal, complex, integer and string values from expressions and
+    can be extended to read user defined values as well.</li>
+<li>Supports a large variety of predefined \ref fea_predefined_op, \ref fea_predefined_fun
+     and \ref fea_predefined_const.</li>    
+</ul>
+
+\section fea_predefined_const Predefined Constants
+By default the parser supports the following mathematical constants:
+<ul>
+	<li>The eulerian number with:<br/>
+	    <b>e</b> = 2.718281828459045235360287<br/>&nbsp;</li>
+	<li>The mathematical constant equal to a circle's circumference divided by its diameter.<br/>
+	    <b>pi</b> =  3.141592653589793238462643<br/>&nbsp;</li>
+	<li>The imaginary unit with:<br/>
+	    <b>i</b> = sqrt(-1)<br/>&nbsp;</li>
+</ul>	
+	
+\section fea_predefined_op Predefined Operators
+<h3>Binary operators:</h3>
+<ul>
+  <li>Standard operators:<br/>
+  <b>"+", "-", "*", "/", "^"</b><br/>&nbsp;</li>
+  <li>Assignment operators:<br/>
+  <b>"=", "+=", "-=", "*=", "/="</b><br/>&nbsp;</li>
+  <li>Logical operators:<br/>
+  <b>"and", "or", "xor","==", "!=", ">", "<", "<=", ">="</b><br/>&nbsp;</li>
+  <li>Bit manipulation:<br/>
+  <b>"&", "|", "<<", ">>"</b><br/>&nbsp;</li>
+  <li>String concatenation:<br/>
+  <b>"//"</b><br/>&nbsp;</li>
+</ul>
+
+<h3>Postfix operators:</h3>
+<ul>
+  <li>Unit postfixes (nano, micro, milli, kilo, giga, mega):<br/>
+  <b>"{n}", "{mu}", "{m}", "{k}", "{G}", "{M}"</b><br/>&nbsp;</li>
+</ul>
+
+<p/>
+<h3>Infix operators:</h3>
+<ul>
+  <li>Sign operator and type conversions:<br/>
+  <b>"-", "(float)", "(int)"</b><br/>&nbsp;</li>
+</ul>
+
+\section fea_predefined_fun Predefined Functions
+<ul>
+  <li>Standard functions:<br/>
+  <b>abs, sin, cos, tan, sinh, cosh, tanh, ln, log, log10, exp, sqrt</b><br/>&nbsp;</li>
+  <li>Unlimited number of arguments:<br/>
+  <b>min, max, sum</b><br/>&nbsp;</li>
+  <li>String functions:<br/>
+  <b>str2dbl, strlen, toupper</b><br/>&nbsp;</li>
+  <li>Complex functions:<br/>
+  <b>real, imag, conj, arg, norm</b><br/>&nbsp;</li>  
+  <li>Array functions:<br/>
+  <b>sizeof</b><br/>&nbsp;</li>  
+</ul>  
+
+*/
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/footer.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/footer.html	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,19 @@
+<div style="position:absolute; width:100%; height:100%; text-align:center;">
+<p>
+<hr/>
+<strong>muParserX</strong> documentation - (C) 2010 <a href="http://beltoforion.de">Ingo Berg</a>
+</p>
+</div>
+
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+try {
+var pageTracker = _gat._getTracker("UA-1019178-3");
+pageTracker._trackPageview();
+} catch(err) {}</script>
+
+</body>
+</html>
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/list_expr_var.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/list_expr_var.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,15 @@
+void ListExprVar(const mu::ParserBase &parser)
+{
+  varmap_type variables = parser.GetUsedVar();
+  if (!variables.size())
+    mu::console() << "Expression does not contain variables\n";
+  else
+  {
+    mu::console() << "Number: " << (int)variables.size() << "\n";
+    mu::varmap_type::const_iterator item = variables.begin();
+
+    for (; item!=variables.end(); ++item)
+      mu::console() << "Name: " << item->first << "   Address: [0x" << item->second << "]\n";
+  }
+}
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/custom/listvar.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/custom/listvar.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,13 @@
+void ListVar(const mu::ParserBase &parser)
+{
+  mu::varmap_type variables = parser.GetVar();
+  if (!variables.size())
+    return;
+
+  cout << "\nParser variables:\n";
+  cout <<   "-----------------\n";
+  cout << "Number: " << (int)variables.size() << "\n";
+  varmap_type::const_iterator item = variables.begin();
+  for (; item!=variables.end(); ++item)
+    mu::console() << _T("Name: ") << item->first << _T("   Address: [0x") << item->second << _T("]\n");
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/doxyfile.dox
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/doc/doxyfile.dox	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,1755 @@
+# Doxyfile 1.7.5.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should 
+# identify the project. Note that if you do not use Doxywizard you need 
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = muParserX
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 2.0.0
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description 
+# for a project that appears at the top of each page and should give viewer 
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is 
+# included in the documentation. The maximum height of the logo should not 
+# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful if your file system 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it 
+# parses. With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this 
+# tag. The format is ext=language, where ext is a file extension, and language 
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also makes the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
+# unions are shown inside the group in which they are included (e.g. using 
+# @ingroup) instead of on a separate page (for HTML and Man pages) or 
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
+# unions with only public data fields will be shown inline in the documentation 
+# of the scope in which they are defined (i.e. file, namespace, or group 
+# documentation), provided this scope is documented. If set to NO (the default), 
+# structs, classes, and unions are shown on a separate page (for HTML and Man 
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penalty. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will roughly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
+# will sort the (brief and detailed) documentation of class members so that 
+# constructors and destructors are listed first. If set to NO (the default) 
+# the constructors will appear in the respective orders defined by 
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
+# do proper type resolution of all parameters of a function it will reject a 
+# match between the prototype and the implementation of a member function even 
+# if there is only one candidate or it is obvious which candidate to choose 
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or macro consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and macros in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = NO
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
+# by doxygen. The layout file controls the global structure of the generated 
+# output files in an output format independent way. The create the layout file 
+# that represents doxygen's defaults, run doxygen with the -l option. 
+# You can optionally specify a file name after the option, if omitted 
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files 
+# containing the references data. This must be a list of .bib files. The 
+# .bib extension is automatically appended if omitted. Using this command 
+# requires the bibtex tool to be installed. See also 
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
+# of the bibliography can be controlled using LATEX_BIB_STYLE.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../parser \
+                         custom
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.txt \
+                         *.cpp \
+                         *.h \
+                         *.hpp \
+                         *.hh \
+                         *.cc \
+                         *.c
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag. 
+# Note that relative paths are relative to directory from which doxygen is run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix file system feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = custom
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
+# and it is also possible to disable source filtering for a specific pattern 
+# using *.ext= (so without naming a filter). This option only has effect when 
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header. Note that when using a custom header you are responsible  
+# for the proper inclusion of any scripts and style sheets that doxygen 
+# needs, which is dependent on the configuration options used. 
+# It is adviced to generate a default header using "doxygen -w html 
+# header.html footer.html stylesheet.css YourConfigFile" and then modify 
+# that header. Note that the header is subject to change so you typically 
+# have to redo this when upgrading to a newer version of doxygen or when 
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = custom/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
+# other source files which should be copied to the HTML output directory. Note 
+# that these files will be copied to the base HTML output directory. Use the 
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
+# Doxygen will adjust the colors in the stylesheet and background images 
+# according to this color. Hue is specified as an angle on a colorwheel, 
+# see http://en.wikipedia.org/wiki/Hue for more information. 
+# For instance the value 0 represents red, 60 is yellow, 120 is green, 
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
+# the colors in the HTML output. For a value of 0 the output will use 
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
+# the luminance component of the colors in the HTML output. Values below 
+# 100 gradually make the output lighter, whereas values above 100 make 
+# the output darker. The value divided by 100 is the actual gamma applied, 
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 
+# the documentation publisher. This should be a reverse domain-name style 
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help 
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
+# documentation. Note that a value of 0 will completely suppress the enum 
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
+# generated for formulas are transparent PNGs. Transparent PNGs are 
+# not supported properly for IE 6.0, but are supported on all modern browsers. 
+# Note that when changing this option you need to delete any form_*.png files 
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
+# (see http://www.mathjax.org) which uses client side Javascript for the 
+# rendering instead of using prerendered bitmaps. Use this if you do not 
+# have LaTeX installed or if you want to formulas look prettier in the HTML 
+# output. When enabled you also need to install MathJax separately and 
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the 
+# HTML output directory using the MATHJAX_RELPATH option. The destination 
+# directory should contain the MathJax.js script. For instance, if the mathjax 
+# directory is located at the same level as the HTML output directory, then 
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the 
+# mathjax.org site, so you can quickly see the result without installing 
+# MathJax, but it is strongly recommended to install a local copy of MathJax 
+# before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using 
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
+# implemented using a PHP enabled web server instead of at the web client 
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server 
+# based approach is that it scales better to large projects and allows 
+# full text search. The disadvantages are that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
+# the generated latex document. The footer should contain everything after 
+# the last chapter. If it is left blank doxygen will generate a 
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
+# source code with syntax highlighting in the LaTeX output. 
+# Note that which sources are shown also depends on other settings 
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition that 
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all references to function-like macros 
+# that are alone on a line, have an all uppercase name, and do not end with a 
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option also works with HAVE_DOT disabled, but it is recommended to 
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
+# allowed to run in parallel. When set to 0 (the default) doxygen will 
+# base this on the number of processors available in the system. You can set it 
+# explicitly to a value larger than 0 to get control over the balance 
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that 
+# doxygen generates. When you want a differently looking font you can specify 
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
+# the font, which can be done by putting it in a standard location or by setting 
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
+# directory containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font. 
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
+# set the path where dot can find it.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are svg, png, jpg, or gif. 
+# If left blank png will be used. If you choose svg you need to set 
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
+# enable generation of interactive SVG images that allow zooming and panning. 
+# Note that this requires a modern browser other than Internet Explorer. 
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that 
+# contain msc files that are included in the documentation (see the 
+# \mscfile command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/muParserX.jpg
Binary file muparserx/doc/muParserX.jpg has changed
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/muParserX.png
Binary file muparserx/doc/muParserX.png has changed
diff -r 458e51062300 -r 5a4d909d9533 muparserx/doc/muParserX_2.png
Binary file muparserx/doc/muParserX_2.png has changed
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/Lib_Parser.vcproj
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/Lib_Parser.vcproj	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,638 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="muParser2"
+	ProjectGUID="{D8ADEC17-F606-46E1-82CF-DB6339A59287}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muparser2.lib"
+				ModuleDefinitionFile=""
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="&quot;C:\Dokumente und Einstellungen\Ingo\Eigene Dateien\Projekte\Uni_Hydrosim\SharedFiles&quot;"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muparser2.lib"
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release (SingleThread)|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="&quot;C:\Dokumente und Einstellungen\Ingo\Eigene Dateien\Projekte\Uni_Hydrosim\SharedFiles&quot;"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muParser.lib"
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release (MultiThread)|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="&quot;C:\Dokumente und Einstellungen\Ingo\Eigene Dateien\Projekte\Uni_Hydrosim\SharedFiles&quot;"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muParserMT.lib"
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release (MT-DLL)|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				RuntimeLibrary="2"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muParserMTD.lib"
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug (Multithread)|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muParserMT_Dbg.lib"
+				ModuleDefinitionFile=""
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug (MTD)|Win32"
+			OutputDirectory="obj"
+			IntermediateDirectory="obj"
+			ConfigurationType="4"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="muParserMTD_Dbg.lib"
+				IgnoreAllDefaultLibraries="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Quelldateien"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\mpError.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpFuncBasic.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpFuncStr.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpICallback.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIOprt.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIToken.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValReader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValue.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpOprtBasic.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpParser.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpParserBase.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpTokenReader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValReader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValue.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpVariable.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Headerdateien"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\mpDefines.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpError.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpFuncBasic.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpFuncStr.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpICallback.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIOprt.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIToken.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValReader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValue.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpOprtBasic.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpOprtBin.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpOprtBinAssign.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpParser.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpParserBase.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpStack.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpTokenPtr.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpTokenReader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpTypes.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValReader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValue.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpVariable.h"
+				>
+			</File>
+			<File
+				RelativePath=".\suSortPred.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Ressourcendateien"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpDefines.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpDefines.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,100 @@
+/** \file
+    \brief A file containing macros used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2011 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_DEFINES_H
+#define MUP_DEFINES_H
+
+#include <cassert>
+
+
+#if defined(_UNICODE)
+  #if !defined(_T)
+  #define _T(x) L##x
+  #endif // not defined _T
+  #define MUP_STRING_TYPE std::wstring
+#else
+  #ifndef _T
+  /** \brief Macro needed for the "unicodification" of strings.
+  */
+  #define _T(x) x
+  #endif
+  
+  /** \brief The string type used by muParserX. 
+  
+    This macro is needed for UNICODE support.
+  */
+  #define MUP_STRING_TYPE std::string
+#endif
+
+/** \brief A macro containing the version of muParserX. */
+#define MUP_PARSER_VERSION _T("2.0.1 (20111009)")
+
+/** \brief A macro for setting the parser namespace. */
+#define MUP_NAMESPACE_START namespace mup {
+
+/** \brief Closing bracket for the parser namespace macro. */
+#define MUP_NAMESPACE_END }
+
+
+#if defined(_DEBUG)
+  #define MUP_TOK_CAST(TYPE, POINTER)  dynamic_cast<TYPE>(POINTER);
+
+  /** \brief Debug macro to force an abortion of the programm with a certain message.
+  */
+  #define MUP_FAIL(MSG)    \
+          bool MSG=false;  \
+          assert(MSG);
+
+  /** \brief An assertion that does not kill the program.
+
+      This macro is neutralised in UNICODE builds. It's
+      too difficult to translate.
+  */
+  #define MUP_ASSERT(COND)                         \
+          if (!(COND))                             \
+          {                                        \
+            stringstream_type ss;                  \
+            ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \
+               << __FILE__ << _T(" line ")         \
+               << __LINE__ << _T(".");             \
+            throw ParserError( ss.str() );         \
+          }
+  #define MUP_LEAKAGE_REPORT
+#else
+  #define MUP_FAIL(MSG)
+  #define MUP_ASSERT(COND)
+  #define MUP_TOK_CAST(TYPE, POINTER)  static_cast<TYPE>(POINTER);
+#endif
+
+  /** \brief Include tests for features about to be implemented in 
+             the future in the unit test.
+  */
+  //#define MUP_NICE_TO_HAVE
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpError.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpError.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,310 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpError.h"
+#include "mpIToken.h"
+
+
+MUP_NAMESPACE_START
+
+  const ParserErrorMsg ParserErrorMsg::m_Instance;
+
+  //------------------------------------------------------------------------------
+  const ParserErrorMsg& ParserErrorMsg::Instance()
+  {
+    return m_Instance;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type ParserErrorMsg::operator[](unsigned a_iIdx) const
+  {
+    return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
+  }
+
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::~ParserErrorMsg()
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignement operator is deactivated.
+  */
+  ParserErrorMsg& ParserErrorMsg::operator=(const ParserErrorMsg& )
+  {
+    assert(false);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::ParserErrorMsg()
+    :m_vErrMsg(0)
+  {
+    m_vErrMsg.resize(ecCOUNT);
+
+    m_vErrMsg[ecUNASSIGNABLE_TOKEN]      = _T("Undefined token \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecINTERNAL_ERROR]          = _T("Internal error");
+    m_vErrMsg[ecINVALID_NAME]            = _T("Invalid function-, variable- or constant name");
+    m_vErrMsg[ecINVALID_FUN_PTR]         = _T("Invalid pointer to callback function");
+    m_vErrMsg[ecINVALID_VAR_PTR]         = _T("Invalid pointer to variable");
+    m_vErrMsg[ecUNEXPECTED_OPERATOR]     = _T("Unexpected operator \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_EOF]          = _T("Unexpected end of expression at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_COMMA]        = _T("Unexpected comma at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_PARENS  ]     = _T("Unexpected parenthesis \"$IDENT$\" at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_FUN]          = _T("Unexpected function \"$IDENT$\" at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_VAL]          = _T("Unexpected value \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_VAR]          = _T("Unexpected variable \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_STR]          = _T("Unexpected string token found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_CONDITIONAL]  = _T("The \"$IDENT$\" operator must be preceeded by a closing bracket");
+    m_vErrMsg[ecUNEXPECTED_NEWLINE]      = _T("Unexprected newline");
+    m_vErrMsg[ecMISSING_PARENS]          = _T("Missing parenthesis");
+    m_vErrMsg[ecMISSING_ELSE_CLAUSE]     = _T("If-then-else operator is missing an else clause");
+    m_vErrMsg[ecMISPLACED_COLON]         = _T("Misplaced colon at position $POS$");
+    m_vErrMsg[ecTOO_MANY_PARAMS]         = _T("Too many parameters for function \"$IDENT$\"");
+    m_vErrMsg[ecTOO_FEW_PARAMS]          = _T("Too few parameters for function \"$IDENT$\"");
+    m_vErrMsg[ecDIV_BY_ZERO]             = _T("Divide by zero");
+    m_vErrMsg[ecDOMAIN_ERROR]            = _T("Domain error");
+    m_vErrMsg[ecNAME_CONFLICT]           = _T("Name conflict");
+    m_vErrMsg[ecOPT_PRI]                 = _T("Invalid value for operator priority (must be greater or equal to zero)");
+    m_vErrMsg[ecBUILTIN_OVERLOAD]        = _T("Binary operator identifier conflicts with a built in operator");
+    m_vErrMsg[ecUNTERMINATED_STRING]     = _T("Unterminated string starting at position $POS$");
+    m_vErrMsg[ecSTRING_EXPECTED]         = _T("String function called with a non string type of argument");
+    m_vErrMsg[ecVAL_EXPECTED]            = _T("Numerical function called with a non value type of argument");
+    m_vErrMsg[ecTYPE_CONFLICT]           = _T("Value \"$IDENT$\" is of type '$TYPE1$'. There is no implicit conversion to type '$TYPE2$'");
+    m_vErrMsg[ecTYPE_CONFLICT_FUN]       = _T("Argument $ARG$ of function/operator \"$IDENT$\" is of type '$TYPE1$' whereas type '$TYPE2$' was expected");
+    m_vErrMsg[ecTYPE_CONFLICT_IDX]       = _T("Index to \"$IDENT$\" must be a positive integer value. '$TYPE1$' is not an acceptable type.");
+    m_vErrMsg[ecGENERIC]                 = _T("Parser error");
+    m_vErrMsg[ecINVALID_TYPE]            = _T("Invalid argument type");
+    m_vErrMsg[ecINVALID_TYPECAST]        = _T("Value type conversion from type '$TYPE1$' to '$TYPE2$' is not supported!");
+    m_vErrMsg[ecARRAY_SIZE_MISMATCH]     = _T("Array size mismatch");
+    m_vErrMsg[ecNOT_AN_ARRAY]            = _T("Using the index operator on the scalar variable \"$IDENT$\" is not allowed");
+    m_vErrMsg[ecUNEXPECTED_SQR_BRACKET]  = _T("Unexpected \"]\"");
+    m_vErrMsg[ecAPI_INVALID_PROTOTYPE]   = _T("Invalid prototype (use something like: \"f:fff\")");
+    m_vErrMsg[ecAPI_NOT_AN_ARRAY]        = _T("Not an array");
+    m_vErrMsg[ecAPI_INVALID_DIMENSION]   = _T("Invalid matrix dimensions");
+    m_vErrMsg[ecINDEX_OUT_OF_BOUNDS]     = _T("Index to variable \"$IDENT$\" is out of bounds");
+    m_vErrMsg[ecINDEX_DIMENSION]         = _T("Index operator dimension error");
+    m_vErrMsg[ecMISSING_SQR_BRACKET]     = _T("Missing \"]\"");
+    m_vErrMsg[ecASSIGNEMENT_TO_VALUE]    = _T("Assignment operator \"$IDENT$\" can't be used in this context");
+    m_vErrMsg[ecEVAL]                    = _T("Can't evaluate function/operator \"$IDENT$\": $HINT$");
+    m_vErrMsg[ecINVALID_PARAMETER]       = _T("Parameter $ARG$ of function \"$IDENT$\" is invalid");
+    m_vErrMsg[ecINVALID_NUMBER_OF_PARAMETERS] = _T("Invalid number of function arguments");
+
+    #if defined(_DEBUG)
+      for (int i=0; i<ecCOUNT; ++i)
+        if (!m_vErrMsg[i].length())
+          assert(false);
+    #endif
+  }
+
+  //---------------------------------------------------------------------------
+  //
+  //  Error context
+  //
+  //---------------------------------------------------------------------------
+
+  /** \brief Constructs an empty Error context structure. */
+  ErrorContext::ErrorContext(EErrorCodes a_iErrc, 
+                             int a_iPos, 
+                             string_type a_sIdent)
+    :Expr()
+    ,Ident(a_sIdent)
+    ,Hint()
+    ,Errc(a_iErrc)
+    ,Type1(0)
+    ,Type2(0)
+    ,Arg(-1)
+    ,Pos(a_iPos)
+  {}
+
+  //---------------------------------------------------------------------------
+  ErrorContext::ErrorContext(EErrorCodes iErrc, 
+                             int iPos, 
+                             string_type sIdent,
+                             char_type cType1,
+                             char_type cType2,
+                             int nArg)
+    :Expr()
+    ,Ident(sIdent)
+    ,Hint()
+    ,Errc(iErrc)
+    ,Type1(cType1)
+    ,Type2(cType2)
+    ,Arg(nArg)
+    ,Pos(iPos)
+  {}
+
+  //---------------------------------------------------------------------------
+  //
+  //  ParserError class
+  //
+  //---------------------------------------------------------------------------
+
+  ParserError::ParserError()
+    :m_Err()
+    ,m_sMsg()
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {}
+
+  //------------------------------------------------------------------------------
+  ParserError::ParserError(const string_type &sMsg) 
+    :m_Err()
+    ,m_sMsg(sMsg)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {}
+
+  //------------------------------------------------------------------------------
+  ParserError::ParserError(const ErrorContext &a_Err) 
+    :m_Err(a_Err)
+    ,m_sMsg()
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    m_sMsg = m_ErrMsg[a_Err.Errc];
+  }
+
+  //------------------------------------------------------------------------------
+  ParserError::ParserError(const ParserError &a_Obj)
+    :m_Err(a_Obj.m_Err)
+    ,m_sMsg(a_Obj.m_sMsg)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {}
+
+  //------------------------------------------------------------------------------
+  ParserError& ParserError::operator=(const ParserError &a_Obj)
+  {
+    if (this==&a_Obj)
+      return *this;
+
+    m_sMsg = a_Obj.m_sMsg;
+    m_Err = a_Obj.m_Err;
+    return *this;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurences of a substring with another string. */
+  void ParserError::ReplaceSubString( string_type &sSource,
+                                      const string_type &sFind,
+                                      const string_type &sReplaceWith) const
+  {
+    string_type sResult;
+    string_type::size_type iPos(0), iNext(0);
+
+    for(;;)
+    {
+      iNext = sSource.find(sFind, iPos);
+      sResult.append(sSource, iPos, iNext-iPos);
+
+      if( iNext==string_type::npos )
+        break;
+
+      sResult.append(sReplaceWith);
+      iPos = iNext + sFind.length();
+    } 
+
+    sSource.swap(sResult);
+  }
+
+
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurences of a substring with another string. */
+  void ParserError::ReplaceSubString( string_type &sSource,
+                                      const string_type &sFind,
+                                      int iReplaceWith) const
+  {
+    stringstream_type stream;
+    stream << iReplaceWith;
+    ReplaceSubString(sSource, sFind, stream.str());
+  }
+  
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurences of a substring with another string. */
+  void ParserError::ReplaceSubString( string_type &sSource,
+                                      const string_type &sFind,
+                                      char_type cReplaceWith) const
+  {
+    stringstream_type stream;
+    stream << cReplaceWith;
+    ReplaceSubString(sSource, sFind, stream.str());
+  }
+  
+  //------------------------------------------------------------------------------
+  void ParserError::Reset()
+  {
+    m_sMsg = _T("");
+    m_Err = ErrorContext();
+  }
+      
+  //------------------------------------------------------------------------------
+  const string_type& ParserError::GetExpr() const 
+  {
+    return m_Err.Expr;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type ParserError::GetMsg() const
+  {
+    string_type sMsg(m_sMsg);
+    ReplaceSubString(sMsg, _T("$EXPR$"),  m_Err.Expr);
+    ReplaceSubString(sMsg, _T("$IDENT$"), m_Err.Ident);
+    ReplaceSubString(sMsg, _T("$POS$"),   m_Err.Pos);
+    ReplaceSubString(sMsg, _T("$ARG$"),   m_Err.Arg);
+    ReplaceSubString(sMsg, _T("$TYPE1$"), m_Err.Type1);
+    ReplaceSubString(sMsg, _T("$TYPE2$"), m_Err.Type2);
+    ReplaceSubString(sMsg, _T("$HINT$"),  m_Err.Hint);
+    return sMsg;
+  }
+
+  //------------------------------------------------------------------------------
+  ErrorContext& ParserError::GetContext()
+  {
+    return m_Err;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the expression position related to the error. 
+
+    If the error is not related to a distinct position this will return -1
+  */
+  int ParserError::GetPos() const
+  {
+    return m_Err.Pos;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return string related with this token (if available). */
+  const string_type& ParserError::GetToken() const
+  {
+    return m_Err.Ident;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the error code. */
+  EErrorCodes ParserError::GetCode() const
+  {
+    return m_Err.Errc;
+  }
+}  // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpError.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpError.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,203 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_ERROR_H
+#define MUP_ERROR_H
+
+#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <memory>
+
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+    /** \brief Error codes. 
+    
+      This is the complete list of all error codes used by muParserX
+    */
+    enum EErrorCodes
+    {
+      // Expression syntax errors
+      ecUNEXPECTED_OPERATOR    =  0, ///< Unexpected binary operator found
+      ecUNASSIGNABLE_TOKEN     =  1, ///< Token cant be identified.
+      ecUNEXPECTED_EOF         =  2, ///< Unexpected end of expression. (Example: "2+sin(")
+      ecUNEXPECTED_COMMA       =  3, ///< An unexpected comma has been found. (Example: "1,23")
+      ecUNEXPECTED_VAL         =  4, ///< An unexpected value token has been found
+      ecUNEXPECTED_VAR         =  5, ///< An unexpected variable token has been found
+      ecUNEXPECTED_PARENS      =  6, ///< Unexpected Parenthesis, opening or closing
+      ecUNEXPECTED_STR         =  7, ///< A string has been found at an inapropriate position
+      ecUNEXPECTED_CONDITIONAL =  8,
+      ecUNEXPECTED_NEWLINE     =  9, 
+      ecSTRING_EXPECTED        = 10, ///< A string function has been called with a different type of argument
+      ecVAL_EXPECTED           = 11, ///< A numerical function has been called with a non value type of argument
+      ecMISSING_PARENS         = 12, ///< Missing parens. (Example: "3*sin(3")
+      ecMISSING_ELSE_CLAUSE    = 13, 
+      ecMISPLACED_COLON        = 14,
+      ecUNEXPECTED_FUN         = 15, ///< Unexpected function found. (Example: "sin(8)cos(9)")
+      ecUNTERMINATED_STRING    = 16, ///< unterminated string constant. (Example: "3*valueof("hello)")
+      ecTOO_MANY_PARAMS        = 17, ///< Too many function parameters
+      ecTOO_FEW_PARAMS         = 18, ///< Too few function parameters. (Example: "ite(1<2,2)")
+      ecTYPE_CONFLICT          = 19, ///< Generic type conflict       
+      ecTYPE_CONFLICT_FUN      = 20, ///< Function argument type conflict.
+      ecTYPE_CONFLICT_IDX      = 21, ///< Function argument type conflict.
+      ecINVALID_TYPE           = 22,       
+      ecINVALID_TYPECAST       = 23, ///< Invalid Value token cast.
+      ecARRAY_SIZE_MISMATCH    = 24, ///< Array size mismatch during a vector operation
+      ecNOT_AN_ARRAY           = 25, ///< Using the index operator on a scalar variable
+      ecUNEXPECTED_SQR_BRACKET = 26, ///< Invalid use of the index operator 
+
+      ecINVALID_NAME           = 27, ///< Invalid function, variable or constant name.
+      ecBUILTIN_OVERLOAD       = 28, ///< Trying to overload builtin operator
+      ecINVALID_FUN_PTR        = 29, ///< Invalid callback function pointer 
+      ecINVALID_VAR_PTR        = 30, ///< Invalid variable pointer 
+      ecINVALID_PARAMETER      = 31, ///< Invalid function parameter
+      ecINVALID_NUMBER_OF_PARAMETERS = 32,
+
+      ecNAME_CONFLICT          = 33, ///< Name conflict
+      ecOPT_PRI                = 34, ///< Invalid operator priority
+      ecASSIGNEMENT_TO_VALUE   = 35, ///< Assignment to operator (3=4 instead of a=4)
+
+      // 
+      ecDOMAIN_ERROR           = 36, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
+      ecDIV_BY_ZERO            = 37, ///< Division by zero (currently unused)
+      ecGENERIC                = 38, ///< Generic error
+
+      ecAPI_INVALID_PROTOTYPE  = 39, ///< API error: tried to create a callback with an invalid prototype definition
+      ecAPI_NOT_AN_ARRAY       = 40, ///< Trying to access a non array type as an array
+      ecAPI_INVALID_DIMENSION  = 41, ///< Trying to access a non array type as an array
+      ecINDEX_OUT_OF_BOUNDS    = 42, ///< Array index is out of bounds
+      ecINDEX_DIMENSION        = 43,
+      ecMISSING_SQR_BRACKET    = 44, ///< The index operator was not closed properly (i.e. "v[3")
+      ecEVAL                   = 45, ///< Error while evaluating function / operator
+      
+      // internal errors
+      ecINTERNAL_ERROR         = 46, ///< Internal error of any kind.
+
+      // The last two are special entries 
+      ecCOUNT,                       ///< This is no error code, It just stores just the total number of error codes
+      ecUNDEFINED              = -1, ///< Undefined message, placeholder to detect unassigned error messages
+    };
+
+    //---------------------------------------------------------------------------
+    class ParserErrorMsg
+    {
+    public:
+        typedef ParserErrorMsg self_type;
+
+      ~ParserErrorMsg();
+
+        static const ParserErrorMsg& Instance();
+        string_type operator[](unsigned a_iIdx) const;
+
+    private:
+        std::vector<string_type>  m_vErrMsg;
+        static const self_type m_Instance;
+
+        ParserErrorMsg& operator=(const ParserErrorMsg &);
+        ParserErrorMsg(const ParserErrorMsg&);
+        ParserErrorMsg();
+    };
+
+    //---------------------------------------------------------------------------
+    /** \brief Error context class. 
+    
+       This struct contains the data associated with parser erros. 
+    */
+    struct ErrorContext
+    {
+      /** \brief Creates an empty ErrorContext object.
+      
+        All Members are initialised to an invalid state.
+      */
+      ErrorContext(EErrorCodes a_iErrc = ecUNDEFINED, 
+                   int a_iPos = -1, 
+                   string_type a_sIdent = string_type() );
+
+      ErrorContext(EErrorCodes a_iErrc, 
+                   int a_iPos, 
+                   string_type a_sIdent,
+                   char_type cType1,
+                   char_type cType2,
+                   int nArg);
+
+      string_type Expr;  ///> The expression string.
+      string_type Ident; ///> The identifier of the token that caused the error.
+      string_type Hint;  ///> Additional message
+      EErrorCodes Errc;  ///> The error code
+      char_type Type1;   ///> For type conflicts only! This is the type that was expected.
+      char_type Type2;   ///> For type conflicts only! This is the type that was actually found.
+      int Arg;           ///> The number of arguments that were expected.
+      int Pos;           ///> Position inside the expression where the error occured.
+    };
+
+    //---------------------------------------------------------------------------
+    /** \brief Error class of the parser. 
+        \author Ingo Berg
+
+      Part of the math parser package.
+    */
+    class ParserError
+    {
+    private:
+        //------------------------------------------------------------------------------
+        /** \brief Replace all ocuurences of a substring with another string. */
+        void ReplaceSubString(string_type &strSource, 
+                              const string_type &strFind,
+                              const string_type &strReplaceWith) const;
+        void ReplaceSubString(string_type &sSource,
+                              const string_type &sFind,
+                              int iReplaceWith) const;
+        void ReplaceSubString(string_type &sSource,
+                              const string_type &sFind,
+                              char_type cReplaceWith) const;
+        void Reset();
+
+    public:
+        ParserError();
+        ParserError(const string_type &sMsg);
+        ParserError(const ErrorContext &a_Err);
+        ParserError(const ParserError &a_Obj);
+        ParserError& operator=(const ParserError &a_Obj);
+
+        const string_type& GetExpr() const;
+        string_type GetMsg() const;
+        int GetPos() const;
+        const string_type& GetToken() const;
+        EErrorCodes GetCode() const;
+        ErrorContext& GetContext();
+
+    private:
+        ErrorContext m_Err;  ///< Error context data
+        string_type m_sMsg;  ///< The message string with all wildcards still in place.
+        const ParserErrorMsg &m_ErrMsg;
+    };		
+} // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncCmplx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncCmplx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,595 @@
+/** \file
+    \brief Definition of functions for complex valued operations.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2011 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpFuncCmplx.h"
+
+//--- Standard includes ----------------------------------------------------
+#include <cmath>
+#include <cassert>
+#include <complex>
+#include <iostream>
+
+//--- Parser framework -----------------------------------------------------
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxReal
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxReal::FunCmplxReal(IPackage *package)
+    :ICallback(cmFUNC, _T("real"), 1, package)
+  {}
+
+  //-----------------------------------------------------------------------
+  FunCmplxReal::~FunCmplxReal()
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxReal::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    float_type v = a_pArg[0]->GetFloat();
+    *ret = v;
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxReal::GetDesc() const
+  {
+    return _T("real(x) - Returns the real part of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxReal::Clone() const
+  {
+    return new FunCmplxReal(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxImag
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxImag::FunCmplxImag()
+    :ICallback(cmFUNC, _T("imag"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxImag::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    float_type v = a_pArg[0]->GetImag();
+    *ret = v;
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxImag::GetDesc() const
+  {
+    return _T("imag(x) - Returns the imaginary part of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxImag::Clone() const
+  {
+    return new FunCmplxImag(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxConj
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxConj::FunCmplxConj()
+    :ICallback(cmFUNC, _T("conj"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxConj::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    *ret = cmplx_type(a_pArg[0]->GetFloat(), -a_pArg[0]->GetImag());
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxConj::GetDesc() const
+  {
+    return _T("conj(x) - Returns the complex conjugate of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxConj::Clone() const
+  {
+    return new FunCmplxConj(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxArg
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxArg::FunCmplxArg()
+    :ICallback(cmFUNC, _T("arg"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxArg::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = std::arg(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxArg::GetDesc() const
+  {
+    return _T("arg(x) - Returns the phase angle (or angular component) of the complex number x, expressed in radians.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxArg::Clone() const
+  {
+    return new FunCmplxArg(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxNorm
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxNorm::FunCmplxNorm()
+    :ICallback(cmFUNC, _T("norm"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxNorm::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = std::norm(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxNorm::GetDesc() const
+  {
+    return _T("norm(x) - Returns the norm value of the complex number x.")
+           _T(" The norm value of a complex number is the squared magnitude,")
+           _T(" defined as the addition of the square of both the real part")
+           _T(" and the imaginary part (without the imaginary unit). This is")
+           _T(" the square of abs (x).");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxNorm::Clone() const
+  {
+    return new FunCmplxNorm(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxCos
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxCos::FunCmplxCos()
+    :ICallback(cmFUNC, _T("cos"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxCos::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    if (a_pArg[0]->IsNonComplexScalar())
+    {
+      *ret = cos(a_pArg[0]->GetFloat());
+    }
+    else
+    {
+      cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+      *ret = cos(v);
+    }
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxCos::GetDesc() const
+  {
+    return _T("cos(x) - Returns the cosine of the number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxCos::Clone() const
+  {
+    return new FunCmplxCos(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxSin
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxSin::FunCmplxSin()
+    :ICallback(cmFUNC, _T("sin"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxSin::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    if (a_pArg[0]->IsNonComplexScalar())
+    {
+      *ret = sin(a_pArg[0]->GetFloat());
+    }
+    else
+    {
+      cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+      *ret = sin(v);
+    }
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxSin::GetDesc() const
+  {
+    return _T("sin(x) - Returns the sine of the number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxSin::Clone() const
+  {
+    return new FunCmplxSin(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxCosH
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxCosH::FunCmplxCosH()
+    :ICallback(cmFUNC, _T("cosh"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxCosH::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = cosh(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxCosH::GetDesc() const
+  {
+    return _T("cosh(x) - Returns the hyperbolic cosine of the number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxCosH::Clone() const
+  {
+    return new FunCmplxCosH(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxSinH
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxSinH::FunCmplxSinH()
+    :ICallback(cmFUNC, _T("sinh"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxSinH::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = sinh(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxSinH::GetDesc() const
+  {
+    return _T("sinh(x) - Returns the hyperbolic sine of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxSinH::Clone() const
+  {
+    return new FunCmplxSinH(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxTan
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxTan::FunCmplxTan()
+    :ICallback(cmFUNC, _T("tan"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxTan::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    if (a_pArg[0]->IsNonComplexScalar())
+    {
+      *ret = tan(a_pArg[0]->GetFloat());
+    }
+    else
+    {
+      cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+      *ret = tan(v);
+    }
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxTan::GetDesc() const
+  {
+    return _T("tan(x) - Returns the tangens of the number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxTan::Clone() const
+  {
+    return new FunCmplxTan(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxTanH
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxTanH::FunCmplxTanH()
+    :ICallback(cmFUNC, _T("tanh"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxTanH::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = tanh(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxTanH::GetDesc() const
+  {
+    return _T("tanh(x) - Returns the hyperbolic tangent of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxTanH::Clone() const
+  {
+    return new FunCmplxTanH(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxSqrt
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxSqrt::FunCmplxSqrt()
+    :ICallback(cmFUNC, _T("sqrt"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxSqrt::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    *ret = sqrt((*a_pArg[0]).GetComplex());
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxSqrt::GetDesc() const
+  {
+    return _T("sqrt(x) - Returns the square root of x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxSqrt::Clone() const
+  {
+    return new FunCmplxSqrt(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxExp
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxExp::FunCmplxExp()
+    :ICallback(cmFUNC, _T("exp"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxExp::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = exp(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxExp::GetDesc() const
+  {
+    return _T("exp(x) - Returns the base-e exponential of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxExp::Clone() const
+  {
+    return new FunCmplxExp(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxLn
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxLn::FunCmplxLn()
+    :ICallback(cmFUNC, _T("ln"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxLn::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = log(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxLn::GetDesc() const
+  {
+    return _T("ln(x) - Returns the natural (base-e) logarithm of the complex number x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxLn::Clone() const
+  {
+    return new FunCmplxLn(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxLog
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxLog::FunCmplxLog()
+    :ICallback(cmFUNC, _T("log"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxLog::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = log10(v);
+  }
+
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxLog::GetDesc() const
+  {
+    return _T("log(x) - Common logarithm of x, for values of x greater than zero.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxLog::Clone() const
+  {
+    return new FunCmplxLog(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxLog10
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxLog10::FunCmplxLog10()
+    :ICallback(cmFUNC, _T("log10"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxLog10::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    cmplx_type v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = log10(v);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxLog10::GetDesc() const
+  {
+    return _T("log10(x) - Common logarithm of x, for values of x greater than zero.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxLog10::Clone() const
+  {
+    return new FunCmplxLog10(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxLog2
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxLog2::FunCmplxLog2()
+    :ICallback(cmFUNC, _T("log2"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxLog2::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    std::complex<float_type> v(a_pArg[0]->GetFloat(), a_pArg[0]->GetImag());
+    *ret = log(v) * (float_type)1.0/log((float_type)2.0);
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxLog2::GetDesc() const
+  {
+    return _T("log2(x) - Logarithm to base 2 of x, for values of x greater than zero.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxLog2::Clone() const
+  {
+    return new FunCmplxLog2(*this);
+  }
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunCmplxAbs
+  //
+  //-----------------------------------------------------------------------
+
+  FunCmplxAbs::FunCmplxAbs()
+    :ICallback(cmFUNC, _T("abs"), 1)
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunCmplxAbs::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    float_type v = sqrt(a_pArg[0]->GetFloat()*a_pArg[0]->GetFloat() + 
+                        a_pArg[0]->GetImag()*a_pArg[0]->GetImag());
+    *ret = v;
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunCmplxAbs::GetDesc() const
+  {
+    return _T("abs(x) - Returns the absolute value of x.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunCmplxAbs::Clone() const
+  {
+    return new FunCmplxAbs(*this);
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncCmplx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncCmplx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,239 @@
+/** \file
+    \brief Definition of functions for complex valued operations.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2011 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_COMPLEX_FUNCTIONS_H
+#define MUP_COMPLEX_FUNCTIONS_H
+
+#include "mpICallback.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------
+  /** \brief Parser callback object for returning the real part of a complex number.
+      \ingroup functions
+  */
+  class FunCmplxReal : public ICallback
+  {
+  public:
+    FunCmplxReal(IPackage *pPackage = NULL);
+    virtual ~FunCmplxReal();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  /** \brief Parser callback object for returning the imaginary part of a complex number.
+      \ingroup functions
+  */
+  class FunCmplxImag : public ICallback
+  {
+  public:
+    FunCmplxImag();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  /** \brief Parser callback object for returning the complex conjugate of 
+             the complex number.
+      \ingroup functions
+  */
+  class FunCmplxConj : public ICallback
+  {
+  public:
+    FunCmplxConj();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+
+  //-----------------------------------------------------------------------
+  /** \brief Parser callback object for returning the phase angle 
+             (or angular component) of a complex number, expressed in radians.
+      \ingroup functions
+  */
+  class FunCmplxArg : public ICallback
+  {
+  public:
+    FunCmplxArg();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  /** \brief Parser callback object for returning the norm value of the 
+             complex number phase angle.
+      \ingroup functions
+  */
+  class FunCmplxNorm : public ICallback
+  {
+  public:
+    FunCmplxNorm();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxCos : public ICallback
+  {
+  public:
+    FunCmplxCos();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxSin : public ICallback
+  {
+  public:
+    FunCmplxSin();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxCosH : public ICallback
+  {
+  public:
+    FunCmplxCosH();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxSinH : public ICallback
+  {
+  public:
+    FunCmplxSinH();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxTan : public ICallback
+  {
+  public:
+    FunCmplxTan();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxTanH : public ICallback
+  {
+  public:
+    FunCmplxTanH();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxSqrt : public ICallback
+  {
+  public:
+    FunCmplxSqrt();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxExp : public ICallback
+  {
+  public:
+    FunCmplxExp();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxLn : public ICallback
+  {
+  public:
+    FunCmplxLn();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxLog : public ICallback
+  {
+  public:
+    FunCmplxLog();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxLog10 : public ICallback
+  {
+  public:
+    FunCmplxLog10();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxLog2 : public ICallback
+  {
+  public:
+    FunCmplxLog2();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //-----------------------------------------------------------------------
+  class FunCmplxAbs : public ICallback
+  {
+  public:
+
+    FunCmplxAbs();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncCommon.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncCommon.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,255 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpFuncCommon.h"
+
+#include <cassert>
+#include <string>
+#include <iostream>
+
+#include "mpValue.h"
+#include "mpParserBase.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  //
+  // FunParserID
+  //
+  //------------------------------------------------------------------------------
+
+  FunParserID::FunParserID()
+    :ICallback(cmFUNC, _T("parserid"), 0)
+  {}
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns the number of elements stored in the first parameter. */
+  void FunParserID::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+    string_type sVer = _T("muParserX V") + parser.GetVersion();
+    *ret = sVer;
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunParserID::GetDesc() const
+  {
+    return _T("parserid() - muParserX version information");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunParserID::Clone() const
+  {
+    return new FunParserID(*this);
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // Max Function
+  //
+  //------------------------------------------------------------------------------
+
+  FunMax::FunMax() : ICallback(cmFUNC, _T("max"), -1)
+  {}
+
+  //------------------------------------------------------------------------------
+  void FunMax::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    float_type max(-1e30), val;
+    for (int i=0; i<a_iArgc; ++i)
+    {
+      switch(a_pArg[i]->GetType())
+      {
+      case 'f': val = a_pArg[i]->GetFloat();   break;
+      case 'i': val = a_pArg[i]->GetFloat(); break;
+      case 'n': break; // ignore not in list entries (missing parameter)
+      case 'c':
+      default:
+        {
+          ErrorContext err;
+          err.Errc = ecTYPE_CONFLICT_FUN;
+          err.Arg = i+1;
+          err.Type1 = a_pArg[i]->GetType();
+          err.Type2 = 'f';
+          throw ParserError(err);
+        }
+      }
+      max = std::max(max, val);    
+    }
+    
+    *ret = max;
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunMax::GetDesc() const
+  {
+    return _T("max(x,y,...,z) - Returns the maximum value from all of its function arguments.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunMax::Clone() const
+  {
+    return new FunMax(*this);
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // Min Function
+  //
+  //------------------------------------------------------------------------------
+
+  FunMin::FunMin() : ICallback(cmFUNC, _T("min"), -1)
+  {}
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns the minimum value of all values. 
+      \param a_pArg Pointer to an array of Values
+      \param a_iArgc Number of values stored in a_pArg
+  */
+  void FunMin::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    float_type min(1e30), val(min);
+
+    for (int i=0; i<a_iArgc; ++i)
+    {
+      switch(a_pArg[i]->GetType())
+      {
+      case 'f': 
+      case 'i': val = a_pArg[i]->GetFloat();   break;
+      default:
+        {
+          ErrorContext err;
+          err.Errc = ecTYPE_CONFLICT_FUN;
+          err.Arg = i+1;
+          err.Type1 = a_pArg[i]->GetType();
+          err.Type2 = 'f';
+          throw ParserError(err);
+        }
+      }
+      min = std::min(min, val);    
+    }
+    
+    *ret = min;
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunMin::GetDesc() const
+  {
+    return _T("min(x,y,...,z) - Returns the minimum value from all of its function arguments.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunMin::Clone() const
+  {
+    return new FunMin(*this);
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // class FunSum
+  //
+  //------------------------------------------------------------------------------
+
+  FunSum::FunSum() 
+    :ICallback(cmFUNC, _T("sum"), -1)
+  {}
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns the minimum value of all values. 
+      \param a_pArg Pointer to an array of Values
+      \param a_iArgc Number of values stored in a_pArg
+  */
+  void FunSum::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    float_type sum(0);
+
+    for (int i=0; i<a_iArgc; ++i)
+    {
+      switch(a_pArg[i]->GetType())
+      {
+      case 'f': 
+      case 'i': sum += a_pArg[i]->GetFloat();   break;
+      default:
+        {
+          ErrorContext err;
+          err.Errc = ecTYPE_CONFLICT_FUN;
+          err.Arg = i+1;
+          err.Type1 = a_pArg[i]->GetType();
+          err.Type2 = 'f';
+          throw ParserError(err);
+        }
+      }
+    }
+    
+    *ret = sum;
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunSum::GetDesc() const
+  {
+    return _T("sum(x,y,...,z) - Returns the sum of all arguments.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunSum::Clone() const
+  {
+    return new FunSum(*this);
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // SizeOf
+  //
+  //------------------------------------------------------------------------------
+
+  FunSizeOf::FunSizeOf()
+    :ICallback(cmFUNC, _T("sizeof"), 1)
+  {}
+
+  //------------------------------------------------------------------------------
+  FunSizeOf::~FunSizeOf()
+  {}
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns the number of elements stored in the first parameter. */
+  void FunSizeOf::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    assert(a_iArgc==1);
+    *ret = (int)(a_pArg[0]->GetArray().GetRows());
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunSizeOf::GetDesc() const
+  {
+    return _T("sizeof(a) - Returns the number of elements in a.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunSizeOf::Clone() const
+  {
+    return new FunSizeOf(*this);
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncCommon.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncCommon.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,101 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_FUNC_COMMON_H
+#define MUP_FUNC_COMMON_H
+
+#include "mpICallback.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser function callback for determining the size of an array. 
+      \ingroup functions
+  */
+  class FunParserID : public ICallback
+  {
+  public:
+    FunParserID ();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class FunParserID
+
+  //------------------------------------------------------------------------------
+  /** \brief Determine maximal value from the parameter list. 
+      \ingroup functions
+  */
+  class FunMax : public ICallback
+  {
+  public:
+    FunMax();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class FunMax
+
+  //------------------------------------------------------------------------------
+  /** \brief Determine minimal value from the parameter list. 
+      \ingroup functions
+  */
+  class FunMin : public ICallback
+  {
+  public:
+    FunMin();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class FunMin
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser callback for summing up all function arguments. 
+      \ingroup functions
+  */  
+  class FunSum : public ICallback
+  {
+  public:
+    FunSum();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class FunSum
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser function callback for determining the size of an array. 
+      \ingroup functions
+  */
+  class FunSizeOf : public ICallback
+  {
+  public:
+    FunSizeOf();
+    virtual ~FunSizeOf();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class FunSizeOf
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncMatrix.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncMatrix.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,106 @@
+/** \file
+    \brief Definition of functions for complex valued operations.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpFuncMatrix.h"
+
+//--- Standard includes ----------------------------------------------------
+#include <cmath>
+#include <cassert>
+#include <complex>
+#include <iostream>
+
+//--- Parser framework -----------------------------------------------------
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------
+  //
+  //  class FunMatrixOnes
+  //
+  //-----------------------------------------------------------------------
+
+  FunMatrixOnes::FunMatrixOnes(IPackage *package)
+    :ICallback(cmFUNC, _T("ones"), -1, package)
+  {}
+
+  //-----------------------------------------------------------------------
+  FunMatrixOnes::~FunMatrixOnes()
+  {}
+
+  //-----------------------------------------------------------------------
+  void FunMatrixOnes::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int argc)
+  {
+    switch(argc)
+    {
+    case 1: // Return a vector
+            {
+              int m = a_pArg[0]->GetInteger();
+              if (m==1)
+                *ret = 1.0;
+              else
+                *ret = matrix_type(a_pArg[0]->GetInteger(), 1, 1.0);
+            }
+            break;
+
+    case 2: // Return a matrix
+            {
+              int m = a_pArg[0]->GetInteger(),
+                  n = a_pArg[1]->GetInteger();
+
+              if (m==n && m==1)
+                *ret = 1.0;
+              else
+                *ret = matrix_type(a_pArg[0]->GetInteger(), a_pArg[1]->GetInteger(), 1.0);
+            }
+            break;
+    
+    default:
+            ErrorContext err;
+            err.Errc = ecINVALID_NUMBER_OF_PARAMETERS;
+            err.Arg = 2;
+            err.Ident = GetIdent();
+            throw ParserError(err);
+    }
+  }
+
+  //-----------------------------------------------------------------------
+  const char_type* FunMatrixOnes::GetDesc() const
+  {
+    return _T("ones(x [, y]) - Returns a matrix whose elements are all 1.");
+  }
+
+  //-----------------------------------------------------------------------
+  IToken* FunMatrixOnes::Clone() const
+  {
+    return new FunMatrixOnes(*this);
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncMatrix.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncMatrix.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,53 @@
+/** \file
+    \brief Definition of functions for complex valued operations.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_FUNC_MATRIX_H
+#define MUP_FUNC_MATRIX_H
+
+#include "mpICallback.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------
+  /** \brief Parser callback object for creating matrices consisting 
+             entirely of ones.
+      \ingroup functions
+  */
+  class FunMatrixOnes : public ICallback
+  {
+  public:
+    FunMatrixOnes(IPackage *pPackage = NULL);
+    virtual ~FunMatrixOnes();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncNonCmplx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncNonCmplx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,97 @@
+/** \file
+    \brief Implementation of basic functions used by muParserX.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#include "mpFuncNonCmplx.h"
+
+//--- Standard includes ----------------------------------------------------
+#include <cmath>
+#include <cassert>
+#include <iostream>
+
+//--- muParserX framework --------------------------------------------------
+#include "mpValue.h"
+#include "mpError.h"
+
+#undef log
+#undef log2
+
+MUP_NAMESPACE_START
+
+  float_type log2(float_type v)  { return log(v) * 1.0/log(2.0); }
+  float_type asinh(float_type v) { return log(v + sqrt(v * v + 1)); }
+  float_type acosh(float_type v) { return log(v + sqrt(v * v - 1)); }
+  float_type atanh(float_type v) { return (0.5 * log((1 + v) / (1 - v))); }
+
+#define MUP_UNARY_FUNC(CLASS, IDENT, FUNC, DESC)                     \
+    CLASS::CLASS()                                                   \
+    :ICallback(cmFUNC, _T(IDENT), 1)                                 \
+    {}                                                               \
+                                                                     \
+    void CLASS::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)        \
+    {                                                                \
+      *ret = FUNC(a_pArg[0]->GetFloat());                            \
+    }                                                                \
+                                                                     \
+    const char_type* CLASS::GetDesc() const                          \
+    {                                                                \
+      return _T(DESC);                                               \
+    }                                                                \
+                                                                     \
+    IToken* CLASS::Clone() const                                     \
+    {                                                                \
+      return new CLASS(*this);                                       \
+    }
+
+    // trigonometric functions
+    MUP_UNARY_FUNC(FunTan,   "sin",   sin,   "sine function")
+    MUP_UNARY_FUNC(FunCos,   "cos",   cos,   "cosine function")
+    MUP_UNARY_FUNC(FunSin,   "tan",   tan,   "tangens function")
+    // arcus functions
+    MUP_UNARY_FUNC(FunASin,  "asin",  asin,  "arcus sine")
+    MUP_UNARY_FUNC(FunACos,  "acos",  acos,  "arcus cosine")
+    MUP_UNARY_FUNC(FunATan,  "atan",  atan,  "arcus tangens")
+    // hyperbolic functions
+    MUP_UNARY_FUNC(FunSinH,  "sinh",  sinh,  "hyperbolic sine")
+    MUP_UNARY_FUNC(FunCosH,  "cosh",  cosh,  "hyperbolic cosine")
+    MUP_UNARY_FUNC(FunTanH,  "tanh",  tanh,  "hyperbolic tangens")
+    // hyperbolic arcus functions
+    MUP_UNARY_FUNC(FunASinH,  "asinh",  asinh,  "hyperbolic arcus sine")
+    MUP_UNARY_FUNC(FunACosH,  "acosh",  acosh,  "hyperbolic arcus cosine")
+    MUP_UNARY_FUNC(FunATanH,  "atanh",  atanh,  "hyperbolic arcus tangens")
+    // logarithm functions
+    MUP_UNARY_FUNC(FunLog,   "log",   log10, "Logarithm base 10")
+    MUP_UNARY_FUNC(FunLog10, "log10", log10, "Logarithm base 10")
+    MUP_UNARY_FUNC(FunLog2,  "log2",  log2,  "Logarithm base 2")
+    MUP_UNARY_FUNC(FunLn,    "ln",    log,   "Natural logarithm")
+    // square root
+    MUP_UNARY_FUNC(FunSqrt,  "sqrt",  sqrt,  "sqrt(x) - square root of x")
+    MUP_UNARY_FUNC(FunExp,   "exp",   exp,   "exp(x) - e to the power of x")
+    MUP_UNARY_FUNC(FunAbs,   "abs",   fabs,  "abs(x) - absolute value of x")
+#undef MUP_UNARY_FUNC
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncNonCmplx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncNonCmplx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,79 @@
+/** \file
+    \brief Implementation of basic functions used by muParserX.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#ifndef MUP_FUNC_NON_CMPLX_H
+#define MUP_FUNC_NON_CMPLX_H
+
+#include "mpICallback.h"
+
+/** \defgroup functions Function callback objects.
+
+  This group lists the objects representing parser functions.
+*/
+
+
+MUP_NAMESPACE_START
+
+#define MUP_UNARY_FUNC_DEF(CLASS)                                          \
+    class CLASS : public ICallback                                         \
+    {                                                                      \
+    public:                                                                \
+      CLASS();                                                             \
+      virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);  \
+      virtual const char_type* GetDesc() const;                            \
+      virtual IToken* Clone() const;                                       \
+    }; 
+
+    MUP_UNARY_FUNC_DEF(FunTan)
+    MUP_UNARY_FUNC_DEF(FunCos)
+    MUP_UNARY_FUNC_DEF(FunSin)
+    // arcus functions
+    MUP_UNARY_FUNC_DEF(FunASin)
+    MUP_UNARY_FUNC_DEF(FunACos)
+    MUP_UNARY_FUNC_DEF(FunATan)
+    // hyperbolic functions
+    MUP_UNARY_FUNC_DEF(FunSinH)
+    MUP_UNARY_FUNC_DEF(FunCosH)
+    MUP_UNARY_FUNC_DEF(FunTanH)
+    // hyperbolic arcus functions
+    MUP_UNARY_FUNC_DEF(FunASinH)
+    MUP_UNARY_FUNC_DEF(FunACosH)
+    MUP_UNARY_FUNC_DEF(FunATanH)
+    // logarithm functions
+    MUP_UNARY_FUNC_DEF(FunLog)
+    MUP_UNARY_FUNC_DEF(FunLog10)
+    MUP_UNARY_FUNC_DEF(FunLog2)
+    MUP_UNARY_FUNC_DEF(FunLn)
+    // square root
+    MUP_UNARY_FUNC_DEF(FunSqrt)
+    MUP_UNARY_FUNC_DEF(FunExp)
+    MUP_UNARY_FUNC_DEF(FunAbs)
+#undef MUP_UNARY_FUNC_DEF
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncStr.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncStr.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,140 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpFuncStr.h"
+
+#include <cmath>
+#include <cassert>
+#include <cstdio>
+#include <cwchar>
+#include <algorithm>
+
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  //
+  // Strlen function
+  //
+  //------------------------------------------------------------------------------
+
+  FunStrLen::FunStrLen()
+    :ICallback(cmFUNC, _T("strlen"), 1)
+  {}
+
+  //------------------------------------------------------------------------------
+  void FunStrLen::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    string_type str = a_pArg[0]->GetString();
+    *ret = (int)str.length();
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunStrLen::GetDesc() const
+  {
+    return _T("strlen(s) - Returns the length of the string s.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunStrLen::Clone() const
+  {
+    return new FunStrLen(*this);
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // ToUpper function
+  //
+  //------------------------------------------------------------------------------
+
+  FunStrToUpper::FunStrToUpper()
+    :ICallback(cmFUNC, _T("toupper"), 1)
+  {}
+
+  //------------------------------------------------------------------------------
+  void FunStrToUpper::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    using namespace std;
+
+    string_type str = a_pArg[0]->GetString();
+    std::transform(str.begin(), str.end(), str.begin(), ::toupper);
+
+    *ret = str;
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunStrToUpper::GetDesc() const
+  {
+    return _T("toupper(s) - Converts the string s to uppercase characters.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunStrToUpper::Clone() const
+  {
+    return new FunStrToUpper(*this);
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // String to double conversion
+  //
+  //------------------------------------------------------------------------------
+
+  FunStrToDbl::FunStrToDbl()
+    :ICallback(cmFUNC, _T("str2dbl"), 1)
+  {}
+
+  //------------------------------------------------------------------------------
+  void FunStrToDbl::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    assert(a_iArgc==1);
+    string_type in;
+    float_type out;
+
+    in = a_pArg[0]->GetString();
+    
+#ifndef _UNICODE    
+    sscanf(in.c_str(), "%lf", &out);
+#else
+    swscanf(in.c_str(), _T("%lf"), &out);
+#endif
+
+    *ret = out;
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* FunStrToDbl::GetDesc() const
+  {
+    return _T("str2dbl(s) - Converts the string stored in s into a floating foint value.");
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* FunStrToDbl::Clone() const
+  {
+    return new FunStrToDbl(*this);
+  }
+}  // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFuncStr.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFuncStr.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,73 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2011 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_FUNC_STR_H
+#define MUP_FUNC_STR_H
+
+#include "mpICallback.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for determining the length of a string. 
+      \ingroup functions
+  */
+  class FunStrLen : public ICallback
+  {
+  public:
+    FunStrLen();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Convert a string to upper case letters. 
+      \ingroup functions  
+  */
+  class FunStrToUpper : public ICallback
+  {
+  public:
+    FunStrToUpper();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parse string to a floating point value. 
+      \ingroup functions  
+  */
+  class FunStrToDbl : public ICallback
+  {
+  public:
+    FunStrToDbl ();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class FunStrToDbl
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpFwdDecl.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpFwdDecl.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,49 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_FWD_DECL_H
+#define MUP_FWD_DECL_H
+
+#include "mpDefines.h"
+
+
+MUP_NAMESPACE_START
+
+  class ParserXBase;
+
+  class ICallback;
+  class IToken;
+  class IValue;
+  class IValueReader;
+  class IPrecedence;
+  class IOprtIndex;
+  class Value;
+  class ValueCache;
+
+  template<typename T>
+  class TokenPtr;
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpICallback.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpICallback.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,138 @@
+/** \file
+    \brief Implementation of the interface for parser callback objects.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpICallback.h"
+#include <cassert>
+
+#include "mpParserBase.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  ICallback::ICallback(ECmdCode a_iCode, 
+                       const char_type *a_szName, 
+                       int a_nArgc,
+                       const IPackage *a_pPackage)
+    :IToken(a_iCode, a_szName)
+    ,m_pParent(NULL)
+    ,m_pPackage(a_pPackage)
+    ,m_nArgc(a_nArgc)
+    ,m_nArgsPresent(-1)
+  {}
+
+  //------------------------------------------------------------------------------
+  ICallback::~ICallback()
+  {}
+
+  //---------------------------------------------------------------------------
+  ICallback* ICallback::AsICallback()
+  {
+    return this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue* ICallback::AsIValue()
+  {
+    return NULL;
+  }
+
+  //------------------------------------------------------------------------------
+  bool ICallback::IsVolatile() const
+  {
+    return false;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns a pointer to the parser object owning this callback. 
+      \pre [assert] m_pParent must be defined
+  */
+  ParserXBase* ICallback::GetParent()
+  {
+    assert(m_pParent);
+    return m_pParent;
+  }
+
+  //------------------------------------------------------------------------------
+  void  ICallback::SetArgc(int argc)
+  {
+    m_nArgc = argc;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns the m´number of arguments required by this callback. 
+      \return Number of arguments or -1 if the number of arguments is variable.  
+  */
+  int ICallback::GetArgc() const
+  {
+    return m_nArgc;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Assign a parser object to the callback.
+      \param a_pParent The parser that belongs to this callback object.
+
+    The parent object can be used in order to access internals of the parser
+    from within a callback object. Thus enabling callbacks to delete 
+    variables or functions if this is desired.
+  */
+  void ICallback::SetParent(parent_type *a_pParent)
+  {
+    assert(a_pParent);
+    m_pParent = a_pParent;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type ICallback::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; ident=\"") << GetIdent() << "\"";
+    ss << _T("; argc=") << GetArgc() << " (present: " << m_nArgsPresent << ")";
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //------------------------------------------------------------------------------
+  void ICallback::SetNumArgsPresent(int argc)
+  {
+    m_nArgsPresent = argc;
+  }
+
+  //------------------------------------------------------------------------------
+  int ICallback::GetArgsPresent() const
+  {
+    if (m_nArgc!=-1)
+      return m_nArgc;
+    else
+      return m_nArgsPresent;
+  }
+} // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpICallback.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpICallback.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,82 @@
+/** \file
+    \brief Definition of the interface for parser callback objects.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MU_IPARSER_CALLBACK_H
+#define MU_IPARSER_CALLBACK_H
+
+//--- muParserX framework --------------------------------------------
+#include "mpIToken.h"
+#include "mpIPackage.h"
+
+
+MUP_NAMESPACE_START
+
+  /** \brief Interface for callback objects. 
+    
+    All Parser functions and operators must implement this interface.
+  */
+  class ICallback : public IToken
+  {
+  public:
+      typedef ParserXBase parent_type;  
+
+      ICallback(ECmdCode a_iCode, 
+                const char_type *a_szName, 
+                int a_nArgNum = 1,
+                const IPackage *a_pPackage = NULL);
+      virtual ~ICallback();
+
+      virtual ICallback* AsICallback();
+      virtual IValue* AsIValue();
+
+      virtual void Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc) = 0;
+      virtual const char_type* GetDesc() const = 0;
+      virtual bool IsVolatile() const;
+      virtual string_type AsciiDump() const;
+        
+      int GetArgc() const;
+      int GetArgsPresent() const;
+      void  SetParent(parent_type *a_pParent);
+      void  SetNumArgsPresent(int argc);
+
+  protected:
+      parent_type* GetParent();
+      void  SetArgc(int argc);
+
+  private:
+
+      parent_type *m_pParent;      ///< Pointer to the parser object using this callback
+      const IPackage *m_pPackage;  ///< Pointer to thhe package this callback is belonging to (may be zero)
+      int  m_nArgc;                ///< Number of this function can take Arguments.
+      int  m_nArgsPresent;         ///< Number of arguments actually submitted
+  }; // class ICallback
+
+MUP_NAMESPACE_END
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIOprt.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIOprt.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,209 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpIOprt.h"
+
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  //
+  // Binary Operators
+  //
+  //------------------------------------------------------------------------------
+
+  IOprtBin::IOprtBin(const char_type *a_szIdent, int nPrec, EOprtAsct eAsc)
+    :ICallback(cmOPRT_BIN, a_szIdent, 2)
+    ,IPrecedence()
+    ,m_nPrec(nPrec)
+    ,m_eAsc(eAsc)
+  {}
+
+  //------------------------------------------------------------------------------
+  IOprtBin::~IOprtBin()
+  {}
+
+  //------------------------------------------------------------------------------
+  string_type IOprtBin::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; ident=\"") << GetIdent() << _T("\"");
+    ss << _T("; prec=") << GetPri();
+    ss << _T("; argc=") << GetArgc();
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //------------------------------------------------------------------------------
+  int IOprtBin::GetPri() const
+  {
+    return m_nPrec;
+  }
+
+  //------------------------------------------------------------------------------
+  EOprtAsct IOprtBin::GetAssociativity() const
+  {
+    return m_eAsc;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Verify the operator prototype.
+
+    Binary operators have the additional constraint that return type and the types
+    of both arguments must be the same. So adding to floats can not produce a string
+    and adding a number to a string is impossible.
+  */
+  void IOprtBin::CheckPrototype(const string_type &a_sProt)
+  {
+    if (a_sProt.length()!=4)
+      throw ParserError( ErrorContext(ecAPI_INVALID_PROTOTYPE, -1, GetIdent() ) ); 
+
+    //if (a_sProt[0]!=a_sProt[2] || a_sProt[0]!=a_sProt[3])
+    //  throw ParserError( ErrorContext(ecAPI_INVALID_PROTOTYPE, -1, GetIdent() ) ); 
+  }
+
+  //---------------------------------------------------------------------------
+  IPrecedence* IOprtBin::AsIPrecedence()
+  {
+    return this;
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // Unary Postfix Operators
+  //
+  //------------------------------------------------------------------------------
+
+  IOprtPostfix::IOprtPostfix(const char_type *a_szIdent)
+    :ICallback(cmOPRT_POSTFIX, a_szIdent, 1)
+  {}
+
+  //------------------------------------------------------------------------------
+  IOprtPostfix::~IOprtPostfix()
+  {}
+
+  //------------------------------------------------------------------------------
+  string_type IOprtPostfix::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; ident=\"") << GetIdent() << _T("\"");
+    ss << _T("; argc=") << GetArgc();
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // Unary Infix Operators
+  //
+  //------------------------------------------------------------------------------
+
+  IOprtInfix::IOprtInfix(const char_type *a_szIdent)
+    :ICallback(cmOPRT_INFIX, a_szIdent, 1)
+  {}
+
+  //------------------------------------------------------------------------------
+  IOprtInfix::~IOprtInfix()
+  {}
+
+  //------------------------------------------------------------------------------
+  string_type IOprtInfix::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; ident=\"") << GetIdent() << _T("\"");
+    ss << _T("; argc=") << GetArgc();
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  // Index operators
+  //
+  //------------------------------------------------------------------------------
+
+  IOprtIndex::IOprtIndex(int nArgc)
+    :IToken(cmIC, _T("[...]"))
+    ,m_nArgc(nArgc)
+  {}
+
+  //------------------------------------------------------------------------------
+  IOprtIndex::~IOprtIndex()
+  {}
+
+  //------------------------------------------------------------------------------
+  string_type IOprtIndex::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; ident=\"") << GetIdent() << _T("\"");
+    ss << _T("; argc=") << GetArgc();
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IOprtIndex* IOprtIndex::AsIOprtIndex()
+  {
+    return this;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  int  IOprtIndex::GetArgc() const
+  {
+    return m_nArgc;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void IOprtIndex::SetNumArgsPresent(int argc)
+  {
+    m_nArgsPresent = argc;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  int IOprtIndex::GetArgsPresent() const
+  {
+    if (m_nArgc!=-1)
+      return m_nArgc;
+    else
+      return m_nArgsPresent;
+  }
+}  // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIOprt.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIOprt.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,120 @@
+/** \file mpIOprt.h
+    \brief Definition of base classes needed for parser operator definitions.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_IPARSER_OPERATOR_H
+#define MUP_IPARSER_OPERATOR_H
+
+#include "mpICallback.h"
+#include "mpIPrecedence.h"
+
+
+MUP_NAMESPACE_START
+
+    //------------------------------------------------------------------------------
+    /** \brief Interface for binary operators.
+        \ingroup binop
+
+      All classes representing binary operator callbacks must be derived from
+      this base class.
+    */
+    class IOprtBin : public ICallback,
+                     public IPrecedence
+    {
+    public:
+
+      IOprtBin(const char_type *a_szIdent, int nPrec, EOprtAsct eAsc);
+      virtual ~IOprtBin();
+      virtual string_type AsciiDump() const;
+
+      virtual int GetPri() const;
+      virtual EOprtAsct GetAssociativity() const;
+
+      //------------------------------------------
+      // IPrecedence implementation
+      //------------------------------------------
+
+      virtual IPrecedence* AsIPrecedence();
+
+    private:
+
+      void CheckPrototype(const string_type &a_szProt);
+      int m_nPrec;
+      EOprtAsct m_eAsc;
+    }; // class IOperator
+
+
+    //------------------------------------------------------------------------------
+    /** \brief Interface for unary postfix operators.
+        \ingroup postfix
+    */
+    class IOprtPostfix : public ICallback
+    {
+    public:
+        IOprtPostfix(const char_type *a_szIdent);
+        virtual ~IOprtPostfix();
+        virtual string_type AsciiDump() const;
+    }; // class IOperator
+
+
+    //------------------------------------------------------------------------------
+    /** \brief Interface for unary infix operators.
+        \ingroup infix
+    */
+    class IOprtInfix : public ICallback
+    {
+    public:
+        IOprtInfix(const char_type *a_szIdent);
+        virtual ~IOprtInfix();
+        virtual string_type AsciiDump() const;
+    }; // class IOperator
+
+    //------------------------------------------------------------------------------
+    /** \brief Interface for index operator tokens.
+    */
+    class IOprtIndex : public IToken
+    {
+    public:
+        IOprtIndex(int nArgc);
+        virtual ~IOprtIndex();
+        virtual string_type AsciiDump() const;
+        virtual void At(ptr_val_type& ret, const ptr_val_type *arg, int argc) = 0;
+        virtual IOprtIndex* AsIOprtIndex();
+
+        int  GetArgc() const;
+        int  GetArgsPresent() const;
+        void SetNumArgsPresent(int argc);
+
+    private:
+        int m_nArgc;          ///< Number of arguments needed for the index operator (dimension of the index)
+        int m_nArgsPresent;   ///< Number of arguments actually submitted
+
+    }; // class IOperator
+}  // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIPackage.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIPackage.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,17 @@
+#include "mpIPackage.h"
+
+#include "mpDefines.h"
+#include "mpParserBase.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+IPackage::IPackage()
+{}
+
+//------------------------------------------------------------------------------
+IPackage::~IPackage()
+{}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIPackage.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIPackage.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,27 @@
+#ifndef MU_IPACKAGE_H
+#define MU_IPACKAGE_H
+
+#include <vector>
+#include "mpFwdDecl.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+class IPackage
+{
+public:
+
+  virtual void AddToParser(ParserXBase *pParser) = 0;
+  virtual string_type GetDesc() const = 0;
+  virtual string_type GetPrefix() const = 0;
+
+protected:
+
+  IPackage();
+  virtual ~IPackage();
+};
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIPrecedence.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIPrecedence.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,50 @@
+/** \file mpIPrecedence.h
+    \brief Definition of base classes needed for parser operator definitions.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_IPRECEDENCE_H
+#define MUP_IPRECEDENCE_H
+
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Interface for binary and ternary operators
+      \ingroup binop
+  */
+  class IPrecedence
+  {
+  public:
+    virtual int GetPri() const = 0;
+    virtual EOprtAsct GetAssociativity() const = 0;
+  };
+}  // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIToken.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIToken.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,321 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpIToken.h"
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <list>
+#include <cassert>
+
+#include "mpIPrecedence.h"
+
+MUP_NAMESPACE_START
+
+#ifdef MUP_LEAKAGE_REPORT
+  std::list<IToken*> IToken::s_Tokens;
+#endif
+
+#ifndef _UNICODE
+
+  //---------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is not defined.
+  */
+  std::ostream& operator<<(std::ostream &a_Stream, const IToken &tok)
+  {
+    return a_Stream << tok.ToString();
+  }  
+
+#else
+
+  //---------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is defined.
+  */
+  std::wostream& operator<<(std::wostream &a_Stream, const IToken &tok)
+  {
+    return a_Stream << tok.ToString();
+  }  
+#endif
+
+#ifdef MUP_LEAKAGE_REPORT
+
+  void IToken::LeakageReport()
+  {
+    using namespace std;
+
+    console() << "\n";     
+    console() << "Memory leakage report:\n\n";     
+    if (IToken::s_Tokens.size())
+    {
+      list<IToken*>::const_iterator item = IToken::s_Tokens.begin();
+      std::vector<int> stat(cmCOUNT, 0);
+      for (; item!=IToken::s_Tokens.end(); ++item)
+      {
+        console() << "Addr: 0x" << hex << *item << "  Ident: \"" << (*item)->GetIdent() << "\"";
+        console() << "\tCode: " << g_sCmdCode[(*item)->GetCode()] << "\n"; 
+        stat[(*item)->GetCode()]++;
+      }
+      console() << "Leaked tokens: " << dec << (int)IToken::s_Tokens.size() << std::endl;
+      
+      for (int i=0; i<cmCOUNT; ++i)
+        console() << g_sCmdCode[i] << ":" << stat[i] << "\n";
+
+      console() << endl;
+    }
+    else
+    {
+      console() << "No tokens leaked!\n";
+    }
+  }
+
+#endif
+
+  //------------------------------------------------------------------------------
+  IToken::IToken(ECmdCode a_iCode)
+    :m_eCode(a_iCode)
+    ,m_sIdent()
+    ,m_nPosExpr(-1)
+    ,m_nRefCount(0)
+    ,m_flags(0)
+  {
+#ifdef MUP_LEAKAGE_REPORT
+    IToken::s_Tokens.push_back(this);
+#endif
+  }
+
+  //------------------------------------------------------------------------------
+  IToken::IToken(ECmdCode a_iCode, string_type a_sIdent)
+    :m_eCode(a_iCode)
+    ,m_sIdent(a_sIdent)
+    ,m_nPosExpr(-1)
+    ,m_nRefCount(0)
+    ,m_flags(0)
+  {
+#ifdef MUP_LEAKAGE_REPORT
+    IToken::s_Tokens.push_back(this);
+#endif
+  }
+
+  /** \brief Destructor (trivial). */
+  IToken::~IToken()
+  {
+#ifdef MUP_LEAKAGE_REPORT
+    std::list<IToken*>::iterator it = std::find(IToken::s_Tokens.begin(), IToken::s_Tokens.end(), this);
+    IToken::s_Tokens.remove(this);
+#endif
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Copy constructor. 
+      \param ref The token to copy basic state information from.
+
+    The copy constructor must be implemented in order not to screw up
+    the reference count of the created object. CC's are used in the
+    Clone function and they would start with a reference count != 0 
+    introducing memory leaks if the default CC where used.
+  */
+  IToken::IToken(const IToken &ref)
+  {
+    m_eCode  = ref.m_eCode;
+    m_sIdent = ref.m_sIdent;
+    m_flags  = ref.m_flags;
+    m_nPosExpr = ref.m_nPosExpr;
+
+    // The following items must be initialised 
+    // (rather than just beeing copied)
+    m_nRefCount = 0;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::ResetRef()
+  {
+    m_nRefCount = 0;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::Release()
+  {
+    delete this;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type IToken::ToString() const
+  {
+    return AsciiDump();
+  }
+
+  //------------------------------------------------------------------------------
+  int IToken::GetExprPos() const
+  {
+    return m_nPosExpr;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::SetExprPos(int nPos)
+  {
+    m_nPosExpr = nPos;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief return the token code. 
+     
+      \sa ECmdCode
+  */
+  ECmdCode IToken::GetCode() const
+  {
+    return m_eCode;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the token identifier string. */
+  const string_type& IToken::GetIdent() const
+  {
+    return m_sIdent;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::SetIdent(const string_type &a_sIdent)
+  {
+    m_sIdent = a_sIdent;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type IToken::AsciiDump() const
+  {
+    stringstream_type ss;
+    ss << g_sCmdCode[m_eCode];
+    return ss.str().c_str();
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::IncRef() const
+  {
+    ++m_nRefCount;
+  }
+
+  //------------------------------------------------------------------------------
+  long IToken::DecRef() const
+  {
+    return --m_nRefCount;
+  }
+
+  //------------------------------------------------------------------------------
+  long IToken::GetRef() const
+  {
+    return m_nRefCount;
+  }
+
+  //---------------------------------------------------------------------------
+  void IToken::AddFlags(int flags)
+  {
+    m_flags |= flags;
+  }
+
+  //---------------------------------------------------------------------------
+  bool IToken::IsFlagSet(int flags) const
+  {
+    return (m_flags & flags)==flags;
+  }
+
+  //---------------------------------------------------------------------------
+  ICallback* IToken::AsICallback()
+  {
+    return NULL;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue* IToken::AsIValue()
+  {
+    return NULL;
+  }
+
+  //---------------------------------------------------------------------------
+  IPrecedence* IToken::AsIPrecedence()
+  {
+    return NULL;
+  }
+
+  //------------------------------------------------------------------------------
+  IOprtIndex* IToken::AsIOprtIndex()
+  {
+    return NULL;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::Compile(const string_type &sArg)
+  {
+  }
+
+  //---------------------------------------------------------------------------
+  //
+  // Generic token implementation
+  //
+  //---------------------------------------------------------------------------
+
+  GenericToken::GenericToken(ECmdCode a_iCode, string_type a_sIdent)
+    :IToken(a_iCode, a_sIdent)
+  {}
+
+  //---------------------------------------------------------------------------
+  GenericToken::GenericToken(ECmdCode a_iCode)
+    :IToken(a_iCode, _T(""))
+  {}
+
+  //---------------------------------------------------------------------------
+  GenericToken::~GenericToken()
+  {}
+
+  //---------------------------------------------------------------------------
+  GenericToken::GenericToken(const GenericToken &a_Tok)
+    :IToken(a_Tok)
+  {}
+
+  //---------------------------------------------------------------------------
+  IToken* GenericToken::Clone() const
+  {
+    return new GenericToken(*this);
+  }
+  
+  //------------------------------------------------------------------------------
+  string_type GenericToken::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << _T("]");
+
+    return ss.str();
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIToken.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIToken.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,223 @@
+/*
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_ITOKEN_H
+#define MUP_ITOKEN_H
+
+#include <list>
+#include "mpTypes.h"
+#include "mpFwdDecl.h"
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Generic token interface for expression tokens. 
+      \author (C) 2010 Ingo Berg 
+
+      Tokens can either be Functions, operators, values, variables or necessary 
+      base tokens like brackets. ´The IToken baseclass implements reference 
+      counting. Only TokenPtr<...> templates may be used as pointers to tokens.
+  */
+  class IToken
+  {
+  friend std::ostream& operator<<(std::ostream &a_Stream, const IToken &a_Val);
+  friend std::wostream& operator<<(std::wostream &a_Stream, const IToken &a_Val);
+
+  friend class TokenPtr<IToken>;
+  friend class TokenPtr<IValue>;
+  friend class TokenPtr<IOprtBin>;
+  friend class TokenPtr<IFunction>;
+  friend class TokenPtr<Value>;
+  friend class TokenPtr<Variable>;
+
+  public:
+
+    enum EFlags
+    {
+      flNONE = 0,
+      flVOLATILE = 1
+    };
+
+    virtual IToken* Clone() const = 0;
+    virtual string_type ToString() const;
+    virtual string_type AsciiDump() const;
+    
+    virtual ICallback* AsICallback();
+    virtual IValue* AsIValue();
+    virtual IPrecedence* AsIPrecedence();
+    virtual IOprtIndex* AsIOprtIndex();
+
+    virtual void Compile(const string_type &sArg);
+
+    ECmdCode GetCode() const;
+    int GetExprPos() const;
+    
+    const string_type& GetIdent() const;
+    long GetRef() const;
+    void SetIdent(const string_type &a_sIdent);
+    void SetExprPos(int nPos);
+
+    void AddFlags(int flags);
+    bool IsFlagSet(int flags) const;
+
+  protected:
+
+    explicit IToken(ECmdCode a_iCode);
+    virtual ~IToken();
+    IToken(ECmdCode a_iCode, string_type a_sIdent);
+    IToken(const IToken &ref);
+
+    void ResetRef();
+
+  private:
+
+    /** \brief Release the token. 
+    
+      This Function either deletes the token or releases it to
+      the value cache for reuse without deletion.
+    */
+    virtual void Release();
+
+    void IncRef() const;
+    long DecRef() const;
+
+    ECmdCode m_eCode;
+    string_type m_sIdent;
+    int m_nPosExpr;           ///< Original position of the token in the expression
+    mutable long m_nRefCount; ///< Reference counter.
+    int m_flags;
+
+#ifdef MUP_LEAKAGE_REPORT
+    static std::list<IToken*> s_Tokens;
+
+  public:
+    static void LeakageReport();
+#endif
+  };
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Default token implentation. 
+  */
+  class GenericToken : public IToken
+  {
+  public:
+      GenericToken(ECmdCode a_iCode, string_type a_sIdent);
+      explicit GenericToken(ECmdCode a_iCode);
+      GenericToken(const GenericToken &a_Tok);      
+      virtual ~GenericToken();
+      virtual IToken* Clone() const;
+      virtual string_type AsciiDump() const;
+  };
+
+  //------------------------------------------------------------------------------
+  template<typename T>
+  class TokenPtr
+  {
+  public:
+     
+      typedef T* token_type;
+
+      //---------------------------------------------------------------------------
+      explicit TokenPtr(token_type p = 0)
+        :m_pTok(p)
+      {
+        if (m_pTok)
+          m_pTok->IncRef();
+      }
+
+      //---------------------------------------------------------------------------
+      TokenPtr(const TokenPtr &p)
+        :m_pTok(p.m_pTok)
+      {
+        if (m_pTok)
+          m_pTok->IncRef();
+      }
+
+      //---------------------------------------------------------------------------
+     ~TokenPtr()
+      {
+        if (m_pTok && m_pTok->DecRef()==0)
+          m_pTok->Release();
+      }
+
+      //---------------------------------------------------------------------------
+      token_type operator->() const
+      {
+        return static_cast<token_type>(m_pTok);
+      }
+  
+      //---------------------------------------------------------------------------
+      T& operator*() const
+      {
+        assert(m_pTok);
+        return *(static_cast<token_type>(m_pTok));
+      }
+
+      //---------------------------------------------------------------------------
+      token_type Get() const
+      {
+        return static_cast<token_type>(m_pTok);
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Release the managed pointer and assign a new pointer. */
+      void Reset(token_type tok)
+      {
+        if (m_pTok && m_pTok->DecRef()==0) 
+        {
+          m_pTok->Release();
+          //delete m_pTok;
+        }
+
+        tok->IncRef();
+        m_pTok = tok;
+      }
+
+      //---------------------------------------------------------------------------
+      TokenPtr& operator=(const TokenPtr &p)
+      {
+        if (p.m_pTok) 
+          p.m_pTok->IncRef();
+
+        if (m_pTok && m_pTok->DecRef()==0) 
+        {
+          m_pTok->Release();
+          //delete m_pTok;
+        }
+
+        m_pTok = p.m_pTok;
+
+        return *this;
+      }
+
+  private:
+      IToken *m_pTok;
+  };
+
+MUP_NAMESPACE_END
+
+#endif // include guard
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIValReader.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIValReader.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,62 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpIValReader.h"
+#include "mpTokenReader.h"
+
+#include <cassert>
+
+
+MUP_NAMESPACE_START
+
+//--------------------------------------------------------------------------------------------
+    IValueReader::IValueReader()
+      :m_pTokenReader(NULL)
+    {}
+
+    //--------------------------------------------------------------------------------------------
+    IValueReader::~IValueReader() 
+    {}
+
+    //--------------------------------------------------------------------------------------------
+    IValueReader::IValueReader(const IValueReader &ref)
+    {
+      m_pTokenReader = ref.m_pTokenReader;
+    }
+
+    //--------------------------------------------------------------------------------------------
+    void IValueReader::SetParent(TokenReader *pTokenReader)
+    {
+      assert(pTokenReader);
+      m_pTokenReader = pTokenReader;
+    }
+
+    //--------------------------------------------------------------------------------------------
+    const IToken* IValueReader::TokenHistory(std::size_t pos) const
+    {
+      const TokenReader::token_buf_type &buf = m_pTokenReader->GetTokens();
+      std::size_t size = buf.size();
+      return (pos>=size) ? NULL : buf[size-1-pos].Get();
+    }
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIValReader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIValReader.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,91 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MU_IPARSER_VALUE_READER_H
+#define MU_IPARSER_VALUE_READER_H
+
+#include "mpValue.h"
+#include "mpIToken.h"
+#include "mpTokenReader.h"
+
+/** \defgroup valreader Value reader classes
+
+  This group lists all classes that detect and parse values in an expression string.
+*/
+
+
+MUP_NAMESPACE_START
+
+  class TokenReader;
+
+  /** \brief Interface for custom value reader objects. 
+      \ingroup valreader
+
+    Value readers are objects used for identifying values 
+    in an expression.
+  */
+  class IValueReader
+  {
+  public:
+
+    IValueReader();
+    IValueReader(const IValueReader &ref);
+
+    virtual ~IValueReader();
+
+    /** \brief Check a certain position in an expression for the presence of a value. 
+        \param a_iPos [in/out] Reference to an integer value representing the current 
+                      position of the parser in the expression.
+        \param a_Val If a value is found it is stored in a_Val
+        \return true if a value was found
+    */
+    virtual bool IsValue(const char_type *a_szExpr,
+                         int &a_iPos, 
+                         Value &a_Val ) = 0;
+
+    /** \brief Clone this ValueReader object. 
+        \return Pointer to the cloned value reader object.
+    */
+    virtual IValueReader* Clone(TokenReader *pParent) const = 0;
+    
+    /** \brief Assign this value reader object to a token 
+               reader object. 
+    
+      The token reader does the tokenization of the expression.
+      It uses this value reader to detect values.
+    */
+    virtual void SetParent(TokenReader *pTokenReader);
+
+  protected:
+
+    const IToken* TokenHistory(std::size_t pos) const;
+
+  private:
+
+    TokenReader *m_pTokenReader;  ///< Pointer to the TokenReader class used for token recognition
+  }; // class IValueReader
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIValue.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIValue.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,435 @@
+/** \file
+    \brief Implementation of the virtual base class used for all parser values.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpIValue.h"
+
+//--- Standard includes ------------------------------------------------------
+#include <cassert>
+
+//--- muParserX framework -----------------------------------------------------
+#include "mpValue.h"
+#include "mpError.h"
+#include "mpValue.h"
+
+
+MUP_NAMESPACE_START
+
+#ifndef _UNICODE
+
+  //---------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is not defined.
+  */
+  std::ostream& operator<<(std::ostream &a_Stream, const IValue &a_Val)
+  {
+    return a_Stream << a_Val.ToString();
+  }  
+
+#else
+
+  //---------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is defined.
+  */
+  std::wostream& operator<<(std::wostream &a_Stream, const IValue &a_Val)
+  {
+    return a_Stream << a_Val.ToString();
+  }  
+#endif
+
+  //---------------------------------------------------------------------------------------------
+  Value operator*(const IValue& lhs, const IValue& rhs)
+  {
+    return Value(lhs) *= rhs;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue::IValue(ECmdCode a_iCode)
+    :IToken(a_iCode)
+  {
+    assert(a_iCode==cmVAL || a_iCode==cmVAR);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue::IValue(ECmdCode a_iCode, const string_type &a_sIdent)
+    :IToken(a_iCode, a_sIdent)
+  {
+    assert(a_iCode==cmVAL || a_iCode==cmVAR);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue::~IValue()
+  {}
+
+  //---------------------------------------------------------------------------
+  ICallback* IValue::AsICallback()
+  {
+    return NULL;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue* IValue::AsIValue()
+  {
+    return this;
+  }
+
+  //---------------------------------------------------------------------------
+  string_type IValue::ToString() const
+  {
+    stringstream_type ss;
+    switch (GetType())
+    {
+    case 'm':  
+          {
+            const matrix_type &arr(GetArray());
+
+            if (arr.GetRows()>1)
+              ss << _T("{");
+
+            for (int i=0; i<arr.GetRows(); ++i)
+            {
+              if (arr.GetCols()>1)
+                ss << _T("{");
+
+              for (int j=0; j<arr.GetCols();++j)
+              {
+                ss << arr.At(i, j).ToString();
+                if (j!=arr.GetCols()-1)
+                  ss << _T(", ");
+              }
+
+              if (arr.GetCols()>1)
+                ss << _T("}");
+
+              if (i!=arr.GetRows()-1)
+                ss << _T("; ");
+            }
+
+            if (arr.GetRows()>1)
+              ss << _T("} ");
+          }
+          break;
+
+    case 'c':
+              {
+                float_type re = GetFloat(),
+                           im = GetImag();
+								
+								// realteil nicht ausgeben, wenn es eine rein imaginäre Zahl ist
+								if (im==0 || re!=0 || (im==0 && re==0))
+									ss << re;
+
+                if (im!=0)
+                {
+	                if (im>0 && re!=0)
+	                  ss << _T("+");
+									
+									if (im!=1)
+	                  ss << im;
+
+                  ss << _T("i");
+                }
+              }
+              break;
+            
+    case 'i':  
+    case 'f':  ss << GetFloat(); break;
+    case 's':  ss << _T("\"") << GetString() << _T("\""); break;
+    case 'b':  ss << ((GetBool()==true) ? _T("true"):_T("false")); break;
+    case 'v':  ss << _T("void"); break;
+    default:   ss << _T("internal error: unknown value type."); break;
+    }
+
+    return ss.str();
+  }
+
+  //---------------------------------------------------------------------------
+  bool IValue::operator==(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 'i': 
+      case 'f': return GetFloat()   == a_Val.GetFloat();
+      case 'c': return GetComplex() == a_Val.GetComplex();
+      case 's': return GetString()  == a_Val.GetString();
+      case 'b': return GetBool()    == a_Val.GetBool();
+      case 'v': return false;
+      case 'm': if (GetRows()!=a_Val.GetRows() || GetCols()!=a_Val.GetCols())
+                {
+                  return false;
+                }
+                else
+                {
+                  for (int i=0; i<GetRows(); ++i)
+                  {
+                    if (const_cast<IValue*>(this)->At(i)!=const_cast<IValue&>(a_Val).At(i))
+                      return false;
+                  }
+
+                  return true;
+                }
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+      } // switch this type
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool IValue::operator!=(const IValue &a_Val) const
+  {
+      char_type type1 = GetType(),
+                type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() != a_Val.GetString();
+      case 'i': 
+      case 'f': return GetFloat() != a_Val.GetFloat();
+      case 'c': return (GetFloat() != a_Val.GetFloat()) || (GetImag() != a_Val.GetImag());
+      case 'b': return GetBool() != a_Val.GetBool();
+      case 'v': return true;
+      case 'm': if (GetRows()!=a_Val.GetRows() || GetCols()!=a_Val.GetCols())
+                {
+                  return true;
+                }
+                else
+                {
+                  for (int i=0; i<GetRows(); ++i)
+                  {
+                    if (const_cast<IValue*>(this)->At(i)!=const_cast<IValue&>(a_Val).At(i))
+                      return true;
+                  }
+
+                  return false;
+                }
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type2 = GetType();
+                err.Type1 = a_Val.GetType();
+                throw ParserError(err);
+      } // switch this type
+    }
+    else
+    {
+      return true;
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool IValue::operator<(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() < a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() < a_Val.GetFloat();
+      case 'b': return GetBool() < a_Val.GetBool();
+                
+      default: 
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool IValue::operator> (const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() > a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() > a_Val.GetFloat();
+      case 'b': return GetBool()  > a_Val.GetBool();
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool IValue::operator>=(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() >= a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() >= a_Val.GetFloat();
+      case 'b': return GetBool() >= a_Val.GetBool();
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool IValue::operator<=(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() <= a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() <= a_Val.GetFloat();
+      case 'b': return GetBool()  <= a_Val.GetBool();
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& IValue::operator=(const IValue &ref)
+  {
+    if (this==&ref)
+      return *this;
+
+    switch(ref.GetType())
+    {
+    case 'i': 
+    case 'f': 
+    case 'c': return *this = cmplx_type(ref.GetFloat(), ref.GetImag());
+    case 's': return *this = ref.GetString();
+    case 'm': return *this = ref.GetArray();
+    case 'b': return *this = ref.GetBool();
+    case 'v': 
+      throw ParserError(_T("Assignment from void type is not possible"));
+
+    default:  
+      throw ParserError(_T("Internal error: unexpected data type identifier in IValue& operator=(const IValue &ref)"));
+    }
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIValue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIValue.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,189 @@
+/** \file
+    \brief Definition of the virtual base class used for all parser values.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_IVALUE_H
+#define MUP_IVALUE_H
+
+#include "mpIToken.h"
+#include "mpFwdDecl.h"
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Interface to be implemented by all classes representing values. 
+  
+    IValue is the common base class of both the Value and Variable classes.
+  */
+  class IValue : public IToken
+  {
+  friend std::ostream& operator<<(std::ostream &a_Stream, const IValue &a_Val);
+  friend std::wostream& operator<<(std::wostream &a_Stream, const IValue &a_Val);
+
+  public:
+
+    explicit IValue(ECmdCode a_iCode);
+    IValue(ECmdCode a_iCode, const string_type &a_sIdent);
+    
+    bool operator==(const IValue &a_Val) const;
+    bool operator!=(const IValue &a_Val) const;
+    bool operator< (const IValue &a_Val) const;
+    bool operator> (const IValue &a_Val) const;
+    bool operator<=(const IValue &a_Val) const;
+    bool operator>=(const IValue &a_Val) const;
+
+    virtual ICallback* AsICallback();
+    virtual IValue* AsIValue();
+    virtual Value* AsValue() = 0;
+
+    virtual IValue& operator=(int_type val) = 0;
+    virtual IValue& operator=(float_type val) = 0;
+    virtual IValue& operator=(string_type val) = 0;
+    virtual IValue& operator=(bool_type val) = 0;
+    virtual IValue& operator=(const cmplx_type &val) = 0;
+    virtual IValue& operator=(const matrix_type &val) = 0;
+            IValue& operator=(const IValue &ref);
+
+    virtual IValue& operator+=(const IValue &ref) = 0;
+    virtual IValue& operator-=(const IValue &ref) = 0;
+    virtual IValue& operator*=(const IValue &ref) = 0;
+
+    virtual IValue& At(int nRow, int nCol = 0) = 0;
+    virtual IValue& At(const IValue &nRows, const IValue &nCols) = 0;
+
+    virtual int_type GetInteger() const = 0;
+    virtual float_type GetFloat() const = 0;
+    virtual float_type GetImag() const = 0;
+    virtual bool GetBool() const = 0;
+    virtual const cmplx_type& GetComplex() const = 0;
+    virtual const string_type&  GetString() const = 0;
+    virtual const matrix_type& GetArray() const = 0;
+    virtual char_type GetType() const = 0;
+    virtual int GetRows() const = 0;
+    virtual int GetCols() const = 0;
+
+    virtual bool IsVolatile() const = 0;
+    virtual string_type ToString() const;
+  
+    //---------------------------------------------------------------------------
+    /** \brief Returns the dimension of the value represented by a value object.
+        
+        The value represents the dimension of the object. Possible value are:
+        <ul>
+          <li>0 - scalar</li>
+          <li>1 - vector</li>
+          <li>2 - matrix</li>
+        </ul>
+    */
+    inline int GetDim() const
+    {
+      return (IsMatrix()) ? GetArray().GetDim() : 0;
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if the type is either floating point or interger. 
+        \throw nothrow
+    */
+    inline bool IsNonComplexScalar() const
+    {
+      char_type t = GetType();
+      return t=='f' || t=='i';
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if the type is not a vector and not a string.
+        \throw nothrow
+    */
+    inline bool IsScalar() const
+    {
+      char_type t = GetType();
+      return t=='f' || t=='i' || t=='c';
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is a noncomplex integer. 
+        \throw nothrow
+    */
+    inline bool IsInteger() const
+    {
+      // checking the type is is insufficient. The integer could be disguised
+      // as a float or a complex value
+      return IsScalar() && GetImag()==0 && GetFloat()==(int_type)GetFloat();
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is an array. 
+        \throw nothrow
+    */  
+    inline bool IsMatrix() const 
+    {
+      return GetType() == 'm';  
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is a complex value. 
+        \throw nothrow
+    */
+    inline bool IsComplex() const
+    {
+      return GetType() == 'c' && GetImag()!=0;
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is a string value. 
+        \throw nothrow
+    */
+    inline bool IsString() const 
+    {
+      return GetType() == 's';  
+    }
+
+  protected:
+    virtual ~IValue();
+  }; // class IValue
+
+  //---------------------------------------------------------------------------------------------
+  Value operator*(const IValue& lhs, const IValue& rhs);
+
+/*
+  //---------------------------------------------------------------------------------------------
+  IValue operator+(const IValue& lhs, const IValue& rhs)
+  {
+    return Value(lhs) += rhs;
+  }
+
+  //---------------------------------------------------------------------------------------------
+  IValue operator-(const IValue& lhs, const IValue& rhs)
+  {
+    return Value(lhs) -= rhs;
+  }
+*/
+}  // namespace mu
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIfThenElse.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIfThenElse.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,65 @@
+#include "mpIfThenElse.h"
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  //
+  // If part of if-then-else clauses
+  //
+  //---------------------------------------------------------------------------
+
+  TokenIfThenElse::TokenIfThenElse(ECmdCode eCode)
+    :IToken(eCode, g_sCmdCode[ eCode ])
+    ,IPrecedence()
+    ,m_nOffset()
+  {}
+
+  //---------------------------------------------------------------------------
+  IToken* TokenIfThenElse::Clone() const
+  {
+    return new TokenIfThenElse(*this);
+  }
+
+  //---------------------------------------------------------------------------
+  void TokenIfThenElse::SetOffset(int nOffset)
+  {
+    m_nOffset = nOffset;
+  }
+
+  //---------------------------------------------------------------------------
+  int TokenIfThenElse::GetOffset() const
+  {
+    return m_nOffset;
+  }
+
+  //---------------------------------------------------------------------------
+  string_type TokenIfThenElse::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << GetIdent();
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; offset=") << m_nOffset;
+    ss << _T("]");
+    return ss.str();
+  }
+  
+  //---------------------------------------------------------------------------
+  int TokenIfThenElse::GetPri() const
+  {
+    return (int)prIF_THEN_ELSE;
+  }
+
+  //---------------------------------------------------------------------------
+  EOprtAsct TokenIfThenElse::GetAssociativity() const
+  {
+    return oaNONE;
+  }
+
+  //---------------------------------------------------------------------------
+  IPrecedence* TokenIfThenElse::AsIPrecedence()
+  {
+    return this;
+  }
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpIfThenElse.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpIfThenElse.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,70 @@
+/** \file
+    \brief Definition of basic types used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#ifndef MUP_IF_THEN_ELSE_H
+#define MUP_IF_THEN_ELSE_H
+
+#include "mpIToken.h"
+#include "mpIPrecedence.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief A class for encapsulation if-then-else tokens. */
+  class TokenIfThenElse : public IToken,
+                          public IPrecedence
+  {
+  public:
+
+      TokenIfThenElse(ECmdCode eCmd);
+      void SetOffset(int nOffset);
+      int GetOffset() const;
+
+      //---------------------------------------------
+      // IToken interface
+      //---------------------------------------------
+
+      virtual IToken* Clone() const;
+      virtual string_type AsciiDump() const;
+      virtual IPrecedence* AsIPrecedence();
+
+      //---------------------------------------------
+      // IPrecedence interface
+      //---------------------------------------------
+
+      virtual int GetPri() const;
+      virtual EOprtAsct GetAssociativity() const;
+
+  private:
+      int m_nOffset;
+  };
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpMatrix.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpMatrix.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,417 @@
+#ifndef MU_MATRIX_H
+#define MU_MATRIX_H
+
+#include <vector>
+#include <cassert>
+#include <iostream>
+#include <stdexcept>
+#include <sstream>
+#include "mpMatrixError.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------------------------------
+  template<class T>
+  class Matrix  
+  {
+  template<class T2>
+  friend Matrix operator+(const Matrix& lhs, const Matrix& rhs);
+
+  template<class T2>
+  friend Matrix operator-(const Matrix& lhs, const Matrix& rhs);
+
+  public:
+
+    //---------------------------------------------------------------------------------------------
+    enum EMatrixStorageScheme
+    {
+      mssROWS_FIRST,
+      mssCOLS_FIRST
+    };
+
+    //---------------------------------------------------------------------------------------------
+    Matrix()
+      :m_nRows(1)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(1)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    Matrix(int nRows, const T &value = T())
+      :m_nRows(nRows)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(m_nRows, value)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    /* \brief Constructs a Matrix object representing a scalar value
+    */
+    Matrix(const T &v)
+      :m_nRows(1)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(1, v)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    /* \brief Constructs a Matrix object representing a vector
+    */
+    Matrix(const std::vector<T> &v)
+      :m_nRows(v.size())
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(v)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    /* Constructs a Matrix object representing a vector
+    */
+    template<size_t TSize>
+    Matrix(T (&v)[TSize])
+      :m_nRows(TSize)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(v, v + TSize)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    template<size_t TRows, size_t TCols>
+    Matrix(T (&v)[TRows][TCols])
+      :m_nRows(TRows)
+      ,m_nCols(TCols)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(TRows*TCols, 0)
+    {
+      for (int m=0; m<TRows; ++m)
+      {
+        for (int n=0; n<TCols; ++n)
+        {
+          At(m,n) = v[m][n];
+        }
+      }
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix(int nRows, int nCols, const T &value = T())
+      :m_nRows(nRows)
+      ,m_nCols(nCols)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(m_nRows*m_nCols, value)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    Matrix(const Matrix &ref)
+    {
+      Assign(ref);
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator=(const Matrix &ref)
+    {
+      if (this!=&ref)
+        Assign(ref);
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator=(const T &v)
+    {
+      m_nCols = 1;
+      m_nRows = 1;
+      m_eStorageScheme = mssROWS_FIRST;
+      m_vData.assign(1, v);
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator+=(const Matrix &lhs)
+    {
+      if (m_nRows!=lhs.m_nRows || m_nCols!=lhs.m_nCols)
+        throw MatrixError("Matrix dimension mismatch");
+
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          At(i,j) += lhs.At(i,j);
+        }
+      }
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator-=(const Matrix &lhs)
+    {
+      if (m_nRows!=lhs.m_nRows || m_nCols!=lhs.m_nCols)
+        throw MatrixError("Matrix dimension mismatch");
+
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          At(i,j) -= lhs.At(i,j);
+        }
+      }
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator*=(const T &rhs)
+    {
+      // Matrix x Matrix multiplication
+      for (int m=0; m<m_nRows; ++m)
+      {
+        for (int n=0; n<m_nCols; ++n)
+        {
+          At(m, n) *= rhs;
+        }
+      }
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator*=(const Matrix &rhs)
+    {
+      // Matrix x Matrix multiplication
+      if (rhs.GetRows()==0)
+      {
+        T v = rhs.At(0,0);
+        for (int m=0; m<m_nRows; ++m)
+        {
+          for (int n=0; n<m_nCols; ++n)
+          {
+            At(m, n) *= v;
+          }
+        }
+      }
+      else if (GetRows()==0)
+      {
+        T v = At(0,0);
+        Assign(rhs);
+        for (int m=0; m<m_nRows; ++m)
+        {
+          for (int n=0; n<m_nCols; ++n)
+          {
+            At(m, n) *= v;
+          }
+        }
+      }
+      else if (m_nCols==rhs.m_nRows)
+      {
+        Matrix<T> out(m_nRows, rhs.m_nCols);
+        
+        // For each cell in the output matrix
+        for (int m=0; m<m_nRows; ++m)
+        {
+          for (int n=0; n<rhs.m_nCols; ++n)
+          {
+            T buf = 0;
+            for (int i=0; i<m_nCols; ++i)
+            {
+              buf += At(m, i) * rhs.At(i, n);
+            }
+            out.At(m,n) = buf;
+          } // for all rows
+        } // for all columns
+
+        Assign(out);
+      }
+      else
+        throw MatrixError("Matrix dimensions don't allow multiplication");
+      
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    void AsciiDump(const char *szTitle) const
+    {
+      using namespace std;
+
+      cout << szTitle << _T("\n");
+      cout << _T("------------------\n");
+      cout << _T("Cols: ") << GetCols() << _T("\n");
+      cout << _T("Rows: ") << GetRows() << _T("\n");
+      cout << _T("Dim:  ") << GetDim()  << _T("\n");
+
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          cout << At(i, j) << _T("  ");
+        }
+        cout << _T("\n");
+      }
+
+      cout << _T("\n\n");
+    }
+
+    //---------------------------------------------------------------------------------------------
+    std::string ToString() const
+    {
+      std::stringstream ss;
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          ss << At(i, j) << "  ";
+        }
+        ss << "\n";
+      }
+
+      return ss.str();
+    }
+
+    //---------------------------------------------------------------------------------------------
+   ~Matrix()
+    {
+      m_vData.clear();
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int GetRows() const
+    {
+      return m_nRows;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int GetCols() const
+    {
+      return m_nCols;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int GetDim() const
+    {
+      if (m_nCols==1)
+      {
+        return (m_nRows==1) ? 0 : 1;
+      }
+      else
+        return 2;
+    }
+  
+    //---------------------------------------------------------------------------------------------
+    T& At(int nRow, int nCol = 0)
+    {
+      int i;
+      if (m_eStorageScheme==mssROWS_FIRST)
+      {
+        i = nRow * m_nCols + nCol;
+      }
+      else
+      {
+        i = nCol * m_nRows + nRow;
+      }
+
+      assert(i<(int)m_vData.size());
+      return m_vData[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    const T& At(int nRow, int nCol = 0) const
+    {
+      int i;
+      if (m_eStorageScheme==mssROWS_FIRST)
+      {
+        i = nRow * m_nCols + nCol;
+      }
+      else
+      {
+        i = nCol * m_nRows + nRow;
+      }
+
+      assert(i<(int)m_vData.size());
+      return m_vData[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    const T* GetData() const
+    {
+      assert(m_vData.size());
+      return &m_vData[0];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    void SetStorageScheme(EMatrixStorageScheme eScheme)
+    {
+      m_eStorageScheme = eScheme;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    EMatrixStorageScheme GetStorageScheme() const
+    {
+      return m_eStorageScheme;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix<T>& Transpose()
+    {
+      if (GetDim()==0)
+        return *this;
+
+      m_eStorageScheme = (m_eStorageScheme==mssROWS_FIRST) ? mssCOLS_FIRST : mssROWS_FIRST;
+      m_nRows ^= m_nCols ^= m_nRows ^= m_nCols;
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    void Fill(const T &v)
+    {
+      m_vData.assign(m_vData.size(), v);
+    }
+
+  private:
+    int m_nCols;
+    int m_nRows;
+    std::vector<T> m_vData;
+    EMatrixStorageScheme m_eStorageScheme;
+
+    //---------------------------------------------------------------------------------------------
+    void Assign(const Matrix &ref)
+    {
+      m_nCols = ref.m_nCols;
+      m_nRows = ref.m_nRows;
+      m_eStorageScheme = ref.m_eStorageScheme;
+      m_vData = ref.m_vData;
+    }
+  };
+
+  //---------------------------------------------------------------------------------------------
+  template<class T>
+  Matrix<T> operator*(const Matrix<T>& lhs, const T& rhs)
+  {
+    return Matrix<T>(lhs) *= rhs;
+  }
+
+  //---------------------------------------------------------------------------------------------
+  template<class T>
+  Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs)
+  {
+    return Matrix<T>(lhs) *= rhs;
+  }
+
+  //---------------------------------------------------------------------------------------------
+  template<class T>
+  Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs)
+  {
+    return Matrix<T>(lhs) += rhs;
+  }
+
+  //---------------------------------------------------------------------------------------------
+  template<class T>
+  Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs)
+  {
+    return Matrix<T>(lhs) -= rhs;
+  }
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpMatrixError.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpMatrixError.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,19 @@
+#ifndef MU_MATRIX_ERROR_H
+#define MU_MATRIX_ERROR_H
+
+#include <stdexcept>
+#include <string>
+
+MUP_NAMESPACE_START
+
+  class MatrixError : public std::runtime_error
+  {
+  public:
+    explicit MatrixError(const std::string &sMsg)
+        :std::runtime_error(sMsg)
+    {}
+  };
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtBinAssign.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtBinAssign.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,243 @@
+/** \file
+    \brief This file contains the implementation of binary assignment 
+           operators used in muParser.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpOprtBinAssign.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------
+  //
+  //  class OprtAssign
+  //
+  //---------------------------------------------------------------------
+
+  OprtAssign::OprtAssign() 
+    :IOprtBin(_T("="), (int)prASSIGN, oaLEFT)
+  {}
+
+  //---------------------------------------------------------------------
+  const char_type* OprtAssign::GetDesc() const 
+  { 
+    return _T("'=' assignement operator"); 
+  }
+
+  //---------------------------------------------------------------------
+  IToken* OprtAssign::Clone() const
+  { 
+    return new OprtAssign(*this); 
+  }
+  
+  //---------------------------------------------------------------------
+  void OprtAssign::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    Variable *pVar = dynamic_cast<Variable*>(a_pArg[0].Get());
+
+    // assigment to non variable type
+    if (!pVar)
+    {
+      ErrorContext err;
+      err.Arg   = 1;
+      err.Ident = _T("=");
+      err.Errc  = ecASSIGNEMENT_TO_VALUE;
+      throw ParserError(err);
+    }
+
+    *pVar = *a_pArg[1]; //pVar->SetFloat(a_pArg[1]->GetFloat());
+    *ret = *pVar; 
+  }
+
+  //---------------------------------------------------------------------
+  //
+  //  class OprtAssignAdd
+  //
+  //---------------------------------------------------------------------
+
+  OprtAssignAdd::OprtAssignAdd() 
+    :IOprtBin(_T("+="), (int)prASSIGN, oaLEFT) 
+  {}
+
+  //---------------------------------------------------------------------
+  void OprtAssignAdd::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)   
+  {
+    Variable *pVar = dynamic_cast<Variable*>(a_pArg[0].Get());
+
+    // assigment to non variable type
+    if (!pVar)
+    {
+      ErrorContext err;
+      err.Arg   = 1;
+      err.Ident = _T("+=");
+      err.Errc  = ecASSIGNEMENT_TO_VALUE;
+      throw ParserError(err);
+    }
+
+    *pVar = cmplx_type(a_pArg[0]->GetFloat() + a_pArg[1]->GetFloat(),
+                       a_pArg[0]->GetImag() + a_pArg[1]->GetImag());
+    *ret = *pVar;
+  }
+
+  //---------------------------------------------------------------------
+  const char_type* OprtAssignAdd::GetDesc() const 
+  { 
+    return _T("assignement operator"); 
+  }
+
+  //---------------------------------------------------------------------
+  IToken* OprtAssignAdd::Clone() const            
+  { 
+    return new OprtAssignAdd(*this); 
+  }
+
+  //---------------------------------------------------------------------
+  //
+  //  class OprtAssignAdd
+  //
+  //---------------------------------------------------------------------
+
+  OprtAssignSub::OprtAssignSub() 
+    :IOprtBin(_T("-="), (int)prASSIGN, oaLEFT) 
+  {}
+
+  //---------------------------------------------------------------------
+  void OprtAssignSub::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)   
+  {
+    Variable *pVar = dynamic_cast<Variable*>(a_pArg[0].Get());
+    if (!pVar)
+    {
+      ErrorContext err;
+      err.Arg   = 1;
+      err.Ident = _T("-=");
+      err.Errc  = ecASSIGNEMENT_TO_VALUE;
+      throw ParserError(err);
+    }
+
+    *pVar = cmplx_type(a_pArg[0]->GetFloat() - a_pArg[1]->GetFloat(),
+                       a_pArg[0]->GetImag() - a_pArg[1]->GetImag());
+    *ret = *pVar; 
+  }
+
+  //---------------------------------------------------------------------
+  const char_type* OprtAssignSub::GetDesc() const 
+  { 
+    return _T("assignement operator"); 
+  }
+
+  //---------------------------------------------------------------------
+  IToken* OprtAssignSub::Clone() const            
+  { 
+     return new OprtAssignSub(*this); 
+  }
+
+  //---------------------------------------------------------------------
+  //
+  //  class OprtAssignAdd
+  //
+  //---------------------------------------------------------------------
+
+  OprtAssignMul::OprtAssignMul() 
+    :IOprtBin(_T("*="), (int)prASSIGN, oaLEFT) 
+  {}
+
+  //---------------------------------------------------------------------
+  void OprtAssignMul::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+  {
+    Variable *pVar = dynamic_cast<Variable*>(a_pArg[0].Get());
+    if (!pVar)
+    {
+      ErrorContext err;
+      err.Arg   = 1;
+      err.Ident = _T("*=");
+      err.Errc  = ecASSIGNEMENT_TO_VALUE;
+      throw ParserError(err);
+    }
+
+    float_type a = a_pArg[0]->GetFloat(),
+               b = a_pArg[0]->GetImag(),
+               c = a_pArg[1]->GetFloat(),
+               d = a_pArg[1]->GetImag();
+    *pVar = cmplx_type(a*c-b*d, a*d-b*c); 
+    *ret = *pVar;
+  }
+
+  //---------------------------------------------------------------------
+  const char_type* OprtAssignMul::GetDesc() const 
+  { 
+    return _T("multiply and assign operator"); 
+  }
+
+  //---------------------------------------------------------------------
+  IToken* OprtAssignMul::Clone() const
+  {  
+    return new OprtAssignMul(*this); 
+  }
+
+  //---------------------------------------------------------------------
+  //
+  //  class OprtAssignDiv
+  //
+  //---------------------------------------------------------------------
+
+  OprtAssignDiv::OprtAssignDiv() : IOprtBin(_T("/="), (int)prASSIGN, oaLEFT) 
+  {}
+
+  //------------------------------------------------------------------------------
+  void OprtAssignDiv::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int)
+  {
+    Variable *pVar = dynamic_cast<Variable*>(a_pArg[0].Get());
+    if (!pVar)
+    {
+      ErrorContext err;
+      err.Arg   = 1;
+      err.Ident = _T("/=");
+      err.Errc  = ecASSIGNEMENT_TO_VALUE;
+      throw ParserError(err);
+    }
+
+    float_type a = a_pArg[0]->GetFloat(),
+               b = a_pArg[0]->GetImag(),
+               c = a_pArg[1]->GetFloat(),
+               d = a_pArg[1]->GetImag(),
+               n = c*c + d*d;
+    *pVar = cmplx_type((a*c+b*d)/n, (b*c-a*d)/n); 
+    *ret = *pVar; 
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* OprtAssignDiv::GetDesc() const 
+  { 
+     return _T("multiply and divide operator"); 
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* OprtAssignDiv::Clone() const
+  {  
+    return new OprtAssignDiv(*this); 
+  }
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtBinAssign.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtBinAssign.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,120 @@
+/** \file
+    \brief This file contains the definition of binary assignment 
+           operators used in muParser.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_OPRT_BIN_ASSIGN_H
+#define MUP_OPRT_BIN_ASSIGN_H
+
+//--- Standard includes ----------------------------------------------------------
+#include <cmath>
+
+//--- muParserX framework --------------------------------------------------------
+#include "mpIOprt.h"
+#include "mpValue.h"
+#include "mpVariable.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Assignement operator. 
+  
+      This operator can only be applied to variable items.
+  */
+  class OprtAssign : public IOprtBin
+  {
+  public:
+    
+    OprtAssign();
+
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Assignement operator. 
+    
+      This operator can only be applied to variable items.
+  */
+  class OprtAssignAdd : public IOprtBin
+  {
+  public:
+    OprtAssignAdd();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Assignement operator. 
+  
+      This operator can only be applied to variable items.
+  */
+  class OprtAssignSub : public IOprtBin
+  {
+  public:
+    OprtAssignSub();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Assignement operator. 
+  
+      This operator can only be applied to variable items.
+  */
+  class OprtAssignMul : public IOprtBin
+  {
+  public:
+    OprtAssignMul();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Assignement operator. 
+  
+      This operator can only be applied to variable items.
+  */
+  class OprtAssignDiv : public IOprtBin
+  {
+  public:
+    
+    OprtAssignDiv();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtBinCommon.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtBinCommon.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,356 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpOprtBinCommon.h"
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------
+  //
+  // class OprtAnd
+  //
+  //-----------------------------------------------------------
+
+  OprtAnd::OprtAnd() 
+    :IOprtBin(_T("&"), (int)prBIT_AND, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtAnd::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if (!a_pArg[0]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'i', 1));
+    
+    if (!a_pArg[1]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'i', 2));
+
+    float_type a = a_pArg[0]->GetFloat(),
+               b = a_pArg[1]->GetFloat();
+
+    if (a!=(int_type)a)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[0]->GetIdent(), a_pArg[0]->GetType(), 'i', 1) ); 
+    
+    if (b!=(int_type)b)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[1]->GetIdent(), a_pArg[1]->GetType(), 'i', 2) ); 
+
+    *ret = (int_type)a & (int_type)(b); 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtAnd::GetDesc() const 
+  { 
+    return _T("bitwise and"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtAnd::Clone() const
+  { 
+    return new OprtAnd(*this); 
+  }
+
+  //-----------------------------------------------------------
+  //
+  // class OprtOr
+  //
+  //-----------------------------------------------------------
+
+  OprtOr::OprtOr() 
+    :IOprtBin(_T("|"), (int)prBIT_OR, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtOr::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if (!a_pArg[0]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'i', 1));
+    
+    if (!a_pArg[1]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'i', 2));
+
+    float_type a = a_pArg[0]->GetFloat(),
+               b = a_pArg[1]->GetFloat();
+
+    if (a!=(int_type)a)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[0]->GetIdent(), a_pArg[0]->GetType(), 'i', 1) ); 
+    
+    if (b!=(int_type)b)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[1]->GetIdent(), a_pArg[1]->GetType(), 'i', 2) ); 
+
+    *ret = (int_type)a | (int_type)(b); 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtOr::GetDesc() const 
+  { 
+    return _T("bitwise or"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtOr::Clone() const
+  { 
+    return new OprtOr(*this); 
+  }
+
+  //-----------------------------------------------------------
+  //
+  // class OprtLOr
+  //
+  //-----------------------------------------------------------
+
+  OprtLOr::OprtLOr() 
+    :IOprtBin(_T("||"), (int)prLOGIC_OR, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtLOr::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+    *ret = a_pArg[0]->GetBool() || a_pArg[1]->GetBool(); 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtLOr::GetDesc() const 
+  { 
+    return _T("logical or"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtLOr::Clone() const
+  { 
+    return new OprtLOr(*this); 
+  }
+
+  //-----------------------------------------------------------
+  //
+  // class OprtLAnd
+  //
+  //-----------------------------------------------------------
+
+  OprtLAnd::OprtLAnd() 
+    :IOprtBin(_T("&&"), (int)prLOGIC_AND, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtLAnd::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+    *ret = a_pArg[0]->GetBool() && a_pArg[1]->GetBool(); 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtLAnd::GetDesc() const 
+  { 
+    return _T("logical and"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtLAnd::Clone() const
+  { 
+    return new OprtLAnd(*this); 
+  }
+
+  //-----------------------------------------------------------
+  //
+  // class OprtShl
+  //
+  //-----------------------------------------------------------
+
+  OprtShl::OprtShl() 
+    :IOprtBin(_T("<<"), (int)prSHIFT, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtShl::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if (!a_pArg[0]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'i', 1));
+    
+    if (!a_pArg[1]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'i', 2));
+
+    float_type a = a_pArg[0]->GetFloat(),
+               b = a_pArg[1]->GetFloat();
+
+    if (a!=(int_type)a)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[0]->GetIdent(), a_pArg[0]->GetType(), 'i', 1) ); 
+    
+    if (b!=(int_type)b)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[1]->GetIdent(), a_pArg[1]->GetType(), 'i', 2) ); 
+
+
+    *ret = (int_type)a << (int_type)(b); 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtShl::GetDesc() const 
+  { 
+    return _T("shift left"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtShl::Clone() const
+  { 
+    return new OprtShl(*this); 
+  }
+
+  //-----------------------------------------------------------
+  //
+  // class OprtShr
+  //
+  //-----------------------------------------------------------
+
+  OprtShr::OprtShr() 
+    :IOprtBin(_T(">>"), (int)prSHIFT, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtShr::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if (!a_pArg[0]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'i', 1));
+    
+    if (!a_pArg[1]->IsScalar())
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'i', 2));
+
+    float_type a = a_pArg[0]->GetFloat(),
+               b = a_pArg[1]->GetFloat();
+
+    if (a!=(int_type)a)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[0]->GetIdent(), a_pArg[0]->GetType(), 'i', 1) ); 
+    
+    if (b!=(int_type)b)
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[1]->GetIdent(), a_pArg[1]->GetType(), 'i', 2) ); 
+
+    *ret = (int_type)a >> (int_type)b; 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtShr::GetDesc() const 
+  { 
+    return _T("shift left"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtShr::Clone() const
+  { 
+    return new OprtShr(*this); 
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  //  Cast To Float
+  //
+  //------------------------------------------------------------------------------
+
+  OprtCastToFloat::OprtCastToFloat()
+    :IOprtInfix( _T("(float)"))
+  {}
+
+  //------------------------------------------------------------------------------
+  void OprtCastToFloat::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int /*a_iArgc*/)  
+  { 
+    switch(a_pArg[0]->GetType())
+    {
+    case 'i':
+    case 'f':  
+    case 'b':  
+         *ret = a_pArg[0]->GetFloat(); 
+         break;
+
+    default:
+      {
+        ErrorContext err;
+        err.Errc = ecINVALID_TYPECAST;
+        err.Type1 = a_pArg[0]->GetType();
+        err.Type2 = 'f';
+        throw ParserError(err);
+      } 
+    } // switch value type
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* OprtCastToFloat::GetDesc() const 
+  { 
+    return _T("cast a value into a floating point number"); 
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* OprtCastToFloat::Clone() const 
+  { 
+    return new OprtCastToFloat(*this); 
+  }
+
+
+  //------------------------------------------------------------------------------
+  //
+  //  Cast To Int
+  //
+  //------------------------------------------------------------------------------
+
+  OprtCastToInt::OprtCastToInt()
+    :IOprtInfix( _T("(int)"))
+  {}
+
+  //------------------------------------------------------------------------------
+  void OprtCastToInt::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int /*a_iArgc*/)  
+  { 
+    switch(a_pArg[0]->GetType())
+    {
+    case 'f':  
+    case 'i': 
+    case 'b':  
+         *ret = (int_type)a_pArg[0]->GetFloat();
+         break;
+
+    default:
+      {
+        ErrorContext err;
+        err.Errc = ecINVALID_TYPECAST;
+        err.Type1 = a_pArg[0]->GetType();
+        err.Type2 = 'i';
+        throw ParserError(err);
+      } 
+    } // switch value type
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* OprtCastToInt::GetDesc() const 
+  { 
+    return _T("cast a value into a floating point number"); 
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* OprtCastToInt::Clone() const 
+  { 
+    return new OprtCastToInt(*this); 
+  }
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtBinCommon.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtBinCommon.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,300 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MP_OPRT_BIN_H
+#define MP_OPRT_BIN_H
+
+/** \file 
+    \brief Definitions of classes used as callbacks for standard binary operators. 
+*/
+
+/** \defgroup binop Binary operator callbacks
+
+  This group lists the objects representing the binary operators of muParserX.
+*/
+
+#include <cmath>
+#include "mpIOprt.h"
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+#define MUP_NAME_PROXY_get_float_type  GetFloat
+#define MUP_NAME_PROXY_get_string_type GetString
+#define MUP_NAME_PROXY_get_bool_type   GetBool
+#define MUP_NAME_PROXY_get_value_type  
+
+/** \brief MUP_BINARY_OPERATOR(CLASS, IDENT, PROT, TYPE, DESC, PRI, OP)
+    \param CLASS Name of the class to be defined
+    \param IDENT The string to be used as the operator identifier
+    \param PROT A string representing the operators prototype
+    \param TYPE The datatype used for the operation
+    \param DESC A string containing the operator description
+    \param PRI The operator precedence
+    \param OP The operation to perform
+
+    A macro for simplifying the process of creating binary operator 
+    callback classes. 
+*/
+#define MUP_BINARY_OPERATOR(CLASS, IDENT, TYPE, DESC, PRI, ASC, OP)        \
+  class CLASS : public IOprtBin                                            \
+  {                                                                        \
+  public:                                                                  \
+    CLASS() : IOprtBin((IDENT), (PRI), (ASC)) {}                           \
+                                                                           \
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc)\
+    {                                                                      \
+      assert(argc==2);                                                     \
+      TYPE a = arg[0]->MUP_NAME_PROXY_get_##TYPE();                        \
+      TYPE b = arg[1]->MUP_NAME_PROXY_get_##TYPE();                        \
+      *ret = OP;                                                           \
+    }                                                                      \
+                                                                           \
+    virtual const char_type* GetDesc() const { return (DESC); }            \
+    virtual IToken* Clone() const            { return new CLASS(); }       \
+  }; 
+
+  // for string values
+  MUP_BINARY_OPERATOR(OprtStrAdd, _T("//"), string_type, _T(""), 2, oaLEFT, a+b)
+  // logical operators
+  MUP_BINARY_OPERATOR(OprtBAnd, _T("and"),  bool_type, _T("less than"), 1, oaLEFT, a&&b)
+  MUP_BINARY_OPERATOR(OprtBOr,  _T("or"),  bool_type, _T("less than"), 1, oaLEFT, a||b)
+  MUP_BINARY_OPERATOR(OprtBXor, _T("xor"),  bool_type, _T("less than"), 1, oaLEFT, (bool_type)(a^b))
+
+//#undef MUP_NAME_PROXY_get_float_type
+//#undef MUP_NAME_PROXY_get_string_type
+//#undef MUP_NAME_PROXY_get_bool_type
+//#undef MUP_BINARY_OPERATOR
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for testing if two values are equal.
+      \ingroup binop
+  */
+  class OprtEQ : public IOprtBin    
+  {
+  public:
+    OprtEQ() : IOprtBin(_T("=="), 2, oaLEFT) {}
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+    { 
+      *ret = *a_pArg[0] == *a_pArg[1]; 
+    }
+    virtual const char_type* GetDesc() const { return _T("equals operator"); }
+    virtual IToken* Clone() const            { return new OprtEQ; }
+  };
+
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for testing if two values are not equal.
+      \ingroup binop
+  */
+  class OprtNEQ : public IOprtBin    
+  {
+  public:
+    OprtNEQ() : IOprtBin(_T("!="), 2, oaLEFT) {}
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+    { 
+      *ret = *a_pArg[0] != *a_pArg[1]; 
+    }
+
+    virtual const char_type* GetDesc() const { return _T("neq operator"); }
+    virtual IToken* Clone() const            { return new OprtNEQ; }
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object class for the "Less than" operator.
+      \ingroup binop
+  */
+  class OprtLT : public IOprtBin    
+  {
+  public:
+    OprtLT() : IOprtBin(_T("<"), 2, oaLEFT) {}
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+    { 
+       *ret = *a_pArg[0] < *a_pArg[1];
+    }
+
+    virtual const char_type* GetDesc() const { return _T("less operator"); }
+    virtual IToken* Clone() const            { return new OprtLT; }
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object class for the "Greater than" operator.
+      \ingroup binop
+  */
+  class OprtGT : public IOprtBin    
+  {
+  public:
+    OprtGT() : IOprtBin(_T(">"), 2, oaLEFT) {}
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+    { 
+       *ret = *a_pArg[0] > *a_pArg[1]; 
+    }
+
+    virtual const char_type* GetDesc() const { return _T("greater than"); }
+    virtual IToken* Clone() const            { return new OprtGT; }
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object class for the "Less or equal" operator.
+      \ingroup binop
+  */
+  class OprtLE : public IOprtBin    
+  {
+  public:
+    OprtLE() : IOprtBin(_T("<="), 2, oaLEFT) {}
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+    { 
+      *ret = *a_pArg[0] <= *a_pArg[1];
+    }
+
+    virtual const char_type* GetDesc() const { return _T("less or equal operator"); }
+    virtual IToken* Clone() const            { return new OprtLE; }
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object class for the "Greater or or equal" operator.
+      \ingroup binop
+  */
+  class OprtGE : public IOprtBin    
+  {
+  public:
+    OprtGE() : IOprtBin(_T(">="), 2, oaLEFT) {}
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int)
+    { 
+       *ret = *a_pArg[0] >= *a_pArg[1]; 
+    }
+
+    virtual const char_type* GetDesc() const { return _T("greater or equal operator"); }
+    virtual IToken* Clone() const            { return new OprtGE; }
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback class for a logic and operator.
+      \ingroup binop
+  */
+  class OprtAnd : public IOprtBin    
+  {
+  public:
+    OprtAnd();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback class for a logic or operator.
+      \ingroup binop
+  */
+  class OprtOr : public IOprtBin    
+  {
+  public:
+    OprtOr();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback class for a logical or operator.
+      \ingroup binop
+  */
+  class OprtLOr : public IOprtBin    
+  {
+  public:
+    OprtLOr();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback class for a logical and operator.
+      \ingroup binop
+  */
+  class OprtLAnd : public IOprtBin    
+  {
+  public:
+    OprtLAnd();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback class for the shift left operator.
+      \ingroup binop
+  */
+  class OprtShl : public IOprtBin    
+  {
+  public:
+    OprtShl();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback class for the shift right operator.
+      \ingroup binop
+  */
+  class OprtShr : public IOprtBin    
+  {
+  public:
+    OprtShr();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for an operator allowing to cast values to floating 
+             point values.
+      \ingroup infix
+  */
+  class OprtCastToFloat : public IOprtInfix
+  {
+  public:
+    OprtCastToFloat();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class OprtCastToFloat
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for an operator allowing to cast values to integer values.
+      \ingroup infix
+  */
+  class OprtCastToInt : public IOprtInfix
+  {
+  public:
+    OprtCastToInt();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class OprtCastToInt
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtCmplx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtCmplx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,302 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpOprtCmplx.h"
+#include <iomanip>
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+//
+//  class  OprtSignCmplx
+//
+//------------------------------------------------------------------------------
+
+  OprtSignCmplx::OprtSignCmplx()
+    :IOprtInfix( _T("-"))
+  {}
+
+  //------------------------------------------------------------------------------
+  void OprtSignCmplx::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)  
+  { 
+    MUP_ASSERT(a_iArgc==1);
+
+    if (a_pArg[0]->IsScalar())
+    {
+      float_type re = a_pArg[0]->GetFloat();
+      float_type im = a_pArg[0]->GetImag();
+
+		  // Do not omit the test for zero! Multiplying 0 with -1 
+      // will yield -0 on IEEE754 compliant implementations!
+      // This would change the result of complex calculations:
+      // 
+      // i.e. sqrt(-1 + (-0)i) !=  sqrt(-1 + 0i)
+      //                   -i  !=  i  
+      cmplx_type v((re==0) ? 0 : -re, (im==0) ? 0 : -im);
+      *ret = v; 
+    }
+    else if (a_pArg[0]->GetType()=='m')
+    {
+      Value v(a_pArg[0]->GetRows(), 0);
+      for (int i=0; i<a_pArg[0]->GetRows(); ++i)
+      {
+        v.At(i) = a_pArg[0]->At(i).GetComplex() * -1.0;
+      }
+      *ret = v;
+    }
+    else
+    {
+        ErrorContext err;
+        err.Errc = ecINVALID_TYPE;
+        err.Type1 = a_pArg[0]->GetType();
+        err.Type2 = 's';
+        throw ParserError(err);
+    }
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* OprtSignCmplx::GetDesc() const 
+  { 
+    return _T("unit multiplicator 1e-9"); 
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* OprtSignCmplx::Clone() const 
+  { 
+    return new OprtSignCmplx(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtAddCmplx
+//
+//-----------------------------------------------------------
+
+  OprtAddCmplx::OprtAddCmplx() 
+    :IOprtBin(_T("+"), (int)prADD_SUB, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtAddCmplx::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    const IValue *arg1 = a_pArg[0].Get();
+    const IValue *arg2 = a_pArg[1].Get();
+
+    if (arg1->IsNonComplexScalar() && arg2->IsNonComplexScalar())
+    {
+      *ret = arg1->GetFloat() + arg2->GetFloat(); 
+    }
+    else if (arg1->GetType()=='m' && arg2->GetType()=='m')
+    {
+      // Matrix + Matrix
+      *ret = arg1->GetArray() + arg2->GetArray();
+    }
+    else
+    {
+      if (!arg1->IsScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), arg1->GetType(), 'c', 1)); 
+
+      if (!arg2->IsScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), arg2->GetType(), 'c', 2)); 
+      
+      *ret = cmplx_type(arg1->GetFloat() + arg2->GetFloat(),
+                        arg1->GetImag()  + arg2->GetImag()); 
+    }
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtAddCmplx::GetDesc() const 
+  { 
+    return _T("addition"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtAddCmplx::Clone() const
+  { 
+    return new OprtAddCmplx(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtSubCmplx
+//
+//-----------------------------------------------------------
+
+  OprtSubCmplx::OprtSubCmplx() 
+    :IOprtBin(_T("-"), (int)prADD_SUB, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtSubCmplx::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+    
+    const IValue *arg1 = a_pArg[0].Get();
+    const IValue *arg2 = a_pArg[1].Get();
+    if ( a_pArg[0]->IsNonComplexScalar() && a_pArg[1]->IsNonComplexScalar())
+    {
+      *ret = arg1->GetFloat() - arg2->GetFloat(); 
+    }
+    else if (a_pArg[0]->GetType()=='m' && a_pArg[1]->GetType()=='m')
+    {
+      // Matrix + Matrix
+      *ret = arg1->GetArray() - arg2->GetArray();
+    }
+    else
+    {
+      if (!a_pArg[0]->IsScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), a_pArg[0]->GetType(), 'c', 1)); 
+
+      if (!a_pArg[1]->IsScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), a_pArg[1]->GetType(), 'c', 2)); 
+      
+      *ret = cmplx_type(a_pArg[0]->GetFloat() - a_pArg[1]->GetFloat(),
+                        a_pArg[0]->GetImag() - a_pArg[1]->GetImag()); 
+    }
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtSubCmplx::GetDesc() const 
+  { 
+    return _T("subtraction"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtSubCmplx::Clone() const
+  { 
+    return new OprtSubCmplx(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtMulCmplx
+//
+//-----------------------------------------------------------
+    
+  OprtMulCmplx::OprtMulCmplx() 
+    :IOprtBin(_T("*"), (int)prMUL_DIV, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtMulCmplx::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+    IValue *arg1 = a_pArg[0].Get();
+    IValue *arg2 = a_pArg[1].Get();
+   *ret = (*arg1) * (*arg2);
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtMulCmplx::GetDesc() const 
+  { 
+    return _T("foo*bar - multiplication"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtMulCmplx::Clone() const
+  { 
+    return new OprtMulCmplx(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtDivCmplx
+//
+//-----------------------------------------------------------
+
+
+  OprtDivCmplx::OprtDivCmplx() 
+    :IOprtBin(_T("/"), (int)prMUL_DIV, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  /** \brief Implements the Division operator. 
+      \throw ParserError in case one of the arguments if 
+             nonnumeric or an array.
+  
+  */
+  void OprtDivCmplx::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if ( a_pArg[0]->IsNonComplexScalar() && a_pArg[1]->IsNonComplexScalar())
+    {
+      *ret = a_pArg[0]->GetFloat() / a_pArg[1]->GetFloat(); 
+    }
+    else
+    {
+      // multiplication of two imaginary numbers      
+      float_type a = a_pArg[0]->GetFloat(),
+                 b = a_pArg[0]->GetImag(),
+                 c = a_pArg[1]->GetFloat(),
+                 d = a_pArg[1]->GetImag(),
+                 n = c*c + d*d;
+      *ret = cmplx_type((a*c+b*d)/n, (b*c-a*d)/n); 
+    }
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtDivCmplx::GetDesc() const 
+  { 
+    return _T("division"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtDivCmplx::Clone() const
+  { 
+    return new OprtDivCmplx(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtPowCmplx
+//
+//-----------------------------------------------------------
+
+  OprtPowCmplx::OprtPowCmplx() 
+    :IOprtBin(_T("^"), (int)prPOW, oaRIGHT) 
+  {}
+                                                                        
+  //-----------------------------------------------------------
+  void OprtPowCmplx::Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc)
+  {
+    assert(argc==2);
+    *ret = exp(arg[1]->GetComplex() * log(arg[0]->GetComplex()));
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtPowCmplx::GetDesc() const 
+  { 
+    return _T("raise x to the power of y"); 
+  }
+
+  //-----------------------------------------------------------
+  IToken* OprtPowCmplx::Clone() const            
+  { 
+    return new OprtPowCmplx(*this); 
+  }
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtCmplx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtCmplx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,124 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MP_OPRT_CMPLX_H
+#define MP_OPRT_CMPLX_H
+
+/** \file 
+    \brief Definitions of classes used as callbacks for standard binary operators. 
+*/
+
+/** \defgroup binop Binary operator callbacks
+
+  This group lists the objects representing the binary operators of muParserX.
+*/
+
+#include <cmath>
+#include "mpIOprt.h"
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for the negative sign operator.
+      \ingroup infix
+  */
+  class OprtSignCmplx : public IOprtInfix
+  {
+  public:
+    OprtSignCmplx();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class OprtSignCmplx
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser callback for implementing an addition of two complex values.
+      \ingroup binop
+  */
+  class OprtAddCmplx : public IOprtBin    
+  {
+  public:
+    OprtAddCmplx();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser callback for implementing the subtraction of two complex values.
+      \ingroup binop
+  */
+  class OprtSubCmplx : public IOprtBin    
+  {
+  public:
+    OprtSubCmplx();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for implementing the multiplications of complex values.
+      \ingroup binop
+  */
+  class OprtMulCmplx : public IOprtBin    
+  {
+  public:
+    OprtMulCmplx();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for implementing the division of complex values.
+      \ingroup binop
+  */
+  class OprtDivCmplx : public IOprtBin    
+  {
+  public:
+    OprtDivCmplx();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Raise x to the power of y.
+      \ingroup binop
+  */
+  class OprtPowCmplx : public IOprtBin
+  {
+  public:
+    OprtPowCmplx();
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; 
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtIndex.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtIndex.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,92 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpOprtIndex.h"
+#include "mpVariable.h"
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------------------------------
+  //
+  //  class  OprtIndex
+  //
+  //-----------------------------------------------------------------------------------------------
+
+  OprtIndex::OprtIndex(IPackage* pPackage)
+    :IOprtIndex(-1)
+  {}
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Index operator implementation
+      \param ret A reference to the return value
+      \param a_pArg Pointer to an array with the indices as ptr_val_type
+      \param a_iArgc Number of indices (=dimension) actully used in the expression found. This must 
+             be 1 or 2 since three dimensional data structures are not supported by muParserX.
+  */
+  void OprtIndex::At(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    try
+    {
+      // The index is -1, thats the actual variable reference
+      if (a_iArgc!=a_pArg[-1]->GetDim())
+      {
+        throw ParserError(ErrorContext(ecINDEX_DIMENSION, -1, GetIdent()));
+      }
+
+      switch(a_iArgc)
+      {
+      case 1:
+          ret.Reset(new Variable( &(ret->At(*a_pArg[0], Value(0))) ) );
+          break;
+
+      case 2:
+          ret.Reset(new Variable( &(ret->At(*a_pArg[0], *a_pArg[1])) ) );
+          break;
+
+      default:
+          throw ParserError(ErrorContext(ecINDEX_DIMENSION, -1, GetIdent()));
+      }
+    }
+    catch(ParserError &exc)
+    {
+      exc.GetContext().Pos = GetExprPos();
+      throw exc;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  const char_type* OprtIndex::GetDesc() const
+  {
+    return _T("[,] - The index operator.");
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IToken* OprtIndex::Clone() const
+  {
+    return new OprtIndex(*this); 
+  }
+
+
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtIndex.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtIndex.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,59 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MP_OPRT_INDEX_H
+#define MP_OPRT_INDEX_H
+
+/** \file 
+    \brief Definitions of index operator classes. 
+*/
+
+/** \defgroup binop Binary operator callbacks
+
+  This group lists the objects representing the binary operators of muParserX.
+*/
+
+#include <cmath>
+#include "mpIOprt.h"
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Default implementation of a multidimensional index operator.
+  */
+  class OprtIndex : public IOprtIndex
+  {
+  public:
+    OprtIndex(IPackage* pPackage=NULL);
+    virtual void At(ptr_val_type& ret, const ptr_val_type *arg, int argc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; 
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtMatrix.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtMatrix.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,111 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpOprtMatrix.h"
+
+
+MUP_NAMESPACE_START
+
+//-------------------------------------------------------------------------------------------------
+//
+//  class  OprtTranspose
+//
+//-------------------------------------------------------------------------------------------------
+
+  OprtTranspose::OprtTranspose(IPackage* pPackage)
+    :IOprtPostfix(_T("'"))
+  {}
+
+  //-------------------------------------------------------------------------------------------------
+  void OprtTranspose::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    if (a_pArg[0]->IsMatrix())
+    {
+      matrix_type matrix = a_pArg[0]->GetArray();
+      matrix.Transpose();
+     *ret = matrix;
+    }
+    else
+      *ret = *a_pArg[0];
+  }
+
+  //-------------------------------------------------------------------------------------------------
+  const char_type* OprtTranspose::GetDesc() const
+  {
+    return _T("foo' - An operator for transposing a matrix.");
+  }
+
+  //-------------------------------------------------------------------------------------------------
+  IToken* OprtTranspose::Clone() const
+  {
+    return new OprtTranspose(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtAdd
+//
+//-----------------------------------------------------------
+
+  OprtColon::OprtColon() 
+    :IOprtBin(_T("~"), (int)prCOLON, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtColon::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    const IValue *argMin = a_pArg[0].Get();
+    const IValue *argMax = a_pArg[1].Get();
+  
+    if (!argMin->IsNonComplexScalar())
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), argMin->GetType(), 'i', 1)); 
+
+    if (!argMax->IsNonComplexScalar())
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), argMax->GetType(), 'i', 1)); 
+
+    if (*argMax < *argMin)
+      throw ParserError(_T("Colon operator: Maximum value smaller than Minimum!")); 
+
+    int n = (argMax->GetFloat() - argMin->GetFloat()) + 1;
+    matrix_type arr(n);
+    for (int i=0; i<n; ++i)
+      arr.At(i) = argMin->GetFloat() + i;
+
+    *ret = arr; 
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtColon::GetDesc() const 
+  { 
+    return _T(": - Colon operator"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtColon::Clone() const
+  { 
+    return new OprtColon(*this); 
+  }
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtMatrix.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtMatrix.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,62 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MP_OPRT_MATRIX_H
+#define MP_OPRT_MATRIX_H
+
+/** \file 
+    \brief Definitions of classes used as callbacks for matrix operators. 
+*/
+
+
+#include <cmath>
+#include "mpIOprt.h"
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------------------------------
+  class OprtTranspose : public IOprtPostfix
+  {
+  public:
+    OprtTranspose(IPackage* pPackage=NULL);
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; 
+
+  //-----------------------------------------------------------------------------------------------
+  class OprtColon : public IOprtBin
+  {
+  public:
+    OprtColon();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; 
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtNonCmplx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtNonCmplx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,363 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpOprtNonCmplx.h"
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  //
+  //  Sign operator
+  //
+  //------------------------------------------------------------------------------
+
+  OprtSign::OprtSign()
+    :IOprtInfix( _T("-"))
+  {}
+
+  //------------------------------------------------------------------------------
+  void OprtSign::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)  
+  { 
+    MUP_ASSERT(a_iArgc==1);
+
+    if (a_pArg[0]->IsScalar())
+    {
+      *ret = -a_pArg[0]->GetFloat();
+    }
+    else if (a_pArg[0]->GetType()=='m')
+    {
+      Value v(a_pArg[0]->GetRows(), 0);
+      for (int i=0; i<a_pArg[0]->GetRows(); ++i)
+      {
+        v.At(i) = -a_pArg[0]->At(i).GetFloat();
+      }
+      *ret = v;
+    }
+    else
+    {
+        ErrorContext err;
+        err.Errc = ecINVALID_TYPE;
+        err.Type1 = a_pArg[0]->GetType();
+        err.Type2 = 's';
+        throw ParserError(err);
+    }
+  }
+
+  //------------------------------------------------------------------------------
+  const char_type* OprtSign::GetDesc() const 
+  { 
+    return _T("unit multiplicator 1e-9"); 
+  }
+
+  //------------------------------------------------------------------------------
+  IToken* OprtSign::Clone() const 
+  { 
+    return new OprtSign(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtAdd
+//
+//-----------------------------------------------------------
+
+  OprtAdd::OprtAdd() 
+    :IOprtBin(_T("+"), (int)prADD_SUB, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtAdd::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    const IValue *arg1 = a_pArg[0].Get();
+    const IValue *arg2 = a_pArg[1].Get();
+    if (arg1->GetType()=='m' && arg2->GetType()=='m')
+    {
+      // Vector + Vector
+      const matrix_type &a1 = arg1->GetArray(),
+                       &a2 = arg2->GetArray();
+      if (a1.GetRows()!=a2.GetRows())
+        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));
+      
+      matrix_type rv(a1.GetRows());
+      for (int i=0; i<a1.GetRows(); ++i)
+      {
+        if (!a1.At(i).IsNonComplexScalar())
+          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a1.At(i).GetType(), 'f', 1)); 
+
+        if (!a2.At(i).IsNonComplexScalar())
+          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a2.At(i).GetType(), 'f', 1)); 
+
+        rv.At(i) = a1.At(i).GetFloat() + a2.At(i).GetFloat();
+      }
+
+      *ret = rv; 
+    }
+    else
+    {
+      if (!arg1->IsNonComplexScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1->GetType(), 'f', 1)); 
+
+      if (!arg2->IsNonComplexScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2->GetType(), 'f', 2)); 
+      
+      *ret = arg1->GetFloat() + arg2->GetFloat(); 
+    }
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtAdd::GetDesc() const 
+  { 
+    return _T("x+y - Addition for noncomplex values"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtAdd::Clone() const
+  { 
+    return new OprtAdd(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtSub
+//
+//-----------------------------------------------------------
+
+  OprtSub::OprtSub() 
+    :IOprtBin(_T("-"), (int)prADD_SUB, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtSub::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if (a_pArg[0]->GetType()=='m' && a_pArg[1]->GetType()=='m')
+    {
+      const matrix_type &a1 = a_pArg[0]->GetArray(),
+                       &a2 = a_pArg[1]->GetArray();
+      if (a1.GetRows()!=a2.GetRows())
+        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));
+      
+      matrix_type rv(a1.GetRows());
+      for (int i=0; i<a1.GetRows(); ++i)
+      {
+        if (!a1.At(i).IsNonComplexScalar())
+          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a1.At(i).GetType(), 'f', 1)); 
+
+        if (!a2.At(i).IsNonComplexScalar())
+          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a2.At(i).GetType(), 'f', 1)); 
+
+        rv.At(i) = cmplx_type(a1.At(i).GetFloat() - a2.At(i).GetFloat(),
+                              a1.At(i).GetImag()  - a2.At(i).GetImag());
+      }
+
+      *ret = rv;
+    }
+    else
+    {
+      if (!a_pArg[0]->IsNonComplexScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'f', 1)); 
+
+      if (!a_pArg[1]->IsNonComplexScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'f', 2)); 
+      
+      *ret = a_pArg[0]->GetFloat() - a_pArg[1]->GetFloat(); 
+    }
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtSub::GetDesc() const 
+  { 
+    return _T("subtraction"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtSub::Clone() const
+  { 
+    return new OprtSub(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtMul
+//
+//-----------------------------------------------------------
+    
+  OprtMul::OprtMul() 
+    :IOprtBin(_T("*"), (int)prMUL_DIV, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  void OprtMul::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+    IValue *arg1 = a_pArg[0].Get();
+    IValue *arg2 = a_pArg[1].Get();
+    if (arg1->GetType()=='m' && arg2->GetType()=='m')
+    {
+      // Scalar multiplication
+      matrix_type a1 = arg1->GetArray();
+      matrix_type a2 = arg2->GetArray();
+
+      if (a1.GetRows()!=a2.GetRows())
+        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));
+
+      float_type val(0);
+      for (int i=0; i<a1.GetRows(); ++i)
+        val += a1.At(i).GetFloat()*a2.At(i).GetFloat();
+
+      *ret = val;
+    }
+    else if (arg1->GetType()=='m' && arg2->IsNonComplexScalar())
+    {
+      // Skalar * Vector
+      matrix_type out(a_pArg[0]->GetArray());
+      for (int i=0; i<out.GetRows(); ++i)
+        out.At(i) = out.At(i).GetFloat() * arg2->GetFloat();
+
+      *ret = out; 
+    }
+    else if (arg2->GetType()=='m' && arg1->IsNonComplexScalar())
+    {
+      // Vector * Skalar
+      matrix_type out(arg2->GetArray());
+      for (int i=0; i<out.GetRows(); ++i)
+        out.At(i) = out.At(i).GetFloat() * arg1->GetFloat();
+
+      *ret = out; 
+    }
+    else
+    {
+      if (!arg1->IsNonComplexScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1->GetType(), 'f', 1)); 
+
+      if (!arg2->IsNonComplexScalar())
+        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2->GetType(), 'f', 2)); 
+
+      *ret = arg1->GetFloat() * arg2->GetFloat(); 
+    }
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtMul::GetDesc() const 
+  { 
+    return _T("multiplication"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtMul::Clone() const
+  { 
+    return new OprtMul(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtDiv
+//
+//-----------------------------------------------------------
+
+
+  OprtDiv::OprtDiv() 
+    :IOprtBin(_T("/"), (int)prMUL_DIV, oaLEFT) 
+  {}
+
+  //-----------------------------------------------------------
+  /** \brief Implements the Division operator. 
+      \throw ParserError in case one of the arguments if 
+             nonnumeric or an array.
+  
+  */
+  void OprtDiv::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
+  { 
+    assert(num==2);
+
+    if (!a_pArg[0]->IsNonComplexScalar())
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'f', 1)); 
+
+    if (!a_pArg[1]->IsNonComplexScalar())
+      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'f', 2)); 
+    
+    *ret = a_pArg[0]->GetFloat() / a_pArg[1]->GetFloat();
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtDiv::GetDesc() const 
+  { 
+    return _T("division"); 
+  }
+  
+  //-----------------------------------------------------------
+  IToken* OprtDiv::Clone() const
+  { 
+    return new OprtDiv(*this); 
+  }
+
+//-----------------------------------------------------------
+//
+// class OprtPow
+//
+//-----------------------------------------------------------
+
+  OprtPow::OprtPow() 
+    :IOprtBin(_T("^"), (int)prPOW, oaRIGHT) 
+  {}
+                                                                        
+  //-----------------------------------------------------------
+  void OprtPow::Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc)
+  {
+    assert(argc==2);
+    float_type a = arg[0]->GetFloat();
+    float_type b = arg[1]->GetFloat();
+    
+    int ib = (int)b;
+    if (b-ib==0)
+    {
+      switch (ib)
+      {
+      case 1: *ret = a; return;
+      case 2: *ret = a*a; return;
+      case 3: *ret = a*a*a; return;
+      case 4: *ret = a*a*a*a; return;
+      case 5: *ret = a*a*a*a*a; return;
+      default: *ret = pow(a, ib); return;
+      }
+    }
+    else
+      *ret = pow(a, b);
+  }
+
+  //-----------------------------------------------------------
+  const char_type* OprtPow::GetDesc() const 
+  { 
+    return _T("x^y - Raises x to the power of y"); 
+  }
+
+  //-----------------------------------------------------------
+  IToken* OprtPow::Clone() const            
+  { 
+    return new OprtPow(*this); 
+  }
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpOprtNonCmplx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpOprtNonCmplx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,126 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MP_OPRT_NON_CMPLX_H
+#define MP_OPRT_NON_CMPLX_H
+
+/** \file 
+    \brief Definitions of classes used as callbacks for standard binary operators. 
+*/
+
+/** \defgroup binop Binary operator callbacks
+
+  This group lists the objects representing the binary operators of muParserX.
+*/
+
+#include <cmath>
+#include "mpIOprt.h"
+#include "mpValue.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for the negative sign operator for noncomplex values.
+      \ingroup infix
+  */
+  class OprtSign : public IOprtInfix
+  {
+  public:
+    OprtSign();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; // class OprtSign
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser callback for implementing an addition of two noncomplex values.
+      \ingroup binop
+  */
+  class OprtAdd : public IOprtBin    
+  {
+  public:
+    OprtAdd();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser callback for implementing the subtraction of two noncomplex values.
+      \ingroup binop
+  */
+  class OprtSub : public IOprtBin    
+  {
+  public:
+    OprtSub();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for implementing the multiplications of noncomplex values.
+      \ingroup binop
+  */
+  class OprtMul : public IOprtBin    
+  {
+  public:
+    OprtMul();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Callback object for implementing the division of noncomplex values.
+      \ingroup binop
+  */
+  class OprtDiv : public IOprtBin    
+  {
+  public:
+    OprtDiv();
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Raise x to the power of y.
+      \ingroup binop
+  */
+  class OprtPow : public IOprtBin
+  {
+  public:
+    
+    OprtPow();
+                                                                        
+    virtual void Eval(ptr_val_type& ret, const ptr_val_type *arg, int argc);
+    virtual const char_type* GetDesc() const;
+    virtual IToken* Clone() const;
+  }; 
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageCmplx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageCmplx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,71 @@
+#include "mpPackageCmplx.h"
+
+#include "mpParserBase.h"
+#include "mpFuncCmplx.h"
+#include "mpOprtCmplx.h"
+#include "mpOprtBinCommon.h"
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+std::auto_ptr<PackageCmplx> PackageCmplx::s_pInstance;
+
+//------------------------------------------------------------------------------
+IPackage* PackageCmplx::Instance()
+{
+  if (s_pInstance.get()==NULL)
+  {
+    s_pInstance.reset(new PackageCmplx);
+  }
+
+  return s_pInstance.get();
+}
+
+//------------------------------------------------------------------------------
+void PackageCmplx::AddToParser(ParserXBase *pParser)
+{
+  // Constants
+  pParser->DefineConst( _T("i"), cmplx_type(0.0, 1.0) );
+
+  // Complex valued functions
+  pParser->DefineFun(new FunCmplxReal());
+  pParser->DefineFun(new FunCmplxImag());
+  pParser->DefineFun(new FunCmplxConj());
+  pParser->DefineFun(new FunCmplxArg());
+  pParser->DefineFun(new FunCmplxNorm());
+  pParser->DefineFun(new FunCmplxSin());
+  pParser->DefineFun(new FunCmplxCos());
+  pParser->DefineFun(new FunCmplxTan());
+  pParser->DefineFun(new FunCmplxSinH());
+  pParser->DefineFun(new FunCmplxCosH());
+  pParser->DefineFun(new FunCmplxTanH());
+  pParser->DefineFun(new FunCmplxSqrt());
+  pParser->DefineFun(new FunCmplxExp());
+  pParser->DefineFun(new FunCmplxLn());
+  pParser->DefineFun(new FunCmplxLog());
+  pParser->DefineFun(new FunCmplxLog2());
+  pParser->DefineFun(new FunCmplxLog10());
+  pParser->DefineFun(new FunCmplxAbs());
+
+  // Complex valued operators
+  pParser->DefineOprt(new OprtAddCmplx());
+  pParser->DefineOprt(new OprtSubCmplx());
+  pParser->DefineOprt(new OprtMulCmplx());
+  pParser->DefineOprt(new OprtDivCmplx());
+  pParser->DefineOprt(new OprtPowCmplx());
+  pParser->DefineInfixOprt(new OprtSignCmplx());
+}
+
+//------------------------------------------------------------------------------
+string_type PackageCmplx::GetDesc() const
+{
+  return _T("");
+}
+
+//------------------------------------------------------------------------------
+string_type PackageCmplx::GetPrefix() const
+{
+  return _T("");
+}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageCmplx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageCmplx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,31 @@
+#ifndef MU_PACKAGE_CMPLX_H
+#define MU_PACKAGE_CMPLX_H
+
+#include <memory>
+#include "mpIPackage.h"
+#include "mpIOprt.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+/** \brief Package for installing complex functions and operators. */
+class PackageCmplx: public IPackage
+{
+friend class std::auto_ptr<PackageCmplx>;
+
+public:
+  
+  static IPackage* Instance();
+  virtual void AddToParser(ParserXBase *pParser);
+  virtual string_type GetDesc() const;
+  virtual string_type GetPrefix() const;
+
+private:
+
+  static std::auto_ptr<PackageCmplx> s_pInstance;
+};
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageCommon.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageCommon.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,102 @@
+#include "mpPackageCommon.h"
+
+#include "mpParserBase.h"
+#include "mpFuncNonCmplx.h"
+#include "mpFuncCommon.h"
+#include "mpOprtBinCommon.h"
+#include "mpOprtBinAssign.h"
+#include "mpValReader.h"
+
+/** \brief Pi (what else?). */
+#define MUP_CONST_PI  3.141592653589793238462643
+
+/** \brief The eulerian number. */
+#define MUP_CONST_E   2.718281828459045235360287
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+std::auto_ptr<PackageCommon> PackageCommon::s_pInstance;
+
+//------------------------------------------------------------------------------
+IPackage* PackageCommon::Instance()
+{
+  if (s_pInstance.get()==NULL)
+  {
+    s_pInstance.reset(new PackageCommon);
+  }
+
+  return s_pInstance.get();
+}
+
+//------------------------------------------------------------------------------
+void PackageCommon::AddToParser(ParserXBase *pParser)
+{
+  // Readers that need fancy decorations on their values must
+  // be added first (i.e. hex -> "0x...") Otherwise the
+  // zero in 0x will be read as a value of zero!
+  pParser->AddValueReader(new HexValReader());
+  pParser->AddValueReader(new DblValReader());
+  pParser->AddValueReader(new BoolValReader());
+  pParser->AddValueReader(new BinValReader());
+
+  // Constants
+  pParser->DefineConst( _T("pi"), (float_type)MUP_CONST_PI );
+  pParser->DefineConst( _T("e"),  (float_type)MUP_CONST_E );
+
+  // Vector
+  pParser->DefineFun(new FunSizeOf());
+
+  // Generic functions
+  pParser->DefineFun(new FunMax());
+  pParser->DefineFun(new FunMin());
+  pParser->DefineFun(new FunSum());
+
+  // misc
+  pParser->DefineFun(new FunParserID());
+
+  // integer package
+  pParser->DefineOprt(new OprtLAnd);
+  pParser->DefineOprt(new OprtLOr);
+  pParser->DefineOprt(new OprtAnd);
+  pParser->DefineOprt(new OprtOr);
+  pParser->DefineOprt(new OprtShr);
+  pParser->DefineOprt(new OprtShl);
+
+  // booloean package
+  pParser->DefineOprt(new OprtLE);
+  pParser->DefineOprt(new OprtGE);
+  pParser->DefineOprt(new OprtLT);
+  pParser->DefineOprt(new OprtGT);
+  pParser->DefineOprt(new OprtEQ);
+  pParser->DefineOprt(new OprtNEQ);
+  pParser->DefineOprt(new OprtBAnd);
+  pParser->DefineOprt(new OprtBOr);
+  pParser->DefineOprt(new OprtBXor);
+
+  // assignement operators
+  pParser->DefineOprt(new OprtAssign);
+  pParser->DefineOprt(new OprtAssignAdd);
+  pParser->DefineOprt(new OprtAssignSub);
+  pParser->DefineOprt(new OprtAssignMul);
+  pParser->DefineOprt(new OprtAssignDiv);
+
+  // infix operators
+  pParser->DefineInfixOprt(new OprtCastToFloat);
+  pParser->DefineInfixOprt(new OprtCastToInt);
+}
+
+//------------------------------------------------------------------------------
+string_type PackageCommon::GetDesc() const
+{
+  return _T("");
+}
+
+//------------------------------------------------------------------------------
+string_type PackageCommon::GetPrefix() const
+{
+  return _T("");
+}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageCommon.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageCommon.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,33 @@
+#ifndef MU_PACKAGE_COMMON_H
+#define MU_PACKAGE_COMMON_H
+
+#include <memory>
+#include "mpIPackage.h"
+#include "mpIOprt.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+/** \brief Package for installing operators and functions which
+           are always present. 
+*/
+class PackageCommon: public IPackage
+{
+friend class std::auto_ptr<PackageCommon>;
+
+public:
+  
+  static IPackage* Instance();
+  virtual void AddToParser(ParserXBase *pParser);
+  virtual string_type GetDesc() const;
+  virtual string_type GetPrefix() const;
+
+private:
+
+  static std::auto_ptr<PackageCommon> s_pInstance;
+};
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageMatrix.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageMatrix.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,48 @@
+#include "mpPackageMatrix.h"
+
+#include "mpParserBase.h"
+#include "mpFuncMatrix.h"
+#include "mpOprtMatrix.h"
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+std::auto_ptr<PackageMatrix> PackageMatrix::s_pInstance;
+
+//------------------------------------------------------------------------------
+IPackage* PackageMatrix::Instance()
+{
+  if (s_pInstance.get()==NULL)
+  {
+    s_pInstance.reset(new PackageMatrix);
+  }
+
+  return s_pInstance.get();
+}
+
+//------------------------------------------------------------------------------
+void PackageMatrix::AddToParser(ParserXBase *pParser)
+{
+  // Matrix functions
+  pParser->DefineFun(new FunMatrixOnes());
+  
+  // Matrix Operators
+  pParser->DefinePostfixOprt(new OprtTranspose(this));
+
+  // Colon operator
+  pParser->DefineOprt(new OprtColon());
+}
+
+//------------------------------------------------------------------------------
+string_type PackageMatrix::GetDesc() const
+{
+  return _T("Operators and functions for matrix operations");
+}
+
+//------------------------------------------------------------------------------
+string_type PackageMatrix::GetPrefix() const
+{
+  return _T("");
+}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageMatrix.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageMatrix.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,31 @@
+#ifndef MU_PACKAGE_MATRIX_H
+#define MU_PACKAGE_MATRIX_H
+
+#include <memory>
+#include "mpIPackage.h"
+#include "mpIOprt.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+/** \brief Package for installing complex functions and operators. */
+class PackageMatrix : public IPackage
+{
+friend class std::auto_ptr<PackageMatrix>;
+
+public:
+  
+  static IPackage* Instance();
+  virtual void AddToParser(ParserXBase *pParser);
+  virtual string_type GetDesc() const;
+  virtual string_type GetPrefix() const;
+
+private:
+
+  static std::auto_ptr<PackageMatrix> s_pInstance;
+};
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageNonCmplx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageNonCmplx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,69 @@
+#include "mpPackageNonCmplx.h"
+
+#include "mpParserBase.h"
+#include "mpFuncNonCmplx.h"
+#include "mpOprtNonCmplx.h"
+#include "mpOprtBinCommon.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+std::auto_ptr<PackageNonCmplx> PackageNonCmplx::s_pInstance;
+
+//------------------------------------------------------------------------------
+IPackage* PackageNonCmplx::Instance()
+{
+  if (s_pInstance.get()==NULL)
+  {
+    s_pInstance.reset(new PackageNonCmplx);
+  }
+
+  return s_pInstance.get();
+}
+
+//------------------------------------------------------------------------------
+void PackageNonCmplx::AddToParser(ParserXBase *pParser)
+{
+  pParser->DefineFun(new FunSin());
+  pParser->DefineFun(new FunCos());
+  pParser->DefineFun(new FunTan());
+  pParser->DefineFun(new FunSinH());
+  pParser->DefineFun(new FunCosH());
+  pParser->DefineFun(new FunTanH());
+  pParser->DefineFun(new FunASin());
+  pParser->DefineFun(new FunACos());
+  pParser->DefineFun(new FunATan());
+  pParser->DefineFun(new FunASinH());
+  pParser->DefineFun(new FunACosH());
+  pParser->DefineFun(new FunATanH());
+  pParser->DefineFun(new FunLog());
+  pParser->DefineFun(new FunLog10());
+  pParser->DefineFun(new FunLog2());
+  pParser->DefineFun(new FunLn());
+  pParser->DefineFun(new FunExp());
+  pParser->DefineFun(new FunSqrt());
+  pParser->DefineFun(new FunAbs());
+
+  // Operator callbacks
+  pParser->DefineInfixOprt(new OprtSign());
+  pParser->DefineOprt(new OprtAdd());
+  pParser->DefineOprt(new OprtSub());
+  pParser->DefineOprt(new OprtMul());
+  pParser->DefineOprt(new OprtDiv());
+  pParser->DefineOprt(new OprtPow);
+}
+
+//------------------------------------------------------------------------------
+string_type PackageNonCmplx::GetDesc() const
+{
+  return _T("");
+}
+
+//------------------------------------------------------------------------------
+string_type PackageNonCmplx::GetPrefix() const
+{
+  return _T("");
+}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageNonCmplx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageNonCmplx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,32 @@
+#ifndef MU_PACKAGE_NON_CMPLX_H
+#define MU_PACKAGE_NON_CMPLX_H
+
+#include <memory>
+#include "mpIPackage.h"
+#include "mpIOprt.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+/** \brief Package for installing complex functions and operators. */
+class PackageNonCmplx: public IPackage
+{
+friend class std::auto_ptr<PackageNonCmplx>;
+
+public:
+  
+  static IPackage* Instance();
+
+  virtual void AddToParser(ParserXBase *pParser);
+  virtual string_type GetDesc() const;
+  virtual string_type GetPrefix() const;
+
+private:
+
+  static std::auto_ptr<PackageNonCmplx> s_pInstance;
+};
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageStr.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageStr.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,50 @@
+#include "mpPackageStr.h"
+
+#include "mpParserBase.h"
+#include "mpFuncStr.h"
+#include "mpOprtBinCommon.h"
+#include "mpValReader.h"
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+std::auto_ptr<PackageStr> PackageStr::s_pInstance;
+
+//------------------------------------------------------------------------------
+IPackage* PackageStr::Instance()
+{
+  if (s_pInstance.get()==NULL)
+  {
+    s_pInstance.reset(new PackageStr);
+  }
+
+  return s_pInstance.get();
+}
+
+//------------------------------------------------------------------------------
+void PackageStr::AddToParser(ParserXBase *pParser)
+{
+  pParser->AddValueReader(new StrValReader());
+
+  // Functions
+  pParser->DefineFun(new FunStrLen());
+  pParser->DefineFun(new FunStrToDbl());
+  pParser->DefineFun(new FunStrToUpper());
+
+  // Operators
+  pParser->DefineOprt(new OprtStrAdd);
+}
+
+//------------------------------------------------------------------------------
+string_type PackageStr::GetDesc() const
+{
+  return _T("A package for string operations.");
+}
+
+//------------------------------------------------------------------------------
+string_type PackageStr::GetPrefix() const
+{
+  return _T("");
+}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageStr.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageStr.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,32 @@
+#ifndef MU_PACKAGE_STR_H
+#define MU_PACKAGE_STR_H
+
+#include <memory>
+
+#include "mpIPackage.h"
+#include "mpIOprt.h"
+
+
+MUP_NAMESPACE_START
+
+//------------------------------------------------------------------------------
+/** \brief Package for installing unit postfix operators into muParserX. */
+class PackageStr : public IPackage
+{
+friend class std::auto_ptr<PackageStr>;
+
+public:
+  
+  static IPackage* Instance();
+  virtual void AddToParser(ParserXBase *pParser);
+  virtual string_type GetDesc() const;
+  virtual string_type GetPrefix() const;
+
+private:
+
+  static std::auto_ptr<PackageStr> s_pInstance;
+};
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageUnit.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageUnit.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,89 @@
+#include "mpPackageUnit.h"
+
+#include "mpParserBase.h"
+
+
+MUP_NAMESPACE_START
+
+/** \brief This is a macro for defining scaling postfix operators.
+
+  These operators can be used for unit conversions.
+*/
+#define MUP_POSTFIX_IMLP(CLASS, IDENT, MUL, DESC)                  \
+  CLASS::CLASS(IPackage *pPackage)                                 \
+    :IOprtPostfix(_T(IDENT))                                       \
+  {}                                                               \
+                                                                   \
+  void CLASS::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int) \
+  {                                                                \
+    if (!a_pArg[0]->IsScalar())                                    \
+    {                                                              \
+      ErrorContext err(ecTYPE_CONFLICT,                            \
+                       GetExprPos(),                               \
+                       a_pArg[0]->ToString(),                      \
+                       a_pArg[0]->GetType(),                       \
+                       'c',                                        \
+                       1);                                         \
+      throw ParserError(err);                                      \
+    }                                                              \
+                                                                   \
+    *ret = a_pArg[0]->GetComplex() * MUL;                          \
+  }                                                                \
+                                                                   \
+  const char_type* CLASS::GetDesc() const                          \
+  {                                                                \
+    return _T(DESC);                                               \
+  }                                                                \
+                                                                   \
+  IToken* CLASS::Clone() const                                     \
+  {                                                                \
+    return new CLASS(*this);                                       \
+  }
+
+  MUP_POSTFIX_IMLP(OprtNano,   "{n}",   (float_type)1e-9,   "{n} - unit multiplicator 1e-9")
+  MUP_POSTFIX_IMLP(OprtMicro,  "{mu}",  (float_type)1e-6,   "{µ} - unit multiplicator 1e-6")
+  MUP_POSTFIX_IMLP(OprtMilli,  "{m}",   (float_type)1e-3,   "{m} - unit multiplicator 1e-3")
+  MUP_POSTFIX_IMLP(OprtKilo,   "{k}",   (float_type)1e3,    "{k} - unit multiplicator 1e3")
+  MUP_POSTFIX_IMLP(OprtMega,   "{M}",   (float_type)1e6,    "{M} - unit multiplicator 1e6")
+  MUP_POSTFIX_IMLP(OprtGiga,   "{G}",   (float_type)1e9,    "{G} - unit multiplicator 1e9")
+
+#undef MUP_POSTFIX_IMLP
+
+//------------------------------------------------------------------------------
+std::auto_ptr<PackageUnit> PackageUnit::s_pInstance;
+
+//------------------------------------------------------------------------------
+IPackage* PackageUnit::Instance()
+{
+  if (s_pInstance.get()==NULL)
+  {
+    s_pInstance.reset(new PackageUnit);
+  }
+
+  return s_pInstance.get();
+}
+
+//------------------------------------------------------------------------------
+void PackageUnit::AddToParser(ParserXBase *pParser)
+{
+  pParser->DefinePostfixOprt(new OprtNano(this));
+  pParser->DefinePostfixOprt(new OprtMicro(this));
+  pParser->DefinePostfixOprt(new OprtMilli(this));
+  pParser->DefinePostfixOprt(new OprtKilo(this));
+  pParser->DefinePostfixOprt(new OprtMega(this));
+  pParser->DefinePostfixOprt(new OprtGiga(this));
+}
+
+//------------------------------------------------------------------------------
+string_type PackageUnit::GetDesc() const
+{
+  return _T("Postfix operators for basic unit conversions.");
+}
+
+//------------------------------------------------------------------------------
+string_type PackageUnit::GetPrefix() const
+{
+  return _T("");
+}
+
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpPackageUnit.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpPackageUnit.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,49 @@
+#ifndef MU_PACKAGE_UNIT_H
+#define MU_PACKAGE_UNIT_H
+
+#include <memory>
+#include "mpIPackage.h"
+#include "mpIOprt.h"
+
+MUP_NAMESPACE_START
+
+#define MUP_POSTFIX_DEF(CLASS)                                             \
+    class CLASS : public IOprtPostfix                                      \
+    {                                                                      \
+    public:                                                                \
+      CLASS(IPackage* pPackage=NULL);                                      \
+      virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc);  \
+      virtual const char_type* GetDesc() const;                            \
+      virtual IToken* Clone() const;                                       \
+    }; 
+
+MUP_POSTFIX_DEF(OprtNano)
+MUP_POSTFIX_DEF(OprtMicro)
+MUP_POSTFIX_DEF(OprtMilli)
+MUP_POSTFIX_DEF(OprtKilo)
+MUP_POSTFIX_DEF(OprtMega)
+MUP_POSTFIX_DEF(OprtGiga)
+
+#undef MUP_POSTFIX_DEF
+
+//------------------------------------------------------------------------------
+/** \brief Package for installing unit postfix operators into muParserX. */
+class PackageUnit : public IPackage
+{
+friend class std::auto_ptr<PackageUnit>;
+
+public:
+  
+  static IPackage* Instance();
+  virtual void AddToParser(ParserXBase *pParser);
+  virtual string_type GetDesc() const;
+  virtual string_type GetPrefix() const;
+
+private:
+
+  static std::auto_ptr<PackageUnit> s_pInstance;
+};
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpParser.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpParser.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,77 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpParser.h"
+
+//--- Standard includes ----------------------------------------------------
+#include <cmath>
+#include <algorithm>
+#include <numeric>
+
+//--- Parser framework -----------------------------------------------------
+#include "mpPackageUnit.h"
+#include "mpPackageStr.h"
+#include "mpPackageCmplx.h"
+#include "mpPackageNonCmplx.h"
+#include "mpPackageCommon.h"
+#include "mpPackageMatrix.h"
+
+using namespace std;
+
+
+/** \brief Namespace for mathematical applications. */
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief Default constructor. 
+
+    Call ParserXBase class constructor and initiate function, operator 
+    and constant initialization.
+  */
+  ParserX::ParserX(EPackages ePackages)
+    :ParserXBase()
+  {
+    DefineNameChars(_T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    DefineOprtChars(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_µ{}"));
+    DefineInfixOprtChars(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ()/+-*^?<>=#!$%&|~'_"));
+
+    if (ePackages & pckUNIT)
+      AddPackage(PackageUnit::Instance());
+
+    if (ePackages & pckSTRING)
+      AddPackage(PackageStr::Instance());
+
+    if (ePackages & pckCOMPLEX)
+      AddPackage(PackageCmplx::Instance());
+
+    if (ePackages & pckNON_COMPLEX)
+      AddPackage(PackageNonCmplx::Instance());
+
+    if (ePackages & pckCOMMON)
+      AddPackage(PackageCommon::Instance());
+
+    if (ePackages & pckMATRIX)
+      AddPackage(PackageMatrix::Instance());
+  }
+} // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpParser.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpParser.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,53 @@
+/** \file
+    \brief Definition of the parser class
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_PARSERX_H
+#define MUP_PARSERX_H
+
+//--- Parser framework -----------------------------------------------------
+#include "mpDefines.h"
+#include "mpParserBase.h"
+
+
+MUP_NAMESPACE_START
+
+/** \brief The parser implementation.
+      \sa ParserXBase
+
+    This is the class that implements the parser. It installs all functions
+    and operatore and defines the constants.
+  */
+  class ParserX : public ParserXBase
+  {
+  public:
+    ParserX(EPackages ePackages = pckALL_COMPLEX);
+  };
+} // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpParserBase.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpParserBase.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,1331 @@
+/** \file
+    \brief Implementation of the muParserX engine.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpParserBase.h"
+
+#include <cassert>
+#include <cmath>
+#include <memory>
+#include <vector>
+#include <sstream>
+
+#include "utGeneric.h"
+#include "mpDefines.h"
+#include "mpIfThenElse.h"
+#include "mpScriptTokens.h"
+
+using namespace std;
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  const char_type *g_sCmdCode[] = { _T("BRCK. OPEN     "),
+                                    _T("BRCK. CLOSE    "),
+                                    _T("IDX OPEN       "),
+                                    _T("IDX CLOSE      "),
+                                    _T("ARG_SEP        "),
+                                    _T("IF             "),
+                                    _T("ELSE           "),
+                                    _T("ENDIF          "),
+                                    _T("JMP            "),
+                                    _T("VAR            "),
+                                    _T("VAL            "),
+                                    _T("FUNC           "),
+                                    _T("OPRT_BIN       "),
+                                    _T("OPRT_IFX       "),
+                                    _T("OPRT_PFX       "),
+                                    _T("END            "),
+                                    _T("SCRIPT_GOTO    "),
+                                    _T("SCRIPT_LABEL   "),
+                                    _T("SCRIPT_FOR     "),
+                                    _T("SCRIPT_IF      "),
+                                    _T("SCRIPT_ELSE    "),
+                                    _T("SCRIPT_ELSEIF  "),
+                                    _T("SCRIPT_ENDIF   "),
+                                    _T("SCRIPT_NEWLINE "),
+                                    _T("SCRIPT_FUNCTION"),
+                                    _T("UNKNOWN        ") };
+
+  //------------------------------------------------------------------------------
+  bool ParserXBase::s_bDumpStack = false;
+  bool ParserXBase::s_bDumpRPN = false;
+
+  //------------------------------------------------------------------------------
+  /** \brief Identifiers for built in binary operators. 
+
+      When defining custom binary operators with AddOprt(...) make sure not to choose 
+      names conflicting with these definitions. 
+  */
+  const char_type* ParserXBase::c_DefaultOprt[] = { _T("("), 
+                                                    _T(")"), 
+                                                    _T("["), 
+                                                    _T("]"), 
+                                                    _T(","),
+                                                    _T("?"),
+                                                    _T(":"),
+                                                    0 };
+
+  //------------------------------------------------------------------------------
+  /** \brief Default constructor. */
+  ParserXBase::ParserXBase()
+    :m_pParserEngine(&ParserXBase::ParseFromString)
+    ,m_pTokenReader()
+    ,m_FunDef()
+    ,m_PostOprtDef()
+    ,m_InfixOprtDef()
+    ,m_OprtDef()
+    ,m_valConst()
+    ,m_valDynVarShadow()
+    ,m_VarDef()
+    ,m_sNameChars()
+    ,m_sOprtChars()
+    ,m_sInfixOprtChars()
+    ,m_nFinalResultIdx(0)
+    ,m_bIsQueryingExprVar(false)
+    ,m_bAutoCreateVar(false)
+    ,m_rpn()
+    ,m_vStackBuffer()
+  {
+    InitTokenReader();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor.
+      \param a_Parser Reference to the other parser object
+
+    Implemented by calling Assign(a_Parser)
+  */
+  ParserXBase::ParserXBase(const ParserXBase &a_Parser)
+    :m_pParserEngine(&ParserXBase::ParseFromString)
+    ,m_pTokenReader()
+    ,m_FunDef()
+    ,m_PostOprtDef()
+    ,m_InfixOprtDef()
+    ,m_OprtDef()
+    ,m_valConst()
+    ,m_valDynVarShadow()
+    ,m_VarDef()
+    ,m_sNameChars()
+    ,m_sOprtChars()
+    ,m_sInfixOprtChars()
+    ,m_nFinalResultIdx(0)
+    ,m_bAutoCreateVar()
+    ,m_rpn()
+    ,m_vStackBuffer()
+  {
+    m_pTokenReader.reset(new TokenReader(this));
+    Assign(a_Parser);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Destructor.
+      \throw nothrow
+  */
+  ParserXBase::~ParserXBase()
+  {
+    // It is important to release the stack buffer before
+    // releasing the value cache. Since it may contain
+    // Values referencing the cache.
+    m_vStackBuffer.clear();
+    m_cache.ReleaseAll();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignement operator. 
+      \param a_Parser Object to copy to this.
+      \return *this
+      \throw nothrow
+      
+    Implemented by calling Assign(a_Parser). Self assignement is suppressed.
+  */
+  ParserXBase& ParserXBase::operator=(const ParserXBase &a_Parser)
+  {
+    Assign(a_Parser);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy state of a parser object to this. 
+      \param a_Parser the source object.
+
+    Clears Variables and Functions of this parser.
+    Copies the states of all internal variables.
+    Resets parse function to string parse mode.
+  */
+  void ParserXBase::Assign(const ParserXBase &ref)
+  {
+    if (&ref==this)
+      return;
+
+    // Don't copy bytecode instead cause the parser to create new bytecode 
+    // by resetting the parse function.
+    ReInit();
+
+    m_pTokenReader.reset(ref.m_pTokenReader->Clone(this));
+
+    m_OprtDef         = ref.m_OprtDef;
+    m_FunDef          = ref.m_FunDef;
+    m_PostOprtDef     = ref.m_PostOprtDef;
+    m_InfixOprtDef    = ref.m_InfixOprtDef;
+    m_valConst        = ref.m_valConst;
+    m_valDynVarShadow = ref.m_valDynVarShadow;
+    m_VarDef          = ref.m_VarDef;             // Copy user defined variables
+    m_nFinalResultIdx = ref.m_nFinalResultIdx;
+
+    // Copy charsets
+    m_sNameChars = ref.m_sNameChars;
+    m_sOprtChars = ref.m_sOprtChars;
+    m_sInfixOprtChars = ref.m_sInfixOprtChars;
+
+    m_bAutoCreateVar = ref.m_bAutoCreateVar;
+
+    // Things that should not be copied:
+    // - m_vStackBuffer
+    // - m_cache
+    // - m_rpn
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Evaluate the expression.
+      \pre A formula must be set.
+      \pre Variables must have been set (if needed)
+      \sa SetExpr
+      \return The evaluation result
+      \throw ParseException if no Formula is set or in case of any other error related to the formula.
+
+      A note on const correctness: 
+      I consider it important that Calc is a const function.
+      Due to caching operations Calc changes only the state of internal variables with one exception
+      m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making
+      Calc non const GetExprVar is non const because it explicitely calls Eval() forcing this update. 
+  */
+  const IValue& ParserXBase::Eval() const
+  {
+    return (this->*m_pParserEngine)(); 
+  }
+  
+  //---------------------------------------------------------------------------
+  /** \brief Return the strings of all Operator identifiers. 
+      \return Returns a pointer to the c_DefaultOprt array of const char *.
+      \throw nothrow
+
+      GetOprt is a const function returning a pinter to an array of const char pointers.
+  */
+  const char_type** ParserXBase::GetOprtDef() const
+  {
+    return (const char_type **)(&c_DefaultOprt[0]);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the set of valid characters to be used in names of
+              functions, variables, constants.
+  */
+  void ParserXBase::DefineNameChars(const char_type *a_szCharset)
+  {
+    m_sNameChars = a_szCharset;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the set of valid characters to be used in names of
+             binary operators and postfix operators.
+      \param a_szCharset A string containing all characters that can be used 
+                         in operator identifiers.
+  */
+  void ParserXBase::DefineOprtChars(const char_type *a_szCharset)
+  {
+    m_sOprtChars = a_szCharset;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the set of valid characters to be used in names of
+             infix operators.
+      \param a_szCharset A string containing all characters that can be used 
+                         in infix operator identifiers.
+  */
+  void ParserXBase::DefineInfixOprtChars(const char_type *a_szCharset)
+  {
+    m_sInfixOprtChars = a_szCharset;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Virtual function that defines the characters allowed in name identifiers. 
+      \sa #ValidOprtChars, #ValidPrefixOprtChars
+  */ 
+  const char_type* ParserXBase::ValidNameChars() const
+  {
+    assert(m_sNameChars.size());
+    return m_sNameChars.c_str();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Virtual function that defines the characters allowed in operator definitions. 
+      \sa #ValidNameChars, #ValidPrefixOprtChars
+  */
+  const char_type* ParserXBase::ValidOprtChars() const
+  {
+    assert(m_sOprtChars.size());
+    return m_sOprtChars.c_str();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Virtual function that defines the characters allowed in infix operator definitions.
+      \sa #ValidNameChars, #ValidOprtChars
+  */
+  const char_type* ParserXBase::ValidInfixOprtChars() const
+  {
+    assert(m_sInfixOprtChars.size());
+    return m_sInfixOprtChars.c_str();
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize the token reader. 
+      \post m_pTokenReader.Get()!=0
+      \throw nothrow
+
+    Create new token reader object and submit pointers to function, operator,
+    constant and variable definitions.
+  */
+  void ParserXBase::InitTokenReader()
+  {
+    m_pTokenReader.reset(new TokenReader(this));
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Reset parser to string parsing mode and clear internal buffers.
+      \throw nothrow
+
+      Resets the token reader.
+  */
+  void ParserXBase::ReInit() const
+  {
+    m_pParserEngine = &ParserXBase::ParseFromString;
+    m_pTokenReader->ReInit();
+    m_rpn.Reset();
+    m_vStackBuffer.clear();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Adds a new package to the parser. 
+  
+    The parser becomes the owner of the package pointer and is responsible for 
+    its deletion.
+  */
+  void ParserXBase::AddPackage(IPackage *p)
+  {
+    p->AddToParser(this);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserXBase::RemovePackage(IPackage *p)
+  {
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a value reader object to muParserX. 
+      \param a_pReader Pointer to the value reader object.
+  */
+  void ParserXBase::AddValueReader(IValueReader *a_pReader)
+  {
+    m_pTokenReader->AddValueReader(a_pReader);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a given name contains invalid characters. 
+      \param a_strName The name to check
+      \param a_szCharSet The characterset
+      \throw ParserException if the name contains invalid charakters.
+  */
+  void ParserXBase::CheckName(const string_type &a_strName, 
+                              const string_type &a_szCharSet) const
+  {
+    if ( !a_strName.length() || 
+        (a_strName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
+        (a_strName[0]>=(char_type)'0' && a_strName[0]<=(char_type)'9'))
+    {
+      Error(ecINVALID_NAME);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Set the mathematical expression. 
+      \param a_sExpr String with the expression
+      \throw ParserException in case of syntax errors.
+
+      Triggers first time calculation thus the creation of the bytecode and 
+      scanning of used variables.
+  */
+  void ParserXBase::SetExpr(const string_type &a_sExpr)
+  {
+    m_pTokenReader->SetExpr(a_sExpr);
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined operator. 
+      \post Will reset the Parser to string parsing mode.
+      \param a_pOprt Pointer to a unary postfix operator object. The parser will
+                     become the new owner of this object hence will destroy it.
+  */
+  void ParserXBase::DefinePostfixOprt(IOprtPostfix *a_pOprt)
+  {
+    m_PostOprtDef[a_pOprt->GetIdent()] = ptr_tok_type(a_pOprt);
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined operator. 
+      \param a_pOprt Pointer to a unary postfix operator object. The parser will
+             become the new owner of this object hence will destroy it.
+  */
+  void ParserXBase::DefineInfixOprt(IOprtInfix *a_pOprt)
+  {
+    m_InfixOprtDef[a_pOprt->GetIdent()] = ptr_tok_type(a_pOprt);
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined variable. 
+      \param a_sName The variable name
+      \param a_Var The variable to be added to muParserX
+  */
+  void ParserXBase::DefineVar(const string_type &a_sName, const Variable &a_Var)
+  {
+    CheckName(a_sName, ValidNameChars());
+    m_VarDef[a_sName] = ptr_tok_type( a_Var.Clone() );
+    ReInit();
+  }
+  
+
+  //---------------------------------------------------------------------------
+  /** \brief Define a parser Constant. 
+      \param a_sName The name of the constant
+      \param a_Val Const reference to the constants value
+
+    Parser constants are handed over by const reference as opposed to variables 
+    which are handed over by reference. Consequently the parser can not change 
+    their value.
+  */
+  void ParserXBase::DefineConst(const string_type &a_sName, const Value &a_Val)
+  {
+    CheckName(a_sName, ValidNameChars());
+    m_valConst[a_sName] = ptr_tok_type( a_Val.Clone() );
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a callback object to the parser. 
+      \param a_pFunc Pointer to the intance of a parser callback object 
+                     representing the function.
+      \sa GetFunDef, functions
+
+    The parser takes ownership over the callback object.
+  */
+  void ParserXBase::DefineFun(ICallback *a_pFunc)
+  {
+    a_pFunc->SetParent(this);
+    m_FunDef[ a_pFunc->GetIdent() ] = ptr_tok_type(a_pFunc);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define a binara operator. 
+      \param a_pCallback Pointer to the callback object
+  */
+  void ParserXBase::DefineOprt(IOprtBin *a_pCallback)
+  {
+    a_pCallback->SetParent(this);
+    m_OprtDef.insert(make_pair(a_pCallback->GetIdent(), ptr_tok_type(a_pCallback)));
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing the used variables only. */
+  const var_maptype& ParserXBase::GetExprVar() const
+  {
+    utils::scoped_setter<bool> guard2(m_bIsQueryingExprVar, true);
+
+    // Create RPN,  but do not compute the result or switch to RPN
+    // parsing mode. The expression may contain yet to be defined variables.
+    CreateRPN();
+    return m_pTokenReader->GetUsedVar();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing the used variables only. */
+  const var_maptype& ParserXBase::GetVar() const
+  {
+    return m_VarDef;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing all parser constants. */
+  const val_maptype& ParserXBase::GetConst() const
+  {
+    return m_valConst;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return prototypes of all parser functions.
+      \return #m_FunDef
+      \sa FunProt, functions
+      \throw nothrow
+
+    The return type is a map of the public type #funmap_type containing the prototype
+    definitions for all numerical parser functions. String functions are not part of 
+    this map. The Prototype definition is encapsulated in objects of the class FunProt
+    one per parser function each associated with function names via a map construct.
+  */
+  const fun_maptype& ParserXBase::GetFunDef() const
+  {
+    return m_FunDef;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Retrieve the mathematical expression. */
+  const string_type& ParserXBase::GetExpr() const
+  {
+    return m_pTokenReader->GetExpr();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Get the version number of muParserX. 
+      \return A string containing the version number of muParserX.
+  */
+  string_type ParserXBase::GetVersion() 
+  {
+    return MUP_PARSER_VERSION;
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserXBase::ApplyRemainingOprt(Stack<ptr_tok_type> &stOpt,
+                                           Stack<ptr_val_type> &stVal) const
+
+
+  {
+    while (stOpt.size() &&
+           stOpt.top()->GetCode() != cmBO && 
+           stOpt.top()->GetCode() != cmIO && 
+           stOpt.top()->GetCode() != cmIF)
+    {
+      ptr_tok_type &op = stOpt.top();
+                      
+      switch(op->GetCode())
+      {
+        case  cmOPRT_BIN:
+              MUP_ASSERT(stOpt.top()->GetCode()==cmOPRT_BIN);
+              ApplyFunc(stOpt, stVal, 2);
+              break;
+
+        case  cmELSE:
+              ApplyIfElse(stOpt, stVal);
+              break;
+
+        default:
+              Error(ecINTERNAL_ERROR);
+      } // switch operator token type
+    } // While operator stack not empty
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Calls a parser function with its corresponding arguments. 
+      \param a_stOpt The operator stack
+      \param a_stVal The value stack
+      \param a_iArgCount The number of function arguments
+  */
+  void ParserXBase::ApplyFunc(Stack<ptr_tok_type> &a_stOpt,
+                              Stack<ptr_val_type> &a_stVal, 
+                              int a_iArgCount) const
+  { 
+    if (a_stOpt.empty())
+      return;
+
+    ptr_tok_type tok = a_stOpt.pop();
+    ICallback *pFun = tok->AsICallback();
+
+    int iArgCount = (pFun->GetArgc()>=0) ? pFun->GetArgc() : a_iArgCount;
+    int iOffset = a_stVal.size() - iArgCount;
+    MUP_ASSERT(iOffset>=0);
+
+    // The paramater stack may be empty since functions may not
+    // have a parameter. They do always have a return value though.
+    // If the param stack is empty create an entry for the function 
+    // return value.
+    if (iArgCount==0)
+      a_stVal.push(ptr_val_type(new Value()));
+
+    MUP_ASSERT((std::size_t)iOffset<a_stVal.size());
+    ptr_val_type *pArg = a_stVal.get_data() + iOffset;
+    
+    //if (pFun->GetArgc()==0)
+    //  a_stVal.push(ptr_val_type(new Value()));
+
+    //ptr_val_type *pArg = a_stVal.get_data() + iOffset;
+
+    try
+    {
+      // Make sure to pass on a volatile flag to the function result
+      bool bResultIsVolatile = false;
+      for (int i=0; i<iArgCount && bResultIsVolatile==false; ++i)
+      {
+        if (pArg[i]->IsFlagSet(IToken::flVOLATILE))
+          bResultIsVolatile = true;
+      }
+
+      // Instead of evaluating the function merely a dummy value of the same type as the function return value
+      // is created 
+      *pArg = ptr_val_type(new Value());
+      pFun->SetNumArgsPresent(iArgCount);
+      
+      if (bResultIsVolatile)
+        (*pArg)->AddFlags(IToken::flVOLATILE);
+
+      m_rpn.Add(tok);
+    }
+    catch(ParserError &e)
+    {
+      // This are type related errors caused by undefined
+      // variables. They must be ignored if the parser is
+      // just checking the presence of expression variables
+      if (!m_bIsQueryingExprVar)
+      {
+        ErrorContext &err = e.GetContext();
+        err.Pos   = m_pTokenReader->GetPos();
+        err.Expr  = m_pTokenReader->GetExpr();
+
+        if (err.Ident.empty())
+          err.Ident = pFun->GetIdent();
+
+        throw;
+      }
+    }
+
+    if (iArgCount>0)
+      a_stVal.pop(iArgCount-1); // remove the arguments
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserXBase::ApplyIfElse(Stack<ptr_tok_type> &a_stOpt,
+                                Stack<ptr_val_type> &a_stVal) const
+  { 
+    while (a_stOpt.size() && a_stOpt.top()->GetCode()==cmELSE)
+    {
+      MUP_ASSERT(a_stOpt.size()>0);
+      MUP_ASSERT(a_stVal.size()>=3);
+      MUP_ASSERT(a_stOpt.top()->GetCode()==cmELSE);
+
+      IToken &tokElse = *(a_stOpt.top().Get());
+
+      // it then else is a ternary operator Pop all three values from the value 
+      // stack and just return the right value
+      ptr_val_type vVal2 = a_stVal.pop();
+      ptr_val_type vVal1 = a_stVal.pop();
+      ptr_val_type bExpr = a_stVal.pop();
+
+      // Push a dummy value of the correct type
+      a_stVal.push(ptr_val_type(new Value(/*cType*/)));
+      
+      // Pass on volatile flags
+      if (vVal1->IsFlagSet(IToken::flVOLATILE) || vVal2->IsFlagSet(IToken::flVOLATILE))
+        a_stVal.top()->AddFlags(IToken::flVOLATILE);
+
+      ptr_tok_type opElse = a_stOpt.pop();
+      ptr_tok_type opIf = a_stOpt.pop();
+      MUP_ASSERT(opElse->GetCode()==cmELSE)
+      MUP_ASSERT(opIf->GetCode()==cmIF)
+      
+      m_rpn.Add(ptr_tok_type(new TokenIfThenElse(cmENDIF)));
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserXBase::DumpRPN() const
+  {
+    m_rpn.AsciiDump();
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserXBase::CreateRPN() const
+  {
+    if (!m_pTokenReader->GetExpr().length()) 
+      Error(ecUNEXPECTED_EOF, 0);
+
+    // The Stacks take the ownership over the tokens
+    Stack<ptr_tok_type> stOpt;
+    Stack<ptr_val_type> stVal;
+    Stack<ICallback*>   stFunc;  
+    Stack<int>  stArgCount;
+    Stack<int>  stIdxCount;
+    ptr_tok_type pTok, pTokPrev;
+    Value val;    
+
+    ReInit();
+
+    // The outermost counter counts the number of seperated items
+    // such as in "a=10,b=20,c=c+a"
+    stArgCount.push(1);
+
+    for(bool bLoop=true; bLoop;)
+    {
+      pTokPrev = pTok;
+      pTok = m_pTokenReader->ReadNextToken();
+
+#if defined(MUP_DUMP_TOKENS)
+      cout << pTok->AsciiDump() << endl;
+#endif
+      ECmdCode eCmd = pTok->GetCode();
+      switch (eCmd)
+      {
+      case  cmVAR:
+      case  cmVAL:
+            {
+              IValue *pVal = pTok->AsIValue();
+              if (stFunc.empty() && pVal->GetType()=='n')
+              {
+                ErrorContext err;
+                err.Errc  = ecUNEXPECTED_PARENS;
+                err.Ident = _T(")");
+                err.Pos   = pTok->GetExprPos();
+                throw ParserError(err);
+              }
+
+              stVal.push( ptr_val_type(pVal) );
+              
+              // Arrays can't be added directly to the reverse polish notation
+              // since there may be an index operator following next...
+              m_rpn.Add(pTok);
+
+              // Apply infix operator if existant
+              if (stOpt.size() && stOpt.top()->GetCode()==cmOPRT_INFIX) 
+                ApplyFunc(stOpt, stVal, 1);
+            }
+            break;
+
+      case  cmIC:
+            {
+              // The argument count for parameterless functions is zero
+              // by default an opening bracket sets parameter count to 1
+              // in preparation of arguments to come. If the last token
+              // was an opening bracket we know better...
+              if (pTokPrev.Get()!=NULL && pTokPrev->GetCode()==cmIO)
+                --stArgCount.top();
+
+              ApplyRemainingOprt(stOpt, stVal);
+
+              // if opt is "]" and opta is "[" the bracket content has been evaluated.
+              // Now its time to check if there is either a function or a sign pending.
+              // - Neither the opening nor the closing bracket will be pushed back to
+              //   the operator stack
+              // - Check if a function is standing in front of the opening bracket, 
+              //   if so evaluate it afterwards to apply an infix operator.
+              if ( stOpt.size() && stOpt.top()->GetCode()==cmIO )
+              {
+                //
+                // Find out how many dimensions were used in the index operator.
+                //
+                std::size_t iArgc = stArgCount.pop();
+
+                stOpt.pop(); // Take opening bracket from stack
+                
+                IOprtIndex *pOprtIndex = pTok->AsIOprtIndex();
+                MUP_ASSERT(pOprtIndex!=NULL);
+
+                pOprtIndex->SetNumArgsPresent(iArgc);
+                m_rpn.Add(pTok);
+                
+                // Pop the index values from the stack
+                MUP_ASSERT(stVal.size()>=iArgc+1); 
+                for (std::size_t i=0; i<iArgc; ++i)
+                  stVal.pop();
+
+                // Now i would need to pop the topmost value from the stack, apply the index
+                // opertor and push the result back to the stack. But here we are just creating the
+                // RPN and are working with dummy values anyway so i just mark the topmost value as 
+                // volatile and leave it were it is. The real index logic is in the RPN evaluator...
+                stVal.top()->AddFlags(IToken::flVOLATILE);
+              } // if opening index bracket is on top of operator stack
+            }
+            break;
+
+      case  cmBC:
+            {
+              // The argument count for parameterless functions is zero
+              // by default an opening bracket sets parameter count to 1
+              // in preparation of arguments to come. If the last token
+              // was an opening bracket we know better...
+              if (pTokPrev.Get()!=NULL && pTokPrev->GetCode()==cmBO)
+                --stArgCount.top();
+
+              ApplyRemainingOprt(stOpt, stVal);
+
+              // if opt is ")" and opta is "(" the bracket content has been evaluated.
+              // Now its time to check if there is either a function or a sign pending.
+              // - Neither the opening nor the closing bracket will be pushed back to
+              //   the operator stack
+              // - Check if a function is standing in front of the opening bracket, 
+              //   if so evaluate it afterwards to apply an infix operator.
+              if ( stOpt.size() && stOpt.top()->GetCode()==cmBO )
+              {
+                //
+                // Here is the stuff to evaluate a function token
+                //
+                int iArgc = stArgCount.pop();
+
+                stOpt.pop(); // Take opening bracket from stack
+                if ( stOpt.empty() )
+                  break;
+                  
+                if ( (stOpt.top()->GetCode()!=cmFUNC) && (stOpt.top()->GetCode()!=cmOPRT_INFIX) )
+                  break;
+
+                ICallback *pFun = stOpt.top()->AsICallback();
+                stFunc.pop(); 
+
+                if (pFun->GetArgc()!=-1 && iArgc > pFun->GetArgc())
+                  Error(ecTOO_MANY_PARAMS, pTok->GetExprPos(), pFun);
+
+                if (iArgc < pFun->GetArgc())
+                  Error(ecTOO_FEW_PARAMS, pTok->GetExprPos(), pFun);
+
+                // Evaluate the function
+                ApplyFunc(stOpt, stVal, iArgc);
+
+                // Apply an infix operator, if present
+                if (stOpt.size() && stOpt.top()->GetCode()==cmOPRT_INFIX) 
+                  ApplyFunc(stOpt, stVal, 1);
+              }
+            }
+            break;
+
+      case  cmELSE:
+            ApplyRemainingOprt(stOpt, stVal);
+            m_rpn.Add(pTok);
+            stOpt.push(pTok);
+            break;
+
+      case  cmSCRIPT_NEWLINE:
+            {
+              ApplyRemainingOprt(stOpt, stVal);
+
+              // Value stack plätten
+              // Stack der RPN um die Anzahl im stack enthaltener Werte zurück setzen
+              int n = stVal.size();
+              m_rpn.AddNewline(pTok, n);
+              stVal.clear();
+              stOpt.clear();
+            }
+            break;
+
+      case  cmARG_SEP:
+            if (stArgCount.empty())
+              Error(ecUNEXPECTED_COMMA, m_pTokenReader->GetPos());
+
+            ++stArgCount.top();
+
+            //if (stVal.size()) // increase argument counter
+            //  stArgCount.top()++;
+
+            ApplyRemainingOprt(stOpt, stVal);
+            break;
+
+      case  cmEOE:
+            ApplyRemainingOprt(stOpt, stVal);
+            m_rpn.Finalize();
+            break;
+
+      case  cmIF:
+      case  cmOPRT_BIN:
+            {
+              while ( stOpt.size() && 
+                      stOpt.top()->GetCode() != cmBO && 
+                      stOpt.top()->GetCode() != cmIO && 
+                      stOpt.top()->GetCode() != cmELSE &&
+                      stOpt.top()->GetCode() != cmIF)
+              {
+                IToken *pOprt1 = stOpt.top().Get();
+                IToken *pOprt2 = pTok.Get();
+                MUP_ASSERT(pOprt1 && pOprt2);  
+                MUP_ASSERT(pOprt1->AsIPrecedence() && pOprt2->AsIPrecedence());  
+
+                int nPrec1 = pOprt1->AsIPrecedence()->GetPri(),
+                    nPrec2 = pOprt2->AsIPrecedence()->GetPri();
+
+                if (pOprt1->GetCode()==pOprt2->GetCode())
+                {
+                  // Deal with operator associativity
+                  EOprtAsct eOprtAsct = pOprt1->AsIPrecedence()->GetAssociativity();
+                  if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || 
+                       (eOprtAsct==oaLEFT  && (nPrec1 <  nPrec2)) )
+                  {
+                    break;
+                  }
+                }
+                else if (nPrec1 < nPrec2)
+                {
+                  break;
+                }
+                
+                // apply the operator now 
+                // (binary operators are identic to functions with two arguments)
+                ApplyFunc(stOpt, stVal, 2);
+              } // while ( ... )
+
+              if (pTok->GetCode()==cmIF)
+                m_rpn.Add(pTok);
+
+              stOpt.push(pTok);
+            }
+            break;
+
+      //
+      //  Postfix Operators
+      //
+      case  cmOPRT_POSTFIX:
+            {
+              ICallback *pOprt = pTok->AsICallback();
+              MUP_ASSERT(stVal.size());
+
+              ptr_val_type &pVal(stVal.top());
+              try
+              {
+                // place a dummy return value into the value stack, do not
+                // evaluate pOprt (this is important for lazy evaluation!)
+                // The only place where evaluation takes place is the RPN 
+                // engine!
+                pVal = ptr_val_type(new Value());
+                m_rpn.Add(pTok);
+              }
+              catch(ParserError &)
+              {
+                if (!m_bIsQueryingExprVar)
+                  throw;
+              }
+            }
+  		      break;
+
+      case  cmIO:
+      case  cmBO:    
+            stOpt.push(pTok);
+            stArgCount.push(1);
+            break;
+
+      //
+      // Functions
+      //
+      case  cmOPRT_INFIX:
+      case  cmFUNC:
+            {
+              ICallback *pFunc = pTok->AsICallback();
+              MUP_ASSERT(pFunc);
+
+              // Check if this function is a argument to another function
+              // if so check if the the return type fits.
+              if (!stFunc.empty() && stFunc.top()->GetCode()==cmFUNC)
+              {
+                MUP_ASSERT(stArgCount.size());
+                int iArgc = (int)stArgCount.top() /*+ 1*/;
+
+                ICallback *pOuterFunc = stFunc.top();
+                if (pOuterFunc->GetArgc()!=-1 && iArgc>pOuterFunc->GetArgc())
+		              Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos());
+
+                MUP_ASSERT(pOuterFunc->GetArgc()==-1 || iArgc<=pOuterFunc->GetArgc());
+              }
+
+              stOpt.push(pTok);  
+              stFunc.push(pFunc); // to collect runtime type information
+            }
+	          break;
+
+      default: 
+            Error(ecINTERNAL_ERROR);
+      } // switch Code
+
+      if (ParserXBase::s_bDumpStack)
+      {
+        StackDump( stVal, stOpt );
+      }
+
+      if ( pTok->GetCode() == cmEOE )
+        bLoop = false;
+    } // for (all tokens)
+
+    if (ParserXBase::s_bDumpRPN)
+    {
+      m_rpn.AsciiDump();
+    }
+
+    m_nFinalResultIdx = stArgCount.top()-1;
+    MUP_ASSERT(stVal.size());
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief One of the two main parse functions.
+      \sa ParseCmdCode(), ParseValue()
+
+    Parse expression from input string. Perform syntax checking and create bytecode.
+    After parsing the string and creating the bytecode the function pointer 
+    #m_pParseFormula will be changed to the second parse routine the uses bytecode instead of string parsing.
+  */
+  const IValue& ParserXBase::ParseFromString() const
+  { 
+    CreateRPN();
+
+    // Umsachalten auf RPN
+    m_vStackBuffer.assign(m_rpn.GetRequiredStackSize(), ptr_val_type());
+    for (std::size_t i=0; i<m_vStackBuffer.size(); ++i)
+    {
+      Value *pValue = new Value;
+      pValue->BindToCache(&m_cache);
+      m_vStackBuffer[i].Reset(pValue);
+    }
+
+    m_pParserEngine = &ParserXBase::ParseFromRPN;
+
+    return (this->*m_pParserEngine)();
+  } 
+
+  //---------------------------------------------------------------------------
+  const IValue& ParserXBase::ParseFromRPN() const
+  {
+    ptr_val_type *pStack = &m_vStackBuffer[0];
+    const ptr_tok_type *pRPN = &(m_rpn.GetData()[0]);
+
+    int sidx = -1;
+    std::size_t lenRPN = m_rpn.GetSize();
+    for (std::size_t i=0; i<lenRPN; ++i)
+    {
+      IToken *pTok = pRPN[i].Get();
+      ECmdCode eCode = pTok->GetCode();
+
+      switch (eCode)
+      {
+      case cmSCRIPT_NEWLINE:
+           sidx = -1; //-= static_cast<TokenNewline*>(pTok)->GetStackOffset();
+           m_nFinalResultIdx = 0;
+           continue;
+
+      case cmVAR:
+           {
+             sidx++;
+             assert(sidx<(int)m_vStackBuffer.size());
+             pStack[sidx].Reset(static_cast<IValue*>(pTok));
+           }
+           continue;
+
+      case cmVAL:
+           {
+             sidx++;
+             assert(sidx<(int)m_vStackBuffer.size());
+             ptr_val_type &val = pStack[sidx];
+             if (val->GetCode()==cmVAR)
+               val.Reset(m_cache.CreateFromCache());
+
+             *val = *(static_cast<IValue*>(pTok));
+           }
+           continue;
+
+      case  cmIC:
+            {
+              IOprtIndex *pIdxOprt = static_cast<IOprtIndex*>(pTok);
+              int nArgs = pIdxOprt->GetArgsPresent();
+              sidx -= nArgs - 1;
+              assert(sidx>=0);
+
+              ptr_val_type &idx = pStack[sidx];     // Pointer to the first index
+              ptr_val_type &val = pStack[--sidx];   // Pointer to the variable or value beeing indexed
+              pIdxOprt->At(val, &idx, nArgs);
+
+
+
+
+/*
+
+              // apply the index operator
+              ptr_val_type &idx = pStack[sidx--];
+              ptr_val_type &val = pStack[sidx];
+              MUP_ASSERT(val->GetCode()==cmVAR);
+             
+              int i;
+              try
+              {
+                i = idx->GetInteger();
+                if (i<0)
+                  Error(ecINDEX_OUT_OF_BOUNDS, pTok->GetExprPos(), val.Get());
+              }
+              catch(ParserError &exc)
+              {
+                if (exc.GetCode()==ecTYPE_CONFLICT)
+                  Error(ecTYPE_CONFLICT_IDX, pTok->GetExprPos(), val.Get());
+                else 
+                  throw;
+              }
+              val.Reset(new Variable( &(val->At(i)) ) );
+*/
+            }
+            continue;
+
+      case cmOPRT_POSTFIX:
+      case cmFUNC:
+      case cmOPRT_BIN:
+      case cmOPRT_INFIX:
+           {
+             ICallback *pFun = static_cast<ICallback*>(pTok);
+             int nArgs = pFun->GetArgsPresent();
+             sidx -= nArgs - 1;
+             assert(sidx>=0);
+
+             ptr_val_type &val = pStack[sidx];
+             try
+             {
+               if (val->GetCode()==cmVAR)
+               {
+                 ptr_val_type buf(m_cache.CreateFromCache());
+                 pFun->Eval(buf, &val, nArgs);
+                 val = buf;
+               }
+               else
+                 pFun->Eval(val, &val, nArgs);
+             }
+             catch(ParserError &exc)
+             {
+               ErrorContext err;
+               err.Expr = m_pTokenReader->GetExpr();
+               err.Ident = pFun->GetIdent();
+               err.Errc = ecEVAL;
+               err.Pos = pFun->GetExprPos();
+               err.Hint = exc.GetMsg();
+               throw ParserError(err);
+             }
+             catch(MatrixError &exc)
+             {
+               ErrorContext err;
+               err.Expr = m_pTokenReader->GetExpr();
+               err.Ident = pFun->GetIdent();
+               err.Errc = ecEVAL;
+               err.Pos = pFun->GetExprPos();
+               err.Hint = _T("Matrix dimension mismatch");
+               throw ParserError(err);
+             }
+           }
+           continue;
+
+      case cmIF:
+           MUP_ASSERT(sidx>=0);
+           if (pStack[sidx--]->GetBool()==false)
+             i+=static_cast<TokenIfThenElse*>(pTok)->GetOffset();
+           continue;
+
+      case cmELSE:
+      case cmJMP:
+           i += static_cast<TokenIfThenElse*>(pTok)->GetOffset();
+           continue;
+
+      case cmENDIF:
+           continue;
+
+			default:
+					Error(ecINTERNAL_ERROR);
+      } // switch token
+    } // for all RPN tokens
+
+    return *pStack[m_nFinalResultIdx];
+  }
+
+  //---------------------------------------------------------------------------
+  void  ParserXBase::Error(EErrorCodes a_iErrc, int a_iPos, const IToken *a_pTok) const
+  {
+    ErrorContext err;
+    err.Errc = a_iErrc;
+    err.Pos = a_iPos;
+    err.Expr = m_pTokenReader->GetExpr();
+    err.Ident = (a_pTok) ? a_pTok->GetIdent() : _T("");
+    throw ParserError(err);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined variables.
+      \throw nothrow
+      
+      Resets the parser to string parsing mode by calling #ReInit.
+  */
+  void ParserXBase::ClearVar()
+  {
+    m_VarDef.clear();
+    m_valDynVarShadow.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Remove a variable from internal storage.
+      \param a_strVarName Name of the variable to be removed.
+      \throw nothrow
+
+    Removes a variable if it exists. If the Variable does not exist 
+    nothing will be done.
+  */
+  void ParserXBase::RemoveVar(const string_type &a_strVarName)
+  {
+    var_maptype::iterator item = m_VarDef.find(a_strVarName);
+    if (item!=m_VarDef.end())
+    {
+      m_VarDef.erase(item);
+      ReInit();
+    }
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear the expression. 
+      \throw nothrow
+
+      Clear the expression and existing bytecode.
+  */
+  void ParserXBase::ClearExpr()
+  {
+    m_pTokenReader->SetExpr(_T(""));
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all function definitions. 
+      \throw nothrow
+  */
+  void ParserXBase::ClearFun()
+  {
+    m_FunDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined constants.
+      \throw nothrow
+
+      Both numeric and string constants will be removed from the internal storage.
+  */
+  void ParserXBase::ClearConst()
+  {
+    m_valConst.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined postfix operators.
+      \throw nothrow
+  */
+  void ParserXBase::ClearPostfixOprt()
+  {
+    m_PostOprtDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined binary operators. 
+      \throw nothrow
+  */
+  void ParserXBase::ClearOprt()
+  {
+    m_OprtDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear the user defined Prefix operators. 
+      \throw nothrow
+  */
+  void ParserXBase::ClearInfixOprt()
+  {
+    m_InfixOprtDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  void ParserXBase::EnableAutoCreateVar(bool bStat)
+  {
+    m_bAutoCreateVar = bStat;
+  }
+
+  //------------------------------------------------------------------------------
+  void ParserXBase::EnableOptimizer(bool bStat)
+  {
+    m_rpn.EnableOptimizer(bStat);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Enable the dumping of bytecode amd stack content on the console. 
+      \param bDumpCmd Flag to enable dumping of the current bytecode to the console.
+      \param bDumpStack Flag to enable dumping of the stack content is written to the console.
+
+     This function is for debug purposes only!
+  */
+  void ParserXBase::EnableDebugDump(bool bDumpRPN, bool bDumpStack)
+  {
+    ParserXBase::s_bDumpRPN   = bDumpRPN;
+    ParserXBase::s_bDumpStack = bDumpStack;
+  }
+
+  //------------------------------------------------------------------------------
+  bool ParserXBase::IsAutoCreateVarEnabled() const
+  {
+    return m_bAutoCreateVar;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Dump stack content. 
+
+      This function is used for debugging only.
+  */
+  void ParserXBase::StackDump(const Stack<ptr_val_type> &a_stVal, 
+			             			      const Stack<ptr_tok_type> &a_stOprt) const
+  {
+    using std::cout;
+    Stack<ptr_tok_type>  stOprt(a_stOprt); 
+    Stack<ptr_val_type>  stVal(a_stVal);
+
+    string_type sInfo = _T("StackDump>  ");
+    console() << _T("\n") << sInfo << _T("Value stack:\n");
+    console() << sInfo;
+    while ( !stVal.empty() ) 
+    {
+      ptr_val_type val = stVal.pop();
+      console() << _T("  ") << *(val.Get()) << _T(" ") << ((val->AsValue()!=NULL) ? _T("(Val)") : _T("(Var)"));
+    }
+
+    if (stOprt.empty())
+      console() << _T("\n") << sInfo << _T("Operator stack is empty.\n");
+    else
+      console() << _T("\n") << sInfo << _T("Operator stack:\n");
+
+    while ( !stOprt.empty() )
+    {
+      ptr_tok_type tok = stOprt.pop();
+      console() << sInfo << _T(" ") << g_sCmdCode[tok->GetCode()] << _T(" \"") << tok->GetIdent() << _T("\" \n");
+    }
+
+    console() <<endl;
+  }
+
+} // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpParserBase.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpParserBase.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,198 @@
+/** \file
+    \brief Definition of the muParserX engine.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_PARSERBASE_H
+#define MUP_PARSERBASE_H
+
+#include <cmath>
+#include <string>
+#include <iostream>
+#include <map>
+#include <memory>
+
+#include "mpIOprt.h"
+#include "mpIValReader.h"
+#include "mpIPackage.h"
+#include "mpStack.h"
+#include "mpTokenReader.h"
+#include "mpError.h"
+#include "mpValue.h"
+#include "mpVariable.h"
+#include "mpTypes.h"
+#include "mpRPN.h"
+#include "mpValueCache.h"
+
+MUP_NAMESPACE_START
+  
+  /** \brief Implementation of the parser engine.
+      \author Ingo Berg
+
+    This is the muParser core. It provides the parsing logic and manages
+    the callback functions, operators, variables and constants. Do not 
+    instantiate this class directly. Create an instance of mup::ParserX instead.
+  */
+  class ParserXBase
+  {
+  friend class TokenReader;
+
+  private:
+
+    //typedef Value (ParserXBase::*parse_function_type)() const;  
+    typedef const IValue& (ParserXBase::*parse_function_type)() const;  
+    static const char_type *c_DefaultOprt[]; 
+    static bool s_bDumpStack;
+    static bool s_bDumpRPN;
+
+  public:
+
+    static string_type GetVersion();
+    static void EnableDebugDump(bool bDumpCmd, bool bDumpRPN);
+
+    ParserXBase(); 
+    ParserXBase( const ParserXBase &a_Parser );
+    ParserXBase& operator=(const ParserXBase &a_Parser);
+    virtual ~ParserXBase();
+    
+    const IValue& Eval() const;
+
+    void SetExpr(const string_type &a_sExpr);
+    void AddValueReader(IValueReader *a_pReader);
+
+    void AddPackage(IPackage *p);
+    void RemovePackage(IPackage *p);
+
+    void DefineFun(ICallback *a_pCallback);
+    void DefineConst(const string_type &a_sName, const Value &a_Val);
+    void DefineVar(const string_type &a_sName, const Variable &a_fVar);
+    
+    // adding operators
+    void DefineOprt(IOprtBin *a_pCallback);
+    void DefinePostfixOprt(IOprtPostfix *a_pCallback);
+    void DefineInfixOprt(IOprtInfix *a_pCallback);
+
+    // Clear user defined variables, constants or functions
+    void ClearVar();
+    void ClearFun();
+    void ClearConst();
+    void ClearInfixOprt();
+    void ClearPostfixOprt();
+    void ClearOprt();
+    void DumpRPN() const;
+
+    void RemoveVar(const string_type &a_sVarName);
+    const var_maptype& GetExprVar() const;
+    const var_maptype& GetVar() const;
+    const val_maptype& GetConst() const;
+    const fun_maptype& GetFunDef() const;
+    const string_type& GetExpr() const;
+
+    const char_type ** GetOprtDef() const;
+    void DefineNameChars(const char_type *a_szCharset);
+    void DefineOprtChars(const char_type *a_szCharset);
+    void DefineInfixOprtChars(const char_type *a_szCharset);
+    
+    void EnableAutoCreateVar(bool bStat);
+    void EnableOptimizer(bool bStat);
+    bool IsAutoCreateVarEnabled() const;
+
+    const char_type* ValidNameChars() const;
+    const char_type* ValidOprtChars() const;
+    const char_type* ValidInfixOprtChars() const;
+
+    void  Error(EErrorCodes a_iErrc, 
+                int a_iPos = -1,
+                const IToken *a_pTok = 0) const;
+
+  private:
+
+    void Assign(const ParserXBase &a_Parser);
+    void InitTokenReader();
+    void ReInit() const;
+
+    void ApplyFunc(Stack<ptr_tok_type> &a_stOpt, Stack<ptr_val_type> &a_stVal, int a_iArgCount) const;
+    void ApplyIfElse(Stack<ptr_tok_type> &a_stOpt, Stack<ptr_val_type> &a_stVal) const;
+    void ApplyRemainingOprt(Stack<ptr_tok_type> &a_stOpt,
+                                Stack<ptr_val_type> &a_stVal) const;
+
+    const IValue& ParseFromString() const; 
+    const IValue& ParseFromRPN() const; 
+
+    void  ClearExpr();
+    void  CheckName(const string_type &a_sName, const string_type &a_CharSet) const;
+    void  CreateRPN() const;
+    void  StackDump( const Stack<ptr_val_type> &a_stVal, 
+                     const Stack<ptr_tok_type> &a_stOprt ) const;
+
+    /** \brief Pointer to the parser function. 
+    
+      Eval() calls the function whose address is stored there.
+    */
+    mutable parse_function_type m_pParserEngine;
+
+    /** \brief Managed pointer to the token reader object. */
+    std::auto_ptr<TokenReader> m_pTokenReader; 
+
+    fun_maptype  m_FunDef;           ///< Function definitions
+    oprt_pfx_maptype m_PostOprtDef;  ///< Postfix operator callbacks
+    oprt_ifx_maptype m_InfixOprtDef; ///< Infix operator callbacks.
+    oprt_bin_multimap m_OprtDef;     ///< Binary operator callbacks
+    val_maptype  m_valConst;         ///< Definition of parser constants
+    val_vec_type m_valDynVarShadow;  ///< Value objects referenced by variables created at parser runtime
+    var_maptype  m_VarDef;           ///< user defind variables.
+
+    string_type m_sNameChars;        ///< Charset for names
+    string_type m_sOprtChars;        ///< Charset for postfix/ binary operator tokens
+    string_type m_sInfixOprtChars;   ///< Charset for infix operator tokens
+
+    /** \brief Index of the final result in the stack array. 
+    
+      The parser supports expressions using with commas for seperating
+      multiple expression. Each comma will increase this number.
+      (i.e. "a=10,b=15,c=a*b")
+    */
+    mutable int m_nFinalResultIdx;          
+
+    /** \brief A flag indicating querying of expression variables is underway.
+      
+      If this flag is set the parser is momentarily querying the expression 
+      variables. In these cases undefined variable errors must be ignored cause 
+      the whole point of querying the expression variables is for finding out 
+      which variables mut be defined.
+    */
+    mutable bool m_bIsQueryingExprVar;    
+
+    mutable bool m_bAutoCreateVar;      ///< If this flag is set unknown variables will be defined automatically
+
+    mutable RPN m_rpn;                  ///< reverse polish notation
+    mutable val_vec_type m_vStackBuffer;
+    mutable ValueCache m_cache;         ///< A cache for recycling value items instead of deleting them
+  };
+} // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpRPN.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpRPN.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,172 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpRPN.h"
+#include "mpIToken.h"
+#include "mpICallback.h"
+#include "mpError.h"
+#include "mpStack.h"
+#include "mpIfThenElse.h"
+#include "mpScriptTokens.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  RPN::RPN()
+    :m_vRPN()
+    ,m_nStackPos(-1)
+    ,m_nLine(0)
+    ,m_nMaxStackPos(0)
+    ,m_bEnableOptimizer(false)
+  {}
+  
+  //---------------------------------------------------------------------------
+  RPN::~RPN()
+  {}
+    
+  //---------------------------------------------------------------------------
+  void RPN::Add(ptr_tok_type tok)
+  {
+    m_vRPN.push_back(tok);
+    if (tok->AsIValue()!=NULL)
+    {
+      m_nStackPos++;
+    }
+    else if (tok->AsICallback())
+    {
+      ICallback *pFun = tok->AsICallback();
+      MUP_ASSERT(pFun);
+      m_nStackPos -= pFun->GetArgsPresent() - 1;
+    }
+
+    MUP_ASSERT(m_nStackPos>=0);
+    m_nMaxStackPos = std::max(m_nStackPos, m_nMaxStackPos);
+  }
+  
+  //---------------------------------------------------------------------------
+  void RPN::AddNewline(ptr_tok_type tok, int n)
+  {
+    static_cast<TokenNewline*>(tok.Get())->SetStackOffset(n);
+    m_vRPN.push_back(tok);
+    m_nStackPos -= n;
+    m_nLine++;
+  }
+
+  //---------------------------------------------------------------------------
+  void RPN::Pop(int num)
+  {
+    if (m_vRPN.size()==0)
+      return;
+
+    for (int i=0; i<num; ++i)
+    {
+      ptr_tok_type tok = m_vRPN.back();
+      
+      if (tok->AsIValue()!=0)
+        m_nStackPos--;
+
+      m_vRPN.pop_back();
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  void RPN::Reset()
+  {
+    m_vRPN.clear();
+    m_nStackPos = -1;
+    m_nMaxStackPos = 0;
+    m_nLine = 0;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief 
+
+      At the moment this will only ass the jump distances to the if-else clauses 
+      found in the expression. 
+  */
+  void RPN::Finalize()
+  {
+    // Determine the if-then-else jump offsets
+    Stack<int> stIf, stElse;
+    int idx;
+    for (std::size_t i=0; i<m_vRPN.size(); ++i)
+    {
+      switch(m_vRPN[i]->GetCode())
+      {
+      case  cmIF:
+            stIf.push(i);
+            break;
+
+      case  cmELSE:
+            stElse.push(i);
+            idx = stIf.pop();
+            static_cast<TokenIfThenElse*>(m_vRPN[idx].Get())->SetOffset(i - idx);
+            break;
+      
+      case  cmENDIF:
+            idx = stElse.pop();
+            static_cast<TokenIfThenElse*>(m_vRPN[idx].Get())->SetOffset(i - idx);
+            break;
+      }
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  void  RPN::EnableOptimizer(bool bStat)
+  {
+    m_bEnableOptimizer = bStat;
+  }
+
+  //---------------------------------------------------------------------------
+  std::size_t RPN::GetSize() const
+  {
+    return m_vRPN.size();
+  }
+
+  //---------------------------------------------------------------------------
+  const token_vec_type& RPN::GetData() const
+  {
+    return m_vRPN;
+  }
+
+  //---------------------------------------------------------------------------
+  int RPN::GetRequiredStackSize() const
+  {
+    return m_nMaxStackPos + 1;
+  }
+
+  //---------------------------------------------------------------------------
+  void RPN::AsciiDump() const
+  {
+    console() << "Number of tokens: " << m_vRPN.size() << "\n";
+    console() << "MaxStackPos:       " << m_nMaxStackPos << "\n";
+    for (std::size_t i=0; i<m_vRPN.size(); ++i)
+    {
+      ptr_tok_type pTok = m_vRPN[i];
+      console() << i << " : " << pTok->GetExprPos() << " : " << pTok->AsciiDump() << "\n";
+    }
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpRPN.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpRPN.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,69 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_RPN_H
+#define MUP_RPN_H
+
+#include "mpFwdDecl.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief A class representing the reverse polnish notation of the expression. 
+  
+  */
+  class RPN
+  {
+  public:
+    
+    RPN();
+   ~RPN();
+    
+    void Add(ptr_tok_type tok);
+    void AddNewline(ptr_tok_type tok, int n);
+    void Pop(int num);
+    void Reset();
+    void Finalize();
+    void AsciiDump() const;
+
+    const token_vec_type& GetData() const;
+    std::size_t GetSize() const;
+
+    int GetRequiredStackSize() const;
+    void EnableOptimizer(bool bStat);
+
+  private:
+
+    token_vec_type m_vRPN;
+    int m_nStackPos;
+    int m_nLine;
+    int m_nMaxStackPos;
+    bool m_bEnableOptimizer;
+  };
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpScriptTokens.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpScriptTokens.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,43 @@
+#include "mpScriptTokens.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  TokenNewline::TokenNewline()
+    :IToken(cmSCRIPT_NEWLINE)
+    ,m_nOffset(0)
+  {}
+
+  //---------------------------------------------------------------------------
+  IToken* TokenNewline::Clone() const
+  {
+    return new TokenNewline(*this);
+  }
+
+  //---------------------------------------------------------------------------
+  void TokenNewline::SetStackOffset(int nOffset)
+  {
+    m_nOffset = nOffset;
+  }
+
+  //---------------------------------------------------------------------------
+  int TokenNewline::GetStackOffset() const
+  {
+    return m_nOffset;
+  }
+
+  //---------------------------------------------------------------------------
+  string_type TokenNewline::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << "NEWLINE";
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T(" ; offset=") << m_nOffset;
+    ss << _T("]");
+    return ss.str();
+  }
+  
+MUP_NAMESPACE_END
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpScriptTokens.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpScriptTokens.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,61 @@
+/** \file
+    \brief Definition of basic types used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#ifndef MUP_SCRIPT_TOKENS_H
+#define MUP_SCRIPT_TOKENS_H
+
+#include "mpIToken.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief A class for encapsulation a newline token. */
+  class TokenNewline : public IToken
+  {
+  public:
+
+      TokenNewline();
+
+      //---------------------------------------------
+      // IToken interface
+      //---------------------------------------------
+
+      virtual IToken* Clone() const;
+      virtual string_type AsciiDump() const;
+
+      int GetStackOffset() const;
+      void SetStackOffset(int nOffset);
+
+  private:
+      int m_nOffset;
+  };
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpStack.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpStack.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,147 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_STACK_H
+#define MUP_STACK_H
+
+#include <cassert>
+#include <string>
+#include <vector>
+
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  /** \brief Parser stack implementation. 
+
+  Stack implementation based on a std::stack. The behaviour of pop() had been
+  slightly changed in order to get an error code if the stack is empty.
+  The stack is used within the Parser both as a value stack and as an operator stack.
+
+  \author (C) 2010 Ingo Berg 
+  */
+  template <typename TVal, typename TCont = std::vector<TVal> >
+  class Stack 
+  {
+  private:
+      /** \brief Type of the underlying container. */
+      typedef TCont cont_type;
+      cont_type m_Cont;
+
+  public:	
+      typedef TVal value_type;
+    
+      //---------------------------------------------------------------------------
+      Stack()
+        :m_Cont()
+      {}
+
+      //---------------------------------------------------------------------------
+      virtual ~Stack()
+      {
+        m_Cont.clear();
+      }
+
+      //---------------------------------------------------------------------------
+      void clear()
+      {
+        m_Cont.clear();
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Pop a value from the stack.
+      
+        Unlike the standard implementation this function will return the value that
+        is going to be taken from the stack.
+
+        \throw ParserException in case the stack is empty.
+        \sa pop(int &a_iErrc)
+      */
+      value_type pop()
+      {
+        if (empty())
+          throw ParserError(_T("stack is empty."));
+
+        value_type el = top();
+        m_Cont.pop_back();
+        return el;
+      }
+
+      //---------------------------------------------------------------------------
+      void pop(unsigned a_iNum)
+      {
+        for (unsigned i=0; i<a_iNum; ++i)
+          m_Cont.pop_back();
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Push an object into the stack. 
+          \param a_Val object to push into the stack.
+          \throw nothrow
+      */
+      void push(const value_type& a_Val) 
+      { 
+        m_Cont.push_back(a_Val); 
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Return the number of stored elements. */
+      unsigned size() const
+      { 
+        return (unsigned)m_Cont.size(); 
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Returns true if stack is empty false otherwise. */
+      bool empty() const
+      {
+        return m_Cont.empty(); 
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Return reference to the top object in the stack. 
+      
+          The top object is the one pushed most recently.
+      */
+      value_type& top() 
+      { 
+        return m_Cont.back(); 
+      }
+
+      //---------------------------------------------------------------------------
+      value_type* get_data()
+      {
+        return &m_Cont[0];
+      }
+
+      //---------------------------------------------------------------------------
+      const value_type* get_data() const
+      {
+        return &m_Cont[0];
+      }
+  };
+} // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpTest.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpTest.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,1636 @@
+/** \file
+    \brief Implementation of the unit test for muParserX.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpTest.h"
+#include "mpValue.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cmath>
+#include <iostream>
+#include <complex>
+
+#define MUP_CONST_PI  3.141592653589793238462643
+#define MUP_CONST_E   2.718281828459045235360287
+
+using namespace std;
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  class FunTest0 : public ICallback
+  {
+  public:
+    FunTest0() : ICallback(cmFUNC, _T("test0"), 0) 
+    {}
+
+    virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+    {
+      ParserXBase &parser = *GetParent();
+      *ret = 0;
+    }
+
+    virtual const char_type* GetDesc() const
+    {
+      return _T("");
+    }
+    
+    virtual IToken* Clone() const
+    {
+      return new FunTest0(*this);
+    }
+  }; // class FunTest0
+
+
+  //---------------------------------------------------------------------------
+  int ParserTester::c_iCount = 0;
+
+  //---------------------------------------------------------------------------
+  ParserTester::ParserTester()
+    :m_vTestFun()
+    ,m_stream(&console())
+  {
+    AddTest(&ParserTester::TestParserValue);
+    AddTest(&ParserTester::TestUndefVar);
+    AddTest(&ParserTester::TestErrorCodes);
+    AddTest(&ParserTester::TestEqn);
+    AddTest(&ParserTester::TestIfElse);
+    AddTest(&ParserTester::TestMultiLine);
+    AddTest(&ParserTester::TestStringFun);
+    AddTest(&ParserTester::TestMatrix);
+    AddTest(&ParserTester::TestComplex);
+    AddTest(&ParserTester::TestVector);
+    AddTest(&ParserTester::TestBinOp);
+    AddTest(&ParserTester::TestPostfix);
+    AddTest(&ParserTester::TestInfix);
+    AddTest(&ParserTester::TestMultiArg);
+    AddTest(&ParserTester::TestNames);
+    ParserTester::c_iCount = 0;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestUndefVar()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing implicit definition of undefined variables...");
+
+    // Test 1: No variables defined, test detection of undefined variables
+    {
+      ParserX p;
+      p.SetExpr(_T("a+b+c+d"));
+      const mup::var_maptype &expr_var = p.GetExprVar();
+      const mup::var_maptype &var = p.GetVar();
+
+      // The expression contains 4 undefined variables
+      if (expr_var.size()!=4)
+        iNumErr++;
+
+      // There are no variables defined
+      if (var.size()!=0)
+        iNumErr++;
+    }
+
+    // Test 2: Variables were defined explicitely, test detection of variables
+    {
+      ParserX p;
+
+      // Now define the variables and perform the check again
+      Value vVarVal[] = { 1, 2, 3, 4};
+      p.DefineVar( _T("a"), Variable(&vVarVal[0]) );
+      p.DefineVar( _T("b"), Variable(&vVarVal[1]) );
+      p.DefineVar( _T("c"), Variable(&vVarVal[2]) );
+      p.DefineVar( _T("d"), Variable(&vVarVal[3]) );
+
+      p.SetExpr(_T("a+b+c+d"));
+      const mup::var_maptype &expr_var = p.GetExprVar();
+      const mup::var_maptype &var = p.GetVar();
+
+      // The expression contains 4 undefined variables
+      if (expr_var.size()!=4)
+        iNumErr++;
+
+      // There are no variables defined
+      if (var.size()!=4)
+        iNumErr++;
+    }
+
+    // Test 3: Variables were defined implicitels, test detection of undefined variables
+    {
+      ParserX p;
+
+      // Now define the variables and perform the check again
+      p.EnableAutoCreateVar(true);
+
+      p.SetExpr(_T("a+b+c+d"));
+      const mup::var_maptype &expr_var = p.GetExprVar();
+      const mup::var_maptype &var = p.GetVar();
+
+      // The expression contains 4 undefined variables
+      if (expr_var.size()!=4)
+        iNumErr++;
+
+      // There are no variables defined
+      if (var.size()!=4)
+        iNumErr++;
+    }
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestMatrix()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing matrix calculations...");
+
+    Value unity(3, 3, 0);
+    unity.At(0, 0) = 1;
+    unity.At(1, 1) = 1;
+    unity.At(2, 2) = 1;
+
+    Value va(3, 0);
+    va.At(0) = 1;
+    va.At(1) = 2;
+    va.At(2) = 3;
+
+    //Value m2(3, 3, 0);
+    //m2.At(0, 0) = 1;  m2.At(0, 1) = 2;  m2.At(0, 2) = 3;
+    //m2.At(1, 0) = 4;  m2.At(1, 1) = 5;  m2.At(1, 2) = 6;
+    //m2.At(2, 0) = 7;  m2.At(2, 1) = 8;  m2.At(2, 2) = 9;
+
+    Value m1_plus_m2(3, 3, 0);
+    m1_plus_m2.At(0, 0) = 2;  m1_plus_m2.At(0, 1) = 2;  m1_plus_m2.At(0, 2) = 3;
+    m1_plus_m2.At(1, 0) = 4;  m1_plus_m2.At(1, 1) = 6;  m1_plus_m2.At(1, 2) = 6;
+    m1_plus_m2.At(2, 0) = 7;  m1_plus_m2.At(2, 1) = 8;  m1_plus_m2.At(2, 2) = 10;
+
+    Value m2_minus_m1(3, 3, 0);
+    m2_minus_m1.At(0, 0) = 0;  m2_minus_m1.At(0, 1) = 2;  m2_minus_m1.At(0, 2) = 3;
+    m2_minus_m1.At(1, 0) = 4;  m2_minus_m1.At(1, 1) = 4;  m2_minus_m1.At(1, 2) = 6;
+    m2_minus_m1.At(2, 0) = 7;  m2_minus_m1.At(2, 1) = 8;  m2_minus_m1.At(2, 2) = 8;
+
+    Value m2_times_10(3, 3, 0);
+    m2_times_10.At(0, 0) = 10;  m2_times_10.At(0, 1) = 20;  m2_times_10.At(0, 2) = 30;
+    m2_times_10.At(1, 0) = 40;  m2_times_10.At(1, 1) = 50;  m2_times_10.At(1, 2) = 60;
+    m2_times_10.At(2, 0) = 70;  m2_times_10.At(2, 1) = 80;  m2_times_10.At(2, 2) = 90;
+
+    Value va_times_vb_transp(3, 3, 0);
+    va_times_vb_transp.At(0, 0) = 4;   va_times_vb_transp.At(0, 1) = 3;   va_times_vb_transp.At(0, 2) = 2;
+    va_times_vb_transp.At(1, 0) = 8;   va_times_vb_transp.At(1, 1) = 6;   va_times_vb_transp.At(1, 2) = 4;
+    va_times_vb_transp.At(2, 0) = 12;  va_times_vb_transp.At(2, 1) = 9;   va_times_vb_transp.At(2, 2) = 6;
+
+    // Check matrix dimension mismatch error
+    iNumErr += ThrowTest(_T("\"hallo\"+m1"), ecEVAL); 
+    iNumErr += ThrowTest(_T("m1+\"hallo\""), ecEVAL); 
+    iNumErr += ThrowTest(_T("va+m1"), ecEVAL); 
+    iNumErr += ThrowTest(_T("m1+va"), ecEVAL); 
+    iNumErr += ThrowTest(_T("va-m1"), ecEVAL); 
+    iNumErr += ThrowTest(_T("m1-va"), ecEVAL); 
+    iNumErr += ThrowTest(_T("va*m1"), ecEVAL);            // matrix dimension mismatch
+    iNumErr += ThrowTest(_T("m1[1]"),     ecINDEX_DIMENSION);
+    iNumErr += ThrowTest(_T("m1[1,2,3]"), ecINDEX_DIMENSION);
+    iNumErr += ThrowTest(_T("va[1,2]"),   ecINDEX_DIMENSION);
+
+    iNumErr += ThrowTest(_T("a+m1"), ecEVAL); 
+    iNumErr += ThrowTest(_T("m1+a"), ecEVAL); 
+    iNumErr += ThrowTest(_T("a-m1"), ecEVAL); 
+    iNumErr += ThrowTest(_T("m1-a"), ecEVAL); 
+
+    // sample expressions
+    iNumErr += EqnTest(_T("m1"),     unity, true);
+    iNumErr += EqnTest(_T("m1*m1"),  unity, true);
+    iNumErr += EqnTest(_T("m1+m2"),  m1_plus_m2, true);
+    iNumErr += EqnTest(_T("m2-m1"),  m2_minus_m1, true);
+    iNumErr += EqnTest(_T("10*m2"),  m2_times_10, true);
+    iNumErr += EqnTest(_T("m2*10"),  m2_times_10, true);
+    iNumErr += EqnTest(_T("5*m2*b"), m2_times_10, true);
+    iNumErr += EqnTest(_T("b*m2*5"), m2_times_10, true);
+    iNumErr += EqnTest(_T("m1*va"),  va, true); 
+
+    // ones
+    Value ones_3(3, 1.0);
+    Value ones_3x3(3, 3, 1.0);
+    iNumErr += ThrowTest(_T("ones(1,2,3)"), ecEVAL); 
+    iNumErr += ThrowTest(_T("ones()"),      ecEVAL); 
+    iNumErr += EqnTest(_T("ones(1,1)"),  1, true); 
+    iNumErr += EqnTest(_T("ones(1)"),    1, true); 
+    iNumErr += EqnTest(_T("ones(3,3)"),  ones_3x3, true); 
+    iNumErr += EqnTest(_T("ones(3,1)"),  ones_3,   true); 
+    iNumErr += EqnTest(_T("ones(3)"),    ones_3,   true); 
+
+    // transposition
+    iNumErr += EqnTest(_T("va'*vb"),    16,   true); 
+    iNumErr += EqnTest(_T("2*va'*vb"),  32,   true); 
+    iNumErr += EqnTest(_T("va*vb'"),    va_times_vb_transp,   true); 
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestComplex()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing complex calculations...");
+
+    // complex numbers
+    // ca=1+i, cb=2+3i, cc=3+4i
+    iNumErr += EqnTest(_T("ca==1+i"),  true,  true);
+    iNumErr += EqnTest(_T("ca==ca"),   true,  true);
+    iNumErr += EqnTest(_T("ca!=1+i"),  false, true);
+    iNumErr += EqnTest(_T("ca!=ca"),   false, true);
+    iNumErr += EqnTest(_T("ca!=cb"),   true,  true);
+    iNumErr += EqnTest(_T("ca!=va"),   true,  true);
+    iNumErr += EqnTest(_T("ca==va"),   false, true);
+
+    // When comparing complex number Matlab/Octave compare only the real part
+    // I'll do the same...
+    iNumErr += EqnTest(_T("ca<10+i"),  true,  true);
+    iNumErr += EqnTest(_T("ca>10+i"),  false, true);
+    iNumErr += EqnTest(_T("ca<=10+i"), true,  true);
+    iNumErr += EqnTest(_T("ca>=10+i"), false, true);
+    iNumErr += EqnTest(_T("ca<=1"),    true,  true);
+    iNumErr += EqnTest(_T("ca>=1"),    true,  true);
+
+    // complex numbers
+    iNumErr += EqnTest(_T("i*i"), -1, true, 0);
+    iNumErr += EqnTest(_T("norm(3+4i)"), 25, true, 0);
+    iNumErr += EqnTest(_T("norm(4i+3)"), 25, true, 0);
+    iNumErr += EqnTest(_T("norm(3i+4)"), 25, true, 0);
+    iNumErr += EqnTest(_T("real(4.1i+3.1)"), (float_type)3.1, true, 0);
+    iNumErr += EqnTest(_T("imag(3.1i+4.1)"), (float_type)3.1, true, 0);
+    iNumErr += EqnTest(_T("real(3.1)"),  (float_type)3.1, true, 0);
+    iNumErr += EqnTest(_T("imag(2.1i)"), (float_type)2.1, true, 0);
+    iNumErr += EqnTest(_T("-(4i+5)"),       cmplx_type(-5, -4), true, 0);
+    iNumErr += EqnTest(_T("sqrt(-1)"),      cmplx_type(0, 1), true, 0);
+    iNumErr += EqnTest(_T("sqrt(i*i)"),     cmplx_type(0, 1), true, 0);
+    iNumErr += EqnTest(_T("sqrt(f)"),       cmplx_type(0, 1), true, 1);
+    iNumErr += EqnTest(_T("sqrt(2-3)"),     cmplx_type(0, 1), true, 0);
+    iNumErr += EqnTest(_T("sqrt(a-b)"),     cmplx_type(0, 1), true, 2);
+    iNumErr += EqnTest(_T("sqrt((2-3))"),   cmplx_type(0, 1), true, 0);
+    iNumErr += EqnTest(_T("sqrt((a-b))"),   cmplx_type(0, 1), true, 2);
+    iNumErr += EqnTest(_T("sqrt(-(1))"),    cmplx_type(0, 1), true, 0);
+    iNumErr += EqnTest(_T("sqrt((-1))"),    cmplx_type(0, 1), true, 0);
+    iNumErr += EqnTest(_T("sqrt(-(-1))"),   cmplx_type(1, 0), true, 0);
+    iNumErr += EqnTest(_T("sqrt(1)"),       cmplx_type(1, 0), true, 0);
+    iNumErr += EqnTest(_T("a=1+2i"),        cmplx_type(1, 2), true, 1);
+    iNumErr += EqnTest(_T("-(1+2i)"),       cmplx_type(-1, -2), true, 0);
+    iNumErr += EqnTest(_T("-(-1-2i)"),      cmplx_type(1, 2), true, 0);
+    iNumErr += EqnTest(_T("a*i"),           cmplx_type(0, 1), true, 1);
+    iNumErr += EqnTest(_T("-(a+b*i)"),      cmplx_type(-1, -2), true, 2);
+    iNumErr += EqnTest(_T("-(-a-b*i)"),     cmplx_type(1, 2), true, 2);
+    iNumErr += EqnTest(_T("(2+4i)*(8-6i)"), cmplx_type(40, 20), true, 0);
+
+    // Test assignment operator with complex numbers. This needs to be written
+    // in a bit of an obfuscated way in order to make the test work. EqnTest
+    // computes the expression multiple times which would assign the variable
+    // multiple times with different values. This would cause false positives
+    // in the fail count. The result of the test expression is assigned to the
+    // variable c, the original variable is then reset and finally the value
+    // in c is used as the expression result...
+    iNumErr += EqnTest(_T("c=(a+=1+2i), a=1, c"), cmplx_type(2, 2), true, 2);
+    iNumErr += EqnTest(_T("c=(a-=1+2i), a=1, c"), cmplx_type(0, -2), true, 2);
+    iNumErr += EqnTest(_T("c=(b*=1+2i), b=2, c"), cmplx_type(2, 4), true, 2);
+    iNumErr += EqnTest(_T("c=(b/=1+2i), b=2, c"), cmplx_type((float_type)0.4, (float_type)-0.8), true, 2);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestParserValue()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing parser value types...");
+    
+    // Define values and variables for each type
+    Value bVal = true;
+    Value iVal = 10;
+    Value fVal = (float_type)3.14;
+    Value sVal = string_type(_T("hello world"));
+    Value sVal1 = _T("hello world");   // Test assignment from const char* to string
+    Value cVal = cmplx_type(1,1);
+    Value aVal(2,0);
+    aVal.At(0) = (float_type)2.0;
+    aVal.At(1) = (float_type)3.0;
+
+    // Create a 3x3 matrix
+    Value matrix(3, 0);
+    matrix.At(0) = Value(3, 0);
+    matrix.At(1) = Value(3, 0);
+    matrix.At(2) = Value(3, 0);
+
+    Variable bVar(&bVal), 
+             iVar(&iVal), 
+             fVar(&fVal), 
+             sVar(&sVal),
+             sVar1(&sVal1),
+             cVar(&cVal),
+             aVar(&aVal);
+
+    // Check the value types
+    try
+    {
+      // Test if matrix values do work
+      if (!matrix.IsMatrix() || matrix.GetRows()!=3)
+        iNumErr++;
+
+      std::size_t sz = matrix.GetRows();
+      for (std::size_t i=0; i<sz; ++i)
+      {
+        std::size_t dim_row = matrix.At(i).GetRows();
+        if (dim_row!=3)
+        {
+          iNumErr++;
+          console() << _T("\n  Array dimension mismatch in matrix row ") << i 
+                    << _T(" (expected=3; dim=") << dim_row << _T(")");
+        }
+      }
+
+
+      // test type checking of values
+      if ( !iVal.IsScalar()  ||  iVal.IsMatrix()  || iVal.GetType()!='i')  iNumErr++;
+      if ( !fVal.IsScalar()  ||  fVal.IsMatrix()  || fVal.GetType()!='f')  iNumErr++;
+      if ( !cVal.IsScalar()  ||  cVal.IsMatrix()  || cVal.GetType()!='c')  iNumErr++;
+      if (  aVal.IsScalar()  || !aVal.IsMatrix()  || aVal.GetType()!='m')  iNumErr++;
+      if (  sVal.IsScalar()  ||  sVal.IsMatrix()  || sVal.GetType()!='s')  iNumErr++;
+      if (  sVal1.IsScalar() ||  sVal1.IsMatrix() || sVal1.GetType()!='s') iNumErr++;
+      if (  bVal.IsScalar()  ||  bVal.IsMatrix()  || bVal.GetType()!='b')  iNumErr++;
+
+      // test type checking of variables
+      if ( !iVar.IsScalar()  ||  iVar.IsMatrix()  || iVar.GetType()!='i')  iNumErr++;
+      if ( !fVar.IsScalar()  ||  fVar.IsMatrix()  || fVar.GetType()!='f')  iNumErr++;
+      if ( !cVar.IsScalar()  ||  cVar.IsMatrix()  || cVar.GetType()!='c')  iNumErr++;
+      if (  aVar.IsScalar()  || !aVar.IsMatrix()  || aVar.GetType()!='m')  iNumErr++;
+      if (  sVar.IsScalar()  ||  sVar.IsMatrix()  || sVar.GetType()!='s')  iNumErr++;
+      if (  sVar1.IsScalar() ||  sVar1.IsMatrix() || sVar1.GetType()!='s') iNumErr++;
+      if (  bVar.IsScalar()  ||  bVar.IsMatrix()  || bVar.GetType()!='b')  iNumErr++;
+
+      // Test type identifier after calling an assignment operator
+      
+      // a double that can be mapped to an integer without rounding error will become one
+      iVal = (float_type)10.0; 
+      if (  iVar.GetType()!='i')  iNumErr++;  
+
+      iVal = 10;
+      if (  iVar.GetType()!='i')  iNumErr++;  
+
+      // a complex number that can be mapped to an integer without rounding error will become one
+      iVal = cmplx_type(10, 0);
+      if (  iVar.GetType()!='i')  iNumErr++;  
+
+      iVal = (float_type)10.1;
+      if (  iVar.GetType()!='f')  iNumErr++;
+
+      iVal = cmplx_type(10, 1);
+      if (  iVar.GetType()!='c')  iNumErr++;
+
+      iVal = _T("test");
+      if (  iVar.GetType()!='s')  iNumErr++;
+
+      iVal = string_type(_T("test"));
+      if (  iVar.GetType()!='s')  iNumErr++;
+
+      iVal = false;
+      if (  iVar.GetType()!='b')  iNumErr++;
+    }
+    catch(...)
+    {
+      iNumErr++;
+    }
+
+    bool bError;
+
+#define VALUE_THROWCHECK(VAR, FAIL, MEMBER) \
+    bError = (FAIL);                        \
+    try                                     \
+    {                                       \
+      VAR.MEMBER();                         \
+    }                                       \
+    catch(...)                              \
+    {                                       \
+      bError ^= true ;                      \
+    }                                       \
+    iNumErr += (bError) ? 1 : 0;            \
+    c_iCount++;
+
+    // Check if the getter functions really throw an exception 
+    // when used with an incorrect value type
+    // Case 1:  test float values
+    VALUE_THROWCHECK(fVal, false, GetFloat)
+    VALUE_THROWCHECK(fVal, false, GetImag)
+    VALUE_THROWCHECK(fVal, true,  GetBool)
+    VALUE_THROWCHECK(fVal, true,  GetString)
+    VALUE_THROWCHECK(fVal, true,  GetArray)
+    // for variables
+    VALUE_THROWCHECK(fVar, false, GetFloat)
+    VALUE_THROWCHECK(fVar, false, GetImag)
+    VALUE_THROWCHECK(fVar, true,  GetBool)
+    VALUE_THROWCHECK(fVar, true,  GetString)
+    VALUE_THROWCHECK(fVar, true,  GetArray)
+
+    // Case 2:  test bool values
+    VALUE_THROWCHECK(bVal, false,  GetFloat)
+    VALUE_THROWCHECK(bVal, true,  GetImag)
+    VALUE_THROWCHECK(bVal, false, GetBool)
+    VALUE_THROWCHECK(bVal, true,  GetString)
+    VALUE_THROWCHECK(bVal, true,  GetArray)
+    // for variables
+    VALUE_THROWCHECK(bVar, false,  GetFloat)
+    VALUE_THROWCHECK(bVar, true,  GetImag)
+    VALUE_THROWCHECK(bVar, false, GetBool)
+    VALUE_THROWCHECK(bVar, true,  GetString)
+    VALUE_THROWCHECK(bVar, true,  GetArray)
+
+    // Case 3:  test string values
+//    VALUE_THROWCHECK(sVal, true,  GetFloat)
+    VALUE_THROWCHECK(sVal, true,  GetImag)
+    VALUE_THROWCHECK(sVal, true,  GetBool)
+    VALUE_THROWCHECK(sVal, false, GetString)
+    VALUE_THROWCHECK(sVal, true,  GetArray)
+    // for variables
+//    VALUE_THROWCHECK(sVar, true,  GetFloat)
+    VALUE_THROWCHECK(sVar, true,  GetImag)
+    VALUE_THROWCHECK(sVar, true,  GetBool)
+    VALUE_THROWCHECK(sVar, false, GetString)
+    VALUE_THROWCHECK(sVar, true,  GetArray)
+
+    // Case 4:  test array values
+//    VALUE_THROWCHECK(aVal, true,  GetFloat)
+    VALUE_THROWCHECK(aVal, true,  GetImag)
+    VALUE_THROWCHECK(aVal, true,  GetBool)
+    VALUE_THROWCHECK(aVal, true,  GetString)
+    VALUE_THROWCHECK(aVal, false, GetArray)
+    // for variables
+//    VALUE_THROWCHECK(aVar, true,  GetFloat)
+    VALUE_THROWCHECK(aVar, true,  GetImag)
+    VALUE_THROWCHECK(aVar, true,  GetBool)
+    VALUE_THROWCHECK(aVar, true,  GetString)
+    VALUE_THROWCHECK(aVar, false, GetArray)
+
+    // Case 5:  test complex values
+//    VALUE_THROWCHECK(cVal, false,  GetFloat)
+    VALUE_THROWCHECK(cVal, false,  GetImag)
+    VALUE_THROWCHECK(cVal, true,   GetBool)
+    VALUE_THROWCHECK(cVal, true,   GetString)
+    VALUE_THROWCHECK(cVal, true,   GetArray)
+    // for variables
+//    VALUE_THROWCHECK(cVar, false,  GetFloat)
+    VALUE_THROWCHECK(cVar, false,  GetImag)
+    VALUE_THROWCHECK(cVar, true,   GetBool)
+    VALUE_THROWCHECK(cVar, true,   GetString)
+    VALUE_THROWCHECK(cVar, true,   GetArray)
+#undef VALUE_THROWCHECK
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestErrorCodes()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing error codes...");
+
+    // This is allowed now:
+    //iNumErr += ThrowTest(_T("1,2"),   ecUNEXPECTED_COMMA);
+    //iNumErr += ThrowTest(_T("(1,2)"), ecUNEXPECTED_COMMA);
+    //iNumErr += ThrowTest(_T("2*1,2"), ecUNEXPECTED_COMMA);
+
+    iNumErr += ThrowTest(_T("sin(1,2)"), ecTOO_MANY_PARAMS);
+
+    // Invalid function argument types
+    iNumErr += ThrowTest(_T("sin(\"test\")"),        ecEVAL, 0);
+    iNumErr += ThrowTest(_T("max(1, \"test\")"),     ecEVAL, 0);
+    iNumErr += ThrowTest(_T("max(1,sin(8), \"t\")"), ecEVAL, 0);
+    iNumErr += ThrowTest(_T("str2dbl(sin(3.14))"),   ecEVAL, 0); 
+
+    // Invalid unary operator argument types
+    iNumErr += ThrowTest(_T("\"test\"{n}"), ecEVAL, 6); // (nano can only be applied to floats)
+    iNumErr += ThrowTest(_T("(1+3i)/(8*9i)+\"hallo\""), ecEVAL); 
+    iNumErr += ThrowTest(_T("(1+3i)/(8*9i)-\"hallo\""), ecEVAL); 
+    iNumErr += ThrowTest(_T("(1+3i)/(8*9i)*\"hallo\""), ecEVAL); 
+    iNumErr += ThrowTest(_T("(1+3i)/(8*9i)/\"hallo\""), ecEVAL); 
+    iNumErr += ThrowTest(_T("10+va"), ecEVAL, 2); 
+
+    // Type conflicts in binary operators
+    iNumErr += ThrowTest(_T("\"test\" // 8"), ecEVAL, 7);
+    iNumErr += ThrowTest(_T("8//\"test\""),   ecEVAL, 1);
+    iNumErr += ThrowTest(_T("5//8"),          ecEVAL, 1);
+    iNumErr += ThrowTest(_T("\"t\"//sin(8)"), ecEVAL, 3);
+    iNumErr += ThrowTest(_T("sin(8)//\"t\""), ecEVAL, 6);
+
+    // Unexpected end of expression
+    iNumErr += ThrowTest(_T("3+"),    ecUNEXPECTED_EOF);
+    iNumErr += ThrowTest(_T("8*"),    ecUNEXPECTED_EOF);
+    iNumErr += ThrowTest(_T("3+("),   ecUNEXPECTED_EOF);
+    iNumErr += ThrowTest(_T("3+sin"), ecUNEXPECTED_EOF);
+    iNumErr += ThrowTest(_T("(2+"),   ecUNEXPECTED_EOF); 
+
+    iNumErr += ThrowTest(_T("3+)"),       ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("3)"),        ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("(3))"),      ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("()"),        ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("(2+)"),      ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("sin(cos)"),  ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("sin(())"),   ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("sin()"),     ecTOO_FEW_PARAMS);
+    iNumErr += ThrowTest(_T("sin)"),      ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("pi)"),       ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("a)"),        ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("2(-m)"),     ecUNEXPECTED_PARENS);
+    iNumErr += ThrowTest(_T("2(m)"),      ecUNEXPECTED_PARENS);
+
+    iNumErr += ThrowTest(_T("(1+2"),      ecMISSING_PARENS);
+    iNumErr += ThrowTest(_T("((3)"),      ecMISSING_PARENS);
+
+    // The behaviour in the next function depends on whether
+    // implicit variable creation is allowed or not. (momentarily its active)
+    iNumErr += ThrowTest(_T("5z)"),       ecUNASSIGNABLE_TOKEN);
+    iNumErr += ThrowTest(_T("sin(3)xyz"), ecUNASSIGNABLE_TOKEN);
+    iNumErr += ThrowTest(_T("5t6"),       ecUNASSIGNABLE_TOKEN);
+    iNumErr += ThrowTest(_T("5 t 6"),     ecUNASSIGNABLE_TOKEN);
+    iNumErr += ThrowTest(_T("ksdfj"),     ecUNASSIGNABLE_TOKEN);
+
+    // unexpected operator
+    iNumErr += ThrowTest(_T("-{m}"),      ecUNEXPECTED_OPERATOR);
+    iNumErr += ThrowTest(_T("{m}4"),      ecUNEXPECTED_OPERATOR);
+    iNumErr += ThrowTest(_T("sin({m})"),  ecUNEXPECTED_OPERATOR);
+    iNumErr += ThrowTest(_T("{m} {m}"),   ecUNEXPECTED_OPERATOR);
+    iNumErr += ThrowTest(_T("{m}(8)"),    ecUNEXPECTED_OPERATOR);
+    iNumErr += ThrowTest(_T("4 + {m}"),   ecUNEXPECTED_OPERATOR);
+    iNumErr += ThrowTest(_T("5+*3)"),     ecUNEXPECTED_OPERATOR);
+
+    // unexpected comma (used without a function)
+    iNumErr += ThrowTest(_T(",3"),           ecUNEXPECTED_COMMA);
+    iNumErr += ThrowTest(_T("sin(,sin(8))"), ecUNEXPECTED_COMMA);
+
+    iNumErr += ThrowTest(_T("sin(3)cos(3)"), ecUNEXPECTED_FUN);
+    iNumErr += ThrowTest(_T("sin(3)3"),      ecUNEXPECTED_VAL);
+    iNumErr += ThrowTest(_T("sin(3)+"),      ecUNEXPECTED_EOF);
+    
+    // value recognition
+    iNumErr += ThrowTest(_T("0x"),      ecUNASSIGNABLE_TOKEN);  // incomplete hex value
+    iNumErr += ThrowTest(_T("1+0x"),    ecUNASSIGNABLE_TOKEN);  // incomplete hex value  
+    iNumErr += ThrowTest(_T("a+0x"),    ecUNASSIGNABLE_TOKEN);  // incomplete hex value  
+
+    // index operator
+    iNumErr += ThrowTest(_T("min(3,]"), ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("sin(]"),   ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("va[]"),    ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("3+]"),     ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("sin[a)"),  ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("1+[8]"),   ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("1[8]"),    ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("3{n}[1]"), ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("[1]"),     ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("]1"),      ecUNEXPECTED_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("va[[3]]"), ecUNEXPECTED_SQR_BRACKET);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestStringFun()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing string functions...");
+
+    iNumErr += EqnTest(_T("strlen(\"12345\")"), 5, true);
+    iNumErr += EqnTest(_T("strlen(toupper(\"abcde\"))"), 5, true);
+    iNumErr += EqnTest(_T("sin(0)+(float)strlen(\"12345\")"), (float_type)5.0, true);
+    iNumErr += EqnTest(_T("10*(float)strlen(toupper(\"12345\"))"), (float_type)50.0, true);
+    iNumErr += EqnTest(_T("\"hello \"//\"world\""), string_type(_T("hello world")), true);
+    iNumErr += EqnTest(_T("toupper(\"hello \")//\"world\""), string_type(_T("HELLO world")), true);
+    iNumErr += EqnTest(_T("\"hello \"//toupper(\"world\")//\" !!!\""), string_type(_T("hello WORLD !!!")), true);
+
+    Assessment(iNumErr);
+
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestPostfix()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing postfix operators...");
+
+    // application
+    iNumErr += EqnTest(_T("8{n}"), (float_type)8e-9, true);
+    iNumErr += EqnTest(_T("8{n}"), (float_type)123.0, false);
+    iNumErr += EqnTest(_T("3{m}+5"), (float_type)5.003, true);
+    iNumErr += EqnTest(_T("1000{m}"), (float_type)1.0, true);
+    iNumErr += EqnTest(_T("1000 {m}"), (float_type)1.0, true);
+    iNumErr += EqnTest(_T("a{m}"), (float_type)1e-3, true);
+    iNumErr += EqnTest(_T("(a){m}"), (float_type)1e-3, true);
+    iNumErr += EqnTest(_T("-(a){m}"), (float_type)-1e-3, true);
+    iNumErr += EqnTest(_T("-a{m}"), (float_type)-1e-3, true);
+    iNumErr += EqnTest(_T("-2{m}"), (float_type)-2e-3, true);
+    iNumErr += EqnTest(_T("a++b"), 3, true);
+    iNumErr += EqnTest(_T("a ++ b"), 3, true);
+    iNumErr += EqnTest(_T("1++2"), 3, true);
+    iNumErr += EqnTest(_T("1 ++ 2"), 3, true);
+    //iNumErr += EqnTest(_T("f1of1(1000)m"), 1, true);
+    //iNumErr += EqnTest(_T("-f1of1(1000)m"), -1, true);
+    //iNumErr += EqnTest(_T("-f1of1(-1000)m"), 1, true);
+    //iNumErr += EqnTest(_T("f4of4(0,0,0,1000)m"), 1, true);
+    iNumErr += EqnTest(_T("2+(a*1000){m}"), (float_type)3.0, true);
+    // some incorrect results
+    iNumErr += EqnTest(_T("1000{m}"), (float_type)0.1, false);
+    iNumErr += EqnTest(_T("(a){m}"), (float_type)2.0, false);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestInfix()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing parser reader implementations...");
+
+    iNumErr += EqnTest(_T("-1"),    (float_type)-1.0, true);
+    iNumErr += EqnTest(_T("-(-1)"),  (float_type)1.0, true);
+    iNumErr += EqnTest(_T("-(-1)*2"),  (float_type)2.0, true);
+    iNumErr += EqnTest(_T("-(-2)*sqrt(4)"),  (float_type)4.0, true);
+    iNumErr += EqnTest(_T("-a"),  (float_type)-1.0, true);
+    iNumErr += EqnTest(_T("-(a)"),  (float_type)-1.0, true);
+    iNumErr += EqnTest(_T("-(-a)"),  (float_type)1.0, true);
+    iNumErr += EqnTest(_T("-(-a)*2"),  (float_type)2.0, true);
+    iNumErr += EqnTest(_T("-(8)"), (float_type)-8.0, true);
+    iNumErr += EqnTest(_T("-8"), (float_type)-8.0, true);
+    iNumErr += EqnTest(_T("-(2+1)"), (float_type)-3.0, true);
+    //iNumErr += EqnTest("-(f1of1(1+2*3)+1*2)", -9.0, true);
+    //iNumErr += EqnTest("-(-f1of1(1+2*3)+1*2)", 5.0, true);
+    iNumErr += EqnTest(_T("-sin(8)"), (float_type)-0.989358, true);
+    iNumErr += EqnTest(_T("-sin(8)"),  (float_type)0.989358, false);
+    iNumErr += EqnTest(_T("3-(-a)"), (float_type)4.0, true);
+    iNumErr += EqnTest(_T("3--a"), (float_type)4.0, true);
+    iNumErr += EqnTest(_T("2++4"), (float_type)6.0, true);
+    iNumErr += EqnTest(_T("--1"), (float_type)1.0, true);
+
+    // Postfix / infix priorities
+    //iNumErr += EqnTest("~2#", 12, true);
+    //iNumErr += EqnTest("~f1of1(2)#", 12, true);
+    //iNumErr += EqnTest("~(b)#", 12, true);
+    //iNumErr += EqnTest("(~b)#", 12, true);
+    //iNumErr += EqnTest("~(2#)", 8, true);
+    //iNumErr += EqnTest("~(f1of1(2)#)", 8, true);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestMultiArg()
+  {
+    int iNumErr = 0;
+    *m_stream << _T("testing multiarg functions...");
+
+    // application
+    iNumErr += EqnTest(_T("max(1,8,9,(int)6)"), (float_type)9.0, true);
+    iNumErr += EqnTest(_T("max((int)6, 1+2, 4, -9)"), (float_type)6.0, true);
+    iNumErr += EqnTest(_T("min((int)6, 1+2, 4, -9)"), (float_type)-9.0, true);
+
+    // 
+    iNumErr += EqnTest(_T("a=test0()"), (float_type)0, true);
+    iNumErr += EqnTest(_T("b=a+test0()"), (float_type)1, true);
+
+    // added as response to this bugreport:
+    // http://code.google.com/p/muparserx/issues/detail?id=1
+    // cause of the error: Function tokens were not cloned in the tokenreader when beeing found.
+    //                     a pointer to the one and only function onject was returned instead
+    //                     consequently the argument counter was overwritten by the second function call 
+    //                     causing an assertion later on.
+    iNumErr += EqnTest(_T("sum(1,2)/sum(3,4)"), (float_type)0.428571, true);
+    iNumErr += EqnTest(_T("3/sum(3,4,5)"), (float_type)0.25, true);
+    iNumErr += EqnTest(_T("sum(3)/sum(3,4,5)"), (float_type)0.25, true);
+    iNumErr += EqnTest(_T("sum(3)+sum(3,4,5)"), (float_type)15, true);
+    iNumErr += EqnTest(_T("sum(1,2)/sum(3,4,5)"), (float_type)0.25, true);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestVector()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing vector operations...");
+
+    // Vector operations
+    iNumErr += ThrowTest(_T("10+2*va"),    ecEVAL);   // fail: number + vector
+    iNumErr += ThrowTest(_T("10+va*2"),    ecEVAL);   // fail: number + vector
+    iNumErr += ThrowTest(_T("va+vc"),      ecEVAL);   // fail: vectors of different size
+    iNumErr += ThrowTest(_T("va-vc"),      ecEVAL);   // fail: vectors of different size
+    iNumErr += ThrowTest(_T("va*vc"),      ecEVAL);   // fail: vectors of different size
+    iNumErr += ThrowTest(_T("va*vb"),      ecEVAL);   // fail: matrix dimension mismatch
+    iNumErr += ThrowTest(_T("va*va"),      ecEVAL);   // fail: matrix dimension mismatch
+    iNumErr += ThrowTest(_T("(va*vb)*b"),  ecEVAL);   // fail: matrix dimension mismatch
+    iNumErr += ThrowTest(_T("va[1.23]"),   ecTYPE_CONFLICT_IDX, 7);   // fail: float value used as index
+    iNumErr += ThrowTest(_T("va[sin(8)]"), ecTYPE_CONFLICT_IDX, 9);   // fail: float value used as index
+    iNumErr += ThrowTest(_T("va[-1]"),     ecINDEX_OUT_OF_BOUNDS); // fail: negative value used as an index
+    iNumErr += ThrowTest(_T("va[c]"),      ecINDEX_OUT_OF_BOUNDS);
+    iNumErr += ThrowTest(_T("va[(3)]"),    ecINDEX_OUT_OF_BOUNDS);
+    iNumErr += ThrowTest(_T("a[1]"),       ecINDEX_DIMENSION); 
+    iNumErr += ThrowTest(_T("va[1"),       ecMISSING_SQR_BRACKET);
+    iNumErr += ThrowTest(_T("va[1]]"),     ecUNEXPECTED_SQR_BRACKET);
+
+    //iNumErr += ThrowTest(_T("va==9"),      ecEVAL);
+    //iNumErr += ThrowTest(_T("va==a"),      ecEVAL);
+    //iNumErr += ThrowTest(_T("a==va"),      ecEVAL);
+    //iNumErr += ThrowTest(_T("9==va"),      ecEVAL);
+
+    Value v(3, 0);
+    v.At(0) = 5.0, v.At(1) = 5.0, v.At(2) = 5.0;      
+    iNumErr += EqnTest(_T("va+vb"), v, true);
+
+    v.At(0) = 5.0, v.At(1) = 5.0, v.At(2) = 6.0;      
+    iNumErr += EqnTest(_T("va+vb"), v, false);
+
+    v.At(0) = -1.0, v.At(1) = -2.0, v.At(2) = -3.0;
+    iNumErr += EqnTest(_T("-va"), v, true);
+
+    iNumErr += EqnTest(_T("sizeof(va+vb)"), 3, true);
+    iNumErr += EqnTest(_T("sizeof(va-vb)"), 3, true);
+
+    iNumErr += EqnTest(_T("va==vb"), false, true);
+    iNumErr += EqnTest(_T("va!=vb"), true, true);
+    //iNumErr += EqnTest(_T("va<vb"),  false, true);
+    //iNumErr += EqnTest(_T("va>vb"),  true, true);
+    //iNumErr += EqnTest(_T("va<=vb"), false, true);
+    //iNumErr += EqnTest(_T("va>=vb"), true, true);
+
+    iNumErr += EqnTest(_T("vb[va[0]]"), 3, true);
+    iNumErr += EqnTest(_T("m1[0,0]+m1[1,1]+m1[2,2]"), 3, true);
+    iNumErr += EqnTest(_T("vb[m1[0,0]]"), 3, true);
+
+    iNumErr += EqnTest(_T("m1[0,0]=2"), 2, true);
+    iNumErr += EqnTest(_T("m1[1,1]=2"), 2, true);
+    iNumErr += EqnTest(_T("m1[2,2]=2"), 2, true);
+    iNumErr += EqnTest(_T("va[0]=12.3"), (float_type)12.3, true);
+    iNumErr += EqnTest(_T("va[1]=12.3"), (float_type)12.3, true);
+    iNumErr += EqnTest(_T("va[2]=12.3"), (float_type)12.3, true);
+
+    iNumErr += EqnTest(_T("va[0]"), 1, true);
+    iNumErr += EqnTest(_T("va[1]"), 2, true);
+    iNumErr += EqnTest(_T("va[2]"), 3, true);
+    iNumErr += EqnTest(_T("(va[2])"), 3, true);
+    iNumErr += EqnTest(_T("va[a]"), 2, true);
+    iNumErr += EqnTest(_T("(va[a])"), 2, true);
+    iNumErr += EqnTest(_T("va[b]"), 3, true);
+    iNumErr += EqnTest(_T("va[(2)]"), 3, true);
+    iNumErr += EqnTest(_T("va[-(-2)]"), 3, true);
+    iNumErr += EqnTest(_T("(va[(2)])"), 3, true);
+    iNumErr += EqnTest(_T("(va[-(-2)])"), 3, true);
+    iNumErr += EqnTest(_T("va[1+1]"), 3, true);
+    iNumErr += EqnTest(_T("va[(int)sin(8)+1]"), 2, true);
+
+    iNumErr += EqnTest(_T("va[2]+4"), 7, true);
+    iNumErr += EqnTest(_T("4+va[2]"), 7, true);
+    iNumErr += EqnTest(_T("va[2]*4"), 12, true);
+    iNumErr += EqnTest(_T("4*va[2]"), 12, true);
+    iNumErr += EqnTest(_T("va[2]+a"), 4, true);
+    iNumErr += EqnTest(_T("a+va[2]"), 4, true);
+    iNumErr += EqnTest(_T("va[2]*b"), 6, true);
+    iNumErr += EqnTest(_T("b*va[2]"), 6, true);
+
+    //Value buf(3,0);
+    //buf[0] = 3;
+    //buf[1] = 4;
+    //buf[2] = 5;
+    //iNumErr += EqnTest(_T("vx+vy"), buf, true);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestBinOp()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing binary operators...");
+
+    // standard aperators
+    iNumErr += EqnTest(_T("1+7"),   (float_type)8.0, true);
+    iNumErr += EqnTest(_T("10-1"),  (float_type)9.0, true);
+    iNumErr += EqnTest(_T("3*4"),  (float_type)12.0, true);
+    iNumErr += EqnTest(_T("10/2"),  (float_type)5.0, true);
+    // operator associativity
+    iNumErr += EqnTest(_T("2^2^3"),  (float_type)256.0, true);
+    iNumErr += EqnTest(_T("3+4*2/(1-5)^2^3"), (float_type)3.0001220703125, true); 
+    iNumErr += EqnTest(_T("1/2/3"), (float_type)1.0/(float_type)6.0, true); 
+
+    // operator precedencs
+    iNumErr += EqnTest(_T("1+2-3*4/5^6"), (float_type)2.99923, true);
+    iNumErr += EqnTest(_T("a+b-c*4/5^6"), (float_type)2.99923, true);
+    iNumErr += EqnTest(_T("1^2/3*4-5+6"), (float_type)2.3333, true);
+    iNumErr += EqnTest(_T("a^b/c*4-5+6"), (float_type)2.3333, true);
+    iNumErr += EqnTest(_T("1+2*3"), (float_type)7.0, true);
+    iNumErr += EqnTest(_T("a+b*c"), (float_type)7.0, true);
+    iNumErr += EqnTest(_T("(1+2)*3"), (float_type)9.0, true);
+    iNumErr += EqnTest(_T("(a+b)*c"), (float_type)9.0, true);
+    iNumErr += EqnTest(_T("(1+2)*(-3)"), (float_type)-9.0, true);
+    iNumErr += EqnTest(_T("(a+b)*(-c)"), (float_type)-9.0, true);
+    iNumErr += EqnTest(_T("2/4"), (float_type)0.5, true);
+    iNumErr += EqnTest(_T("4&4"), 4, true);
+    iNumErr += EqnTest(_T("2+2&(a+b+c)"), 4, true);
+    iNumErr += EqnTest(_T("3&3"), 3, true);
+    iNumErr += EqnTest(_T("c&3"), 3, true);
+    iNumErr += EqnTest(_T("(c)&3"), 3, true);
+    iNumErr += EqnTest(_T("(a+b)&3"), 3, true);
+    iNumErr += EqnTest(_T("(a+b+c)&6"), 6, true);
+    iNumErr += EqnTest(_T("(1+2+3)&6"), 6, true);
+    iNumErr += EqnTest(_T("3&c"), 3, true);
+    iNumErr += EqnTest(_T("(a<<1)+2"), 4,  true);
+    iNumErr += EqnTest(_T("(a<<2)+2"), 6,  true);
+    iNumErr += EqnTest(_T("(a<<3)+2"), 10, true);
+    iNumErr += EqnTest(_T("(a<<4)+2"), 18, true);
+    iNumErr += EqnTest(_T("(a<<5)+2"), 34, true);
+
+    // bool operators for comparing values
+    iNumErr += EqnTest(_T("a<b"),  true,  true);
+    iNumErr += EqnTest(_T("b>a"),  true,  true);
+    iNumErr += EqnTest(_T("a>a"),  false, true);
+    iNumErr += EqnTest(_T("a<a"),  false, true);
+    iNumErr += EqnTest(_T("a>a"),  false, true);
+    iNumErr += EqnTest(_T("a<=a"), true,  true);
+    iNumErr += EqnTest(_T("a<=b"), true,  true);
+    iNumErr += EqnTest(_T("b<=a"), false, true);
+    iNumErr += EqnTest(_T("a>=a"), true,  true);
+    iNumErr += EqnTest(_T("b>=a"), true,  true);
+    iNumErr += EqnTest(_T("a>=b"), false, true);
+    // The following equations were raising type conflict errors once
+    // since the result of sqrt(1) is 1 which is an integer as fas as muParserX
+    // is concerned:
+    iNumErr += EqnTest(_T("sqrt(a)<sin(8)"), false, true);
+    iNumErr += EqnTest(_T("sqrt(a)<=sin(8)"), false, true);
+    iNumErr += EqnTest(_T("sqrt(a)>sin(8)"), true, true);
+    iNumErr += EqnTest(_T("sqrt(a)>=sin(8)"), true, true);
+    iNumErr += EqnTest(_T("sqrt(a)==sin(8)"), false, true);
+    iNumErr += EqnTest(_T("sqrt(a)!=sin(8)"), true, true);
+    iNumErr += EqnTest(_T("sqrt(a)+1.01"), 2.01, true);
+    iNumErr += EqnTest(_T("sqrt(a)-1.01"), -0.01, true);
+
+    // interaction with sign operator
+    iNumErr += EqnTest( _T("3-(-a)"), 4, true);
+    iNumErr += EqnTest( _T("3--a"), 4,   true);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestMultiLine()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing multiline expressions...");
+
+    // Test error detection
+    iNumErr += ThrowTest(_T("sin(\n"), ecUNEXPECTED_NEWLINE);
+    iNumErr += ThrowTest(_T("1+\n"), ecUNEXPECTED_NEWLINE);
+    iNumErr += ThrowTest(_T("a,\n"), ecUNEXPECTED_NEWLINE);
+    iNumErr += ThrowTest(_T("a*\n"), ecUNEXPECTED_NEWLINE);
+    iNumErr += ThrowTest(_T("va[\n"), ecUNEXPECTED_NEWLINE);
+    iNumErr += ThrowTest(_T("(true) ? \n"), ecUNEXPECTED_NEWLINE);
+    iNumErr += ThrowTest(_T("(true) ? 10:\n"), ecUNEXPECTED_NEWLINE);
+
+    // Expressions spanning multiple lines
+    iNumErr += EqnTest(_T("a=1\n")
+                       _T("b=2\n") 
+                       _T("c=3\n") 
+                       _T("a+b+c") , 6, true);
+    iNumErr += EqnTest(_T("a=1,b=2\n") 
+                       _T("c=a+b\n") 
+                       _T("a+b+c") , 6, true);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestIfElse()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing if-else conditional...");
+
+    // Test error detection
+    iNumErr += ThrowTest(_T(": 2"), ecUNEXPECTED_CONDITIONAL);     
+    iNumErr += ThrowTest(_T("? 1 : 2"), ecUNEXPECTED_CONDITIONAL); 
+    iNumErr += ThrowTest(_T("(a<b) ? (b<c) ? 1 : 2"), ecMISSING_ELSE_CLAUSE); 
+    iNumErr += ThrowTest(_T("(a<b) ? 1"), ecMISSING_ELSE_CLAUSE); 
+    iNumErr += ThrowTest(_T("(a<b) ? a"), ecMISSING_ELSE_CLAUSE); 
+    iNumErr += ThrowTest(_T("(a<b) ? a+b"), ecMISSING_ELSE_CLAUSE); 
+    iNumErr += ThrowTest(_T("a : b"), ecMISPLACED_COLON, 2); 
+    iNumErr += ThrowTest(_T("1 : 2"), ecMISPLACED_COLON, 2); 
+    iNumErr += ThrowTest(_T("(true) ? 1 : 2 : 3"), ecMISPLACED_COLON); 
+    iNumErr += EqnTest(_T("true ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("1<2 ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("a<b ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("((a>b) ? true : false) ? 1 : 2"), 2, true);
+    iNumErr += EqnTest(_T("((a>b) ? true : false) ? 1 : sum((a>b) ? 1 : 2)"), 2, true);
+    iNumErr += EqnTest(_T("((a>b) ? false : true) ? 1 : sum((a>b) ? 1 : 2)"), 1, true);
+    iNumErr += EqnTest(_T("(true) ? 10 : 11"), 10, true);
+    iNumErr += EqnTest(_T("(true) ? a+b : c+d"), 3, true);
+    iNumErr += EqnTest(_T("(true) ? false : true"), false, true);
+    iNumErr += EqnTest(_T("(false) ? 10 : 11"), 11, true);
+    iNumErr += EqnTest(_T("(false) ? a+b : c+d"), 1, true);
+    iNumErr += EqnTest(_T("(false) ? false : true"), true, true);
+    iNumErr += EqnTest(_T("(a<b) ? 10 : 11"), 10, true);
+    iNumErr += EqnTest(_T("(a>b) ? 10 : 11"), 11, true);
+    iNumErr += EqnTest(_T("(a<b) ? c : d"), 3, true);
+    iNumErr += EqnTest(_T("(a>b) ? c : d"), -2, true);
+    iNumErr += EqnTest(_T("(a>b) ? true : false"), false, true);
+
+    // With multiarg functions
+    iNumErr += EqnTest(_T("sum((a>b) ? 1 : 2)"), 2, true);
+    iNumErr += EqnTest(_T("sum((a>b) ? 1 : 2, 100)"), 102, true);
+    iNumErr += EqnTest(_T("sum((true) ? 1 : 2)"), 1, true);
+    iNumErr += EqnTest(_T("sum((true) ? 1 : 2, 100)"), 101, true);
+    iNumErr += EqnTest(_T("sum(3, (a>b) ? 3 : 10)"), 13, true);
+    iNumErr += EqnTest(_T("sum(3, (a<b) ? 3 : 10)"), 6, true);
+    iNumErr += EqnTest(_T("sum(3, (a>b) ? 3 : 10)*10"), 130, true);
+    iNumErr += EqnTest(_T("sum(3, (a<b) ? 3 : 10)*10"), 60, true);
+    iNumErr += EqnTest(_T("10*sum(3, (a>b) ? 3 : 10)"), 130, true);
+    iNumErr += EqnTest(_T("10*sum(3, (a<b) ? 3 : 10)"), 60, true);
+    iNumErr += EqnTest(_T("(a<b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 60, true);
+    iNumErr += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 99, true);
+    iNumErr += EqnTest(_T("(a<b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 360, true);
+    iNumErr += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 99, true);
+    iNumErr += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : sum(3, (a<b) ? 3 : 10)*10"), 60, true);
+
+    iNumErr += EqnTest(_T("(a<b)&&(a<b) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("(a>b)&&(a<b) ? 128 : 255"), 255, true);
+    iNumErr += EqnTest(_T("(1<2)&&(1<2) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("(1>2)&&(1<2) ? 128 : 255"), 255, true);
+    iNumErr += EqnTest(_T("((1<2)&&(1<2)) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("((1>2)&&(1<2)) ? 128 : 255"), 255, true);
+    iNumErr += EqnTest(_T("((a<b)&&(a<b)) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("((a>b)&&(a<b)) ? 128 : 255"), 255, true);
+
+    // nested conditionals with brackets
+    iNumErr += EqnTest(_T("(a<b) ? ((b<c) ? 2*(a+b) : 2) : 3"), 6, true);
+    iNumErr += EqnTest(_T("(a<b) ? 3 : ((b<c) ? 2*(a+b) : 2)"), 3, true);
+    iNumErr += EqnTest(_T("(a<b) ? ((b>c) ? 1 : 2) : 3"), 2, true);
+    iNumErr += EqnTest(_T("(a>b) ? ((b<c) ? 1 : 2) : 3"), 3, true);
+    iNumErr += EqnTest(_T("(a>b) ? ((b>c) ? 1 : 2) : 3"), 3, true);
+
+    // nested conditionals without brackets
+    iNumErr += EqnTest(_T("(a<b) ? (b<c) ? 1 : 2 : 3"), 1, true);
+    iNumErr += EqnTest(_T("(a<b) ? (b>c) ? 1 : 2 : 3"), 2, true);
+    iNumErr += EqnTest(_T("(a>b) ? (b<c) ? 1 : 2 : 3"), 3, true);
+    iNumErr += EqnTest(_T("(a>b) ? (b>c) ? 1 : 2 : 3"), 3, true);
+
+    // Neue Tests
+    iNumErr += EqnTest(_T("(a<b)&&(a<b) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("(a>b)&&(a<b) ? 128 : 255"), 255, true);
+    iNumErr += EqnTest(_T("(1<2)&&(1<2) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("(1>2)&&(1<2) ? 128 : 255"), 255, true);
+    iNumErr += EqnTest(_T("((1<2)&&(1<2)) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("((1>2)&&(1<2)) ? 128 : 255"), 255, true);
+    iNumErr += EqnTest(_T("((a<b)&&(a<b)) ? 128 : 255"), 128, true);
+    iNumErr += EqnTest(_T("((a>b)&&(a<b)) ? 128 : 255"), 255, true);
+
+    iNumErr += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255, true);
+    iNumErr += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255, true);
+    iNumErr += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128, true);
+    iNumErr += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128, true);
+    iNumErr += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32, true);
+    iNumErr += EqnTest(_T("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64, true);
+    iNumErr += EqnTest(_T("1>0 ? 50 :  1>0 ? 128 : 255"), 50, true);
+    iNumErr += EqnTest(_T("1>0 ? 50 : (1>0 ? 128 : 255)"), 50, true);
+    iNumErr += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 50"), 128, true);
+    iNumErr += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32, true);
+    iNumErr += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32, true);
+    iNumErr += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :  1>0 ? 32 :1>2 ? 64 : 16"), 255, true);
+    iNumErr += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255, true);
+    iNumErr += EqnTest(_T("true ? false ? 128 : 255 : true ? 32 : 64"), 255, true);
+
+    // assignment operators
+    iNumErr += EqnTest(_T("a= false ? 128 : 255, a"), 255, true);
+    iNumErr += EqnTest(_T("a=((a>b)&&(a<b)) ? 128 : 255, a"), 255, true);
+    iNumErr += EqnTest(_T("c=(a<b)&&(a<b) ? 128 : 255, c"), 128, true);
+    iNumErr += EqnTest(_T("false ? a=a+1 : 666, a"), 1, true);
+    iNumErr += EqnTest(_T("true?a=10:a=20, a"), 10, true);
+    iNumErr += EqnTest(_T("false?a=10:a=20, a"), 20, true);
+    iNumErr += EqnTest(_T("false?a=sum(3,4):10, a"), 1, true);  // a should not change its value due to lazy calculation
+
+    iNumErr += EqnTest(_T("a=true?b=true?3:4:5, a"), 3, true);
+    iNumErr += EqnTest(_T("a=true?b=true?3:4:5, b"), 3, true);
+    iNumErr += EqnTest(_T("a=false?b=true?3:4:5, a"), 5, true);
+    iNumErr += EqnTest(_T("a=false?b=true?3:4:5, b"), 2, true);
+
+    iNumErr += EqnTest(_T("a=true?5:b=true?3:4, a"), 5, true);
+    iNumErr += EqnTest(_T("a=true?5:b=true?3:4, b"), 2, true);
+    iNumErr += EqnTest(_T("a=false?5:b=true?3:4, a"), 3, true);
+    iNumErr += EqnTest(_T("a=false?5:b=true?3:4, b"), 3, true);
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestEqn()
+  {
+    int  iNumErr = 0;
+    *m_stream << _T("testing sample equations...");
+
+    iNumErr += EqnTest(_T("-2--8"), (float_type)6.0, true);
+    iNumErr += EqnTest(_T("2*(a=9)*3"), 54, true);
+
+    // Functions
+    iNumErr += EqnTest(_T("10*strlen(toupper(\"12345\"))"), 50, true);
+
+    // hex value recognition
+    iNumErr += EqnTest(_T("0xff"), 255, true);
+    iNumErr += EqnTest(_T("10+0xff"), 265, true);
+    iNumErr += EqnTest(_T("0xff+10"), 265, true);
+    iNumErr += EqnTest(_T("10*0xff"), 2550, true);
+    iNumErr += EqnTest(_T("0xff*10"), 2550, true);
+    iNumErr += EqnTest(_T("10+0xff+1"), 266, true);
+    iNumErr += EqnTest(_T("1+0xff+10"), 266, true);
+
+    // ...
+    iNumErr += EqnTest(_T("exp(ln(7))"), (float_type)7.0, true);
+    iNumErr += EqnTest(_T("e^ln(7)"), (float_type)7.0, true);
+    iNumErr += EqnTest(_T("e^(ln(7))"), (float_type)7.0, true);
+    iNumErr += EqnTest(_T("(e^(ln(7)))"), (float_type)7.0, true);
+    iNumErr += EqnTest(_T("1-(e^(ln(7)))"), (float_type)-6.0, true);
+    iNumErr += EqnTest(_T("2*(e^(ln(7)))"), (float_type)14.0, true);
+    iNumErr += EqnTest(_T("10^log(5)"), (float_type)5.0, true);
+    iNumErr += EqnTest(_T("10^log10(5)"), (float_type)5.0, true);
+    iNumErr += EqnTest(_T("2^log2(4)"), (float_type)4.0, true);
+    iNumErr += EqnTest(_T("-(sin(0)+1)"), (float_type)-1.0, true);
+    iNumErr += EqnTest(_T("-(2^1.1)"), (float_type)-2.14354692, true);
+
+    // infix + postfix operator in arguments for binary operators (Reference: Matlab)
+    iNumErr += EqnTest(_T("-sin(8){m}*6"), (float_type)-0.00593615, true);
+    iNumErr += EqnTest(_T("-sin(8){m}/6"), (float_type)-1.6489e-4, true);
+    iNumErr += EqnTest(_T("-sin(8){m}+6"), (float_type)5.99901, true);
+    iNumErr += EqnTest(_T("-sin(8){m}-6"), (float_type)-6.000989, true);
+
+    iNumErr += EqnTest(_T("(cos(2.41)/b)"), (float_type)-0.372056, true);
+
+    // long formula (Reference: Matlab)
+    iNumErr += EqnTest(
+      _T("(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))")
+      _T("/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/")
+      _T("((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-")
+      _T("e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6")
+      _T("+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e")
+      _T("*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), (float_type)-12.23016549, true);
+
+    // long formula (Reference: Matlab)
+    iNumErr += EqnTest(_T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), (float_type)-7995810.09926, true);
+
+    /* <ibg 20100321 atan currently unsupported/>
+
+    // long formula (Reference: Matlab)
+    iNumErr += EqnTest(
+      "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e"
+      ")+a)))*2.77)", -2.16995656, true);
+    */
+
+    Assessment(iNumErr);
+    return iNumErr;
+  }
+
+
+  //---------------------------------------------------------------------------
+  int ParserTester::TestNames()
+  {
+    int  iStat= 0;
+
+    *m_stream << "testing name restriction enforcement...";
+    
+    ParserX p;
+
+#define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
+    iErr = 0;                                    \
+    ParserTester::c_iCount++;                    \
+    try                                          \
+    {                                            \
+      p.Define##DOMAIN(EXPR, ARG);               \
+    }                                            \
+    catch(Parser::exception_type&)               \
+    {                                            \
+      iErr = (FAIL==false) ? 0 : 1;              \
+    }                                            \
+    iStat += iErr;      
+    
+    // constant names
+//      PARSER_THROWCHECK(Const, false, "0a", 1)
+//      PARSER_THROWCHECK(Const, false, "9a", 1)
+//      PARSER_THROWCHECK(Const, false, "+a", 1)
+//      PARSER_THROWCHECK(Const, false, "-a", 1)
+//      PARSER_THROWCHECK(Const, false, "a-", 1)
+//      PARSER_THROWCHECK(Const, false, "a*", 1)
+//      PARSER_THROWCHECK(Const, false, "a?", 1)
+//      PARSER_THROWCHECK(Const, false, "a?", 1)
+//      PARSER_THROWCHECK(Const, false, "a?", 1)
+//      PARSER_THROWCHECK(Const, true, "a", 1)
+//      PARSER_THROWCHECK(Const, true, "a_min", 1)
+//      PARSER_THROWCHECK(Const, true, "a_min0", 1)
+//      PARSER_THROWCHECK(Const, true, "a_min9", 1)
+//      // variable names
+//      Parser::value_type a;
+//      p.ClearConst();
+//      PARSER_THROWCHECK(Var, false, "9a", &a)
+//      PARSER_THROWCHECK(Var, false, "0a", &a)
+//      PARSER_THROWCHECK(Var, false, "+a", &a)
+//      PARSER_THROWCHECK(Var, false, "-a", &a)
+//      PARSER_THROWCHECK(Var, false, "?a", &a)
+//      PARSER_THROWCHECK(Var, false, "!a", &a)
+//      PARSER_THROWCHECK(Var, false, "a+", &a)
+//      PARSER_THROWCHECK(Var, false, "a-", &a)
+//      PARSER_THROWCHECK(Var, false, "a*", &a)
+//      PARSER_THROWCHECK(Var, false, "a?", &a)
+//      PARSER_THROWCHECK(Var, true, "a", &a)
+//      PARSER_THROWCHECK(Var, true, "a_min", &a)
+//      PARSER_THROWCHECK(Var, true, "a_min0", &a)
+//      PARSER_THROWCHECK(Var, true, "a_min9", &a)
+//      PARSER_THROWCHECK(Var, false, "a_min9", 0)
+//      // Postfix operators
+//      // fail
+//      PARSER_THROWCHECK(PostfixOprt, false, "(k", f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, false, "9+", f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, false, "+", 0)
+//      // pass
+//      PARSER_THROWCHECK(PostfixOprt, true, "-a",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "?a",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "_",   f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "#",   f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "&&",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "||",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "&",   f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "|",   f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "++",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "--",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "?>",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "?<",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "**",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "xor", f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "and", f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "or",  f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "not", f1of1)
+//      PARSER_THROWCHECK(PostfixOprt, true, "!",   f1of1)
+//      // Binary operator
+//      // The following must fail with builtin operators activated
+//      // p.EnableBuiltInOp(true); -> this is the default
+//      PARSER_THROWCHECK(Oprt, false, "+",  f1of2)
+//      PARSER_THROWCHECK(Oprt, false, "-",  f1of2)
+//      PARSER_THROWCHECK(Oprt, false, "*",  f1of2)
+//      PARSER_THROWCHECK(Oprt, false, "/",  f1of2)
+//      // without activated built in operators it should work
+//      p.EnableBuiltInOprt(false);
+//      PARSER_THROWCHECK(Oprt, true, "+",  f1of2)
+//      PARSER_THROWCHECK(Oprt, true, "-",  f1of2)
+//      PARSER_THROWCHECK(Oprt, true, "*",  f1of2)
+//      PARSER_THROWCHECK(Oprt, true, "/",  f1of2)
+//
+#undef PARSER_THROWCHECK
+
+    if (iStat==0) 
+      *m_stream << "passed" << endl;
+    else 
+      *m_stream << "\n  failed with " << iStat << " errors" << endl;
+
+    return iStat;
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTester::AddTest(testfun_type a_pFun)
+  {
+    m_vTestFun.push_back(a_pFun);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTester::Run()
+  {
+    int iStat = 0;
+    try
+    {
+      for (int i=0; i<(int)m_vTestFun.size(); ++i)
+        iStat += (this->*m_vTestFun[i])();
+    }
+    catch(ParserError &e)
+    {
+      *m_stream << e.GetMsg() << endl;
+      *m_stream << e.GetToken() << endl;
+      Abort();
+    }
+    catch(std::exception &e)
+    {
+      *m_stream << e.what() << endl;
+      Abort();
+    }
+    catch(...)
+    {
+      *m_stream << _T("Internal error");
+      Abort();
+    }
+
+    if (iStat==0) 
+    {
+      *m_stream << _T("Test passed (") <<  ParserTester::c_iCount << _T(" expressions)") << endl;
+    }
+    else 
+    {
+      *m_stream << _T("Test failed with ") << iStat 
+                << _T(" errors (") <<  ParserTester::c_iCount 
+                << _T(" expressions)") << endl;
+    }
+    ParserTester::c_iCount = 0;
+
+#ifdef MUP_LEAKAGE_REPORT
+    // All tokens must have been destroyed by now, verify this
+    IToken::LeakageReport();  
+#endif
+  }
+
+
+  //---------------------------------------------------------------------------
+  int ParserTester::ThrowTest(const string_type &a_sExpr, int a_nErrc, int a_nPos)
+  {
+    bool a_bFail = true;
+    ParserTester::c_iCount++;
+    
+    try
+    {
+      ParserX p;
+
+      // Add variables
+      Value vVarVal[] = { 1, 2, 3, -2};
+      p.DefineVar( _T("a"), Variable(&vVarVal[0]) );
+      p.DefineVar( _T("b"), Variable(&vVarVal[1]) );
+      p.DefineVar( _T("c"), Variable(&vVarVal[2]) );
+      p.DefineVar( _T("d"), Variable(&vVarVal[3]) );
+
+      // array variables
+      Value aVal1(3, 0);
+      aVal1.At(0) = (float_type)1.0;
+      aVal1.At(1) = (float_type)2.0;
+      aVal1.At(2) = (float_type)3.0;
+  
+      Value aVal2(3, 0);
+      aVal2.At(0) = (float_type)4.0;
+      aVal2.At(1) = (float_type)3.0;
+      aVal2.At(2) = (float_type)2.0;
+
+      Value aVal3(4, 0);
+      aVal3.At(0) = (float_type)4.0;
+      aVal3.At(1) = (float_type)3.0;
+      aVal3.At(2) = (float_type)2.0;
+      aVal3.At(3) = (float_type)5.0;
+
+      Value aVal4(4, 0);
+      aVal4.At(0) = (float_type)4.0;
+      aVal4.At(1) = false;
+      aVal4.At(2) = _T("hallo");
+
+      // Matrix variables
+      Value m1(3, 3, 0);
+      m1.At(0, 0) = 1;
+      m1.At(1, 1) = 1;
+      m1.At(2, 2) = 1;
+
+      Value m2(3, 3, 0);
+      m2.At(0, 0) = 1;  m2.At(0, 1) = 2;  m2.At(0, 2) = 3;
+      m2.At(1, 0) = 4;  m2.At(1, 1) = 5;  m2.At(1, 2) = 6;
+      m2.At(2, 0) = 7;  m2.At(2, 1) = 8;  m2.At(2, 2) = 9;
+
+      p.DefineVar(_T("m1"), Variable(&m1));
+      p.DefineVar(_T("m2"), Variable(&m2));
+      p.DefineVar(_T("va"), Variable(&aVal1));
+      p.DefineVar(_T("vb"), Variable(&aVal2)); 
+      p.DefineVar(_T("vc"), Variable(&aVal3)); 
+      p.DefineVar(_T("vd"), Variable(&aVal4)); 
+
+      p.SetExpr(a_sExpr);
+      Value fRes = p.Eval();
+    }
+    catch(ParserError &e)
+    {
+      // output the formula in case of an failed test
+      if (a_nErrc!=e.GetCode() )
+      {
+        *m_stream << _T("\n  ") 
+                  << _T("Expression: \"") << a_sExpr 
+                  << _T("\"  Code:")      << e.GetCode() 
+                  << _T("  Expected:")  << a_nErrc;
+      }
+      
+      // Check whether the error is reported at the correct expression position
+      if (a_nPos!=-1 && a_nPos!=e.GetPos())
+      {
+        *m_stream << _T("\n  ") 
+                  << _T("Invalid error position: \"") << a_sExpr 
+                  << _T("\"  Pos:")  << e.GetPos()
+                  << _T("  Expected:")  << a_nPos;
+      }
+
+      return (a_nErrc==e.GetCode() && (a_nPos==-1 || a_nPos==e.GetPos()) ) ? 0 : 1;
+    }
+
+    *m_stream << _T("\n  ") 
+              << _T("Expression failed: \"") 
+              << a_sExpr 
+              << _T("\"  (no exception raised).");
+
+    return 1; 
+  }
+
+  //---------------------------------------------------------------------------
+  int ParserTester::EqnTest(const string_type &a_str, Value a_val, bool a_fPass, int nExprVar)
+  {
+    ParserTester::c_iCount++;
+    int iRet(1);
+    Value fVal[5];
+
+    try
+    {
+      // p1 is a pointer since I'm going to delete it in order to test if
+      // parsers after copy construction still refer to members of the deleted object.
+      // !! If this is the case this function will crash !!
+      std::auto_ptr<ParserX> p1(new ParserX()); 
+
+      // Add variables
+      Value vVarVal[] = { 1, 2, 3, -2, -1};
+
+      // m1 ist die Einheitsmatrix
+      Value m1(3, 3, 0);
+      m1.At(0, 0) = 1;
+      m1.At(1, 1) = 1;
+      m1.At(2, 2) = 1;
+
+      // m2 ist die Einheitsmatrix
+      Value m2(3, 3, 0);
+      m2.At(0, 0) = 1;  m2.At(0, 1) = 2;  m2.At(0, 2) = 3;
+      m2.At(1, 0) = 4;  m2.At(1, 1) = 5;  m2.At(1, 2) = 6;
+      m2.At(2, 0) = 7;  m2.At(2, 1) = 8;  m2.At(2, 2) = 9;
+
+      p1->DefineOprt(new DbgSillyAdd);
+      p1->DefineFun(new FunTest0);
+
+      p1->DefineVar( _T("a"),  Variable(&vVarVal[0]) );
+      p1->DefineVar( _T("b"),  Variable(&vVarVal[1]) );
+      p1->DefineVar( _T("c"),  Variable(&vVarVal[2]) );
+      p1->DefineVar( _T("d"),  Variable(&vVarVal[3]) );
+      p1->DefineVar( _T("f"),  Variable(&vVarVal[4]) );
+      p1->DefineVar( _T("m1"), Variable(&m1) );
+      p1->DefineVar( _T("m2"), Variable(&m2) );
+
+      // Add constants
+      p1->DefineConst(_T("pi"), (float_type)MUP_CONST_PI);
+      p1->DefineConst(_T("e"),  (float_type)MUP_CONST_E);
+      p1->DefineConst(_T("const"),  1);
+      p1->DefineConst(_T("const1"), 2);
+      p1->DefineConst(_T("const2"), 3);
+
+      // some vector variables
+      Value aVal1(3, 0);
+      aVal1.At(0) = (float_type)1.0;
+      aVal1.At(1) = (float_type)2.0;
+      aVal1.At(2) = (float_type)3.0;
+      
+      Value aVal2(3, 0);
+      aVal2.At(0) = (float_type)4.0;
+      aVal2.At(1) = (float_type)3.0;
+      aVal2.At(2) = (float_type)2.0;
+      p1->DefineVar(_T("va"), Variable(&aVal1));
+      p1->DefineVar(_T("vb"), Variable(&aVal2)); 
+
+      // complex variables
+      Value cVal[3];
+      cVal[0] = mup::cmplx_type(1, 1);
+      cVal[1] = mup::cmplx_type(2, 3);
+      cVal[2] = mup::cmplx_type(3, 4);
+      p1->DefineVar(_T("ca"), Variable(&cVal[0]));
+      p1->DefineVar(_T("cb"), Variable(&cVal[1])); 
+      p1->DefineVar(_T("cc"), Variable(&cVal[2])); 
+
+      p1->SetExpr(a_str);
+      
+      fVal[0] = p1->Eval();
+
+      // Test copy and assignement operators
+      std::vector<ParserX> vParser;
+      vParser.push_back(*p1);   // Push p1 into the vector
+      ParserX p2 = vParser[0];   // take parser from vector
+      
+      // destroy the originals from p2
+      vParser.clear();              // delete the vector
+      p1.reset(0);                  // delete the original
+
+      fVal[1] = p2.Eval();          // If copy constructions does not work
+                                    // we may see a crash here
+
+      // Test assignement operator
+      // additionally  disable Optimizer this time
+      ParserX p3;
+      p3 = p2;
+      fVal[2] = p3.Eval();          // If assignment does not work
+                                    // we may see a crash here
+
+      // Calculating a second time will parse from rpn rather than from
+      // string. The result must be the same...
+      fVal[3] = p3.Eval();
+
+      // Calculate yet another time. There is the possibility of
+      // changing variables as a side effect of expression
+      // evaluation. So there are really bugs that could make this fail...
+      fVal[4] = p3.Eval(); 
+
+      // Check i number of used variables is correct
+      if (nExprVar!=-1)
+      {
+        int n2 = p2.GetExprVar().size();
+        int n3 = p3.GetExprVar().size();
+
+        if (n2+n3!=2*n2 || n2!=nExprVar)       
+        {
+          *m_stream << _T("  Number of expression variables is incorrect. (expected: ") 
+                    << nExprVar << _T("; detected: ") << n2 << _T(")");
+        }
+      }
+
+      // Check the three results
+      // 1.) Types must be identic
+      bool bStat = fVal[0].GetType()==fVal[1].GetType() &&
+                   fVal[0].GetType()==fVal[2].GetType() &&
+                   fVal[0].GetType()==fVal[3].GetType() &&
+                   fVal[0].GetType()==fVal[4].GetType();
+      char_type cType = fVal[1].GetType();
+      if (!bStat) 
+      {
+       *m_stream << _T("\n  ") << a_str << _T(" :  inconsistent result type (") 
+                 << fVal[0].GetType() << _T(", ") 
+                 << fVal[1].GetType() << _T(", ") 
+                 << fVal[2].GetType() << _T(", ") 
+                 << fVal[3].GetType() << _T(", ") 
+                 << fVal[4].GetType() << _T(")");
+        return 1;
+      }
+
+      // Compare the results
+      switch(cType)
+      {
+      case  'i': 
+      case  'b': 
+      case  's': bStat = (a_val==fVal[0] && 
+                          a_val==fVal[1] && 
+                          a_val==fVal[2] && 
+                          a_val==fVal[3] && 
+                          a_val==fVal[4]); 
+                 break;
+
+      // We need more attention for comaring float values due to floating point
+      // inaccuracies.
+      case  'f': 
+            {
+              bStat = true;
+  	          int num = sizeof(fVal)/sizeof(Value);
+              for (int i=0; i<num; ++i)
+	              bStat &= (fabs(a_val.GetFloat()-fVal[i].GetFloat()) <= fabs(fVal[i].GetFloat()*0.0001));
+            }
+            break;
+
+      case 'c':
+            {
+              bStat = true;
+  	          int num = sizeof(fVal)/sizeof(Value);
+              for (int i=0; i<num; ++i)
+              {
+                bStat &= (fabs(a_val.GetFloat()- fVal[i].GetFloat()) <= std::max((float_type)1e-15, fabs(fVal[i].GetFloat() * (float_type)0.0000001)));
+                bStat &= (fabs(a_val.GetImag() - fVal[i].GetImag())  <= std::max((float_type)1e-15, fabs(fVal[i].GetImag()  * (float_type)0.0000001)));
+              }
+            }
+            break;
+
+      case 'm':
+            {
+              bStat = true;
+  	          int num = sizeof(fVal)/sizeof(Value);
+
+              for (int i=0; i<num; ++i)
+              {
+                struct CheckArray
+                {
+                  CheckArray()
+                  {}
+
+                  bool Check(IValue &v1, IValue &v2)
+                  {
+                    if (v1.GetType()!=v2.GetType())
+                      return false;
+                    
+                    if (v1.GetRows()!=v2.GetRows())
+                      return false;
+
+                    if (v1.IsMatrix())
+                    {
+
+                      bool bCheck = true;
+                      for (int i=0; i<v1.GetRows(); ++i)
+                      {
+                        if (!Check(v1.At(i), v2.At(i)))
+                          return false;
+                      }
+
+                      return true;
+                    }
+                    else
+                    {
+                      return (fabs(v1.GetFloat()- v2.GetFloat()) <= std::max((float_type)1e-15, fabs(v1.GetFloat() * (float_type)0.0000001)));
+                    }
+                  }
+                } checker;
+                
+                bStat = checker.Check(a_val, fVal[i]);
+                if (!bStat)
+                  break;
+              }
+            }
+            break;
+
+      default: 
+            throw std::runtime_error("Parser return value has an unexpected typecode.");
+      }
+
+      iRet = (bStat==a_fPass) ? 0 : 1;
+   }
+   catch(ParserError &e)
+   {
+     *m_stream << _T("\n  ") << a_str << _T(" : ") << e.GetMsg();	
+     return 1;
+   }
+   catch(std::exception &e)
+   {
+     *m_stream << _T("\n  ") << a_str << _T(" : ") << e.what() << _T("\n");
+     return 1;
+   }
+   catch(...)
+   {
+     *m_stream << _T("\n  \"") << a_str << _T("\" : ") << _T("Unexpected Eception");
+     return 1;
+   }
+
+   if (iRet)
+   {
+     *m_stream << _T("\n  ") << a_str << _T(" : ") << _T("(at least one incorrect result ") 
+               << fVal[0] << _T(", ") 
+               << fVal[1] << _T(", ") 
+               << fVal[2] << _T(", ") 
+               << fVal[3] << _T(", ") 
+               << fVal[4] << _T("; expected=") << a_val << _T(")");	
+   }
+
+    return iRet; 
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Internal error in test class Test is going to be aborted. */
+  void ParserTester::Abort() const
+  {
+    *m_stream << _T("\nTest failed (internal error in test class)") << endl;
+    while (!getchar());
+    exit(-1);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTester::Assessment(int a_iNumErr) const
+  {
+    if (a_iNumErr==0) 
+      *m_stream << _T("passed") << endl;
+    else 
+      *m_stream << _T("\n  failed with ") << a_iNumErr << _T(" errors") << endl;
+  }
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpTest.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpTest.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,101 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2011 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MU_PARSER_TEST_H
+#define MU_PARSER_TEST_H
+
+#include <string>
+#include <numeric> // for accumulate
+#include "mpParser.h"
+#include "mpOprtBinCommon.h"
+
+
+MUP_NAMESPACE_START
+
+MUP_BINARY_OPERATOR(DbgSillyAdd, _T("++"), float_type, _T(""), 3, oaLEFT, a+b)
+
+    /** \brief Test cases for unit testing the parser framework.
+
+      (C) 2011 Ingo Berg
+    */
+    class ParserTester // final
+    {
+    private:
+        static int c_iCount;
+
+        int TestParserValue();
+        int TestNames();
+        int TestErrorCodes();
+        int TestStringFun();
+        int TestVector();
+        int TestBinOp();
+        int TestPostfix();
+        int TestInfix();
+        int TestEqn();
+        int TestMultiArg();
+        int TestUndefVar();
+        int TestIfElse();
+        int TestMultiLine();
+        int TestMatrix();
+        int TestComplex();
+
+        void Assessment(int a_iNumErr) const;
+        void Abort() const;
+
+    public:
+        typedef int (ParserTester::*testfun_type)();
+
+	      ParserTester();
+
+        /** \brief Destructor (trivial). */
+       ~ParserTester() {};
+      	
+        /** \brief Copy constructor is deactivated. */
+        ParserTester(const ParserTester &a_Obj)
+          :m_vTestFun()
+          ,m_stream(a_Obj.m_stream)
+        {};
+
+	      void Run();
+
+    private:
+        std::vector<testfun_type> m_vTestFun;
+
+#if defined(_UNICODE)
+        std::wostream *m_stream;
+#else
+        std::ostream *m_stream;
+#endif
+
+	      void AddTest(testfun_type a_pFun);
+
+        // Test Double Parser
+        int EqnTest(const string_type &a_str, Value a_val, bool a_fPass, int nExprVar = -1);
+        int ThrowTest(const string_type &a_str, int a_nErrc, int a_nPos = -1);
+    }; // ParserTester
+}  // namespace mu
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpTokenReader.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpTokenReader.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,944 @@
+/** \file
+    \brief Implementation of the token reader used to break the expression string up 
+           into tokens.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2011 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+
+#include "mpTokenReader.h"
+
+#include <cassert>
+
+#include "mpParserBase.h"
+#include "mpIValReader.h"
+#include "mpIfThenElse.h"
+#include "mpScriptTokens.h"
+#include "mpOprtIndex.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor.
+      \sa Assign
+      \throw nothrow
+  */
+  TokenReader::TokenReader(const TokenReader &a_Reader) 
+  { 
+    Assign(a_Reader);
+  }
+    
+  //---------------------------------------------------------------------------
+  /** \brief Assignement operator.
+      \param a_Reader Object to copy to this token reader.
+      \throw nothrow
+    
+      Self assignement will be suppressed otherwise #Assign is called.
+  */
+  TokenReader& TokenReader::operator=(const TokenReader &a_Reader) 
+  {
+    if (&a_Reader!=this)
+      Assign(a_Reader);
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assign state of a token reader to this token reader. 
+      \param a_Reader Object from which the state should be copied.
+      \throw nothrow
+  */
+  void TokenReader::Assign(const TokenReader &obj)
+  {
+    m_pParser             = obj.m_pParser;
+    m_sExpr               = obj.m_sExpr;
+    m_nPos                = obj.m_nPos;
+    m_nNumBra             = obj.m_nNumBra;
+    m_nNumIndex           = obj.m_nNumIndex;
+    m_nNumIfElse          = obj.m_nNumIfElse;
+    m_nSynFlags           = obj.m_nSynFlags;
+    m_UsedVar             = obj.m_UsedVar;
+    m_pVarDef             = obj.m_pVarDef;
+    m_pPostOprtDef        = obj.m_pPostOprtDef;
+    m_pInfixOprtDef       = obj.m_pInfixOprtDef;
+    m_pOprtDef            = obj.m_pOprtDef;
+    m_pFunDef             = obj.m_pFunDef;
+    m_pConstDef           = obj.m_pConstDef;
+    m_pDynVarShadowValues = obj.m_pDynVarShadowValues;
+    m_vTokens             = obj.m_vTokens;
+
+    // Reader klassen klonen 
+    DeleteValReader();
+    std::size_t i, iSize = obj.m_vValueReader.size();
+    for (i=0; i<iSize; ++i)
+    {
+      m_vValueReader.push_back(obj.m_vValueReader[i]->Clone(this));
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Constructor. 
+        
+      Create a Token reader and bind it to a parser object. 
+
+      \pre [assert] a_pParser may not be NULL
+      \post #m_pParser==a_pParser
+      \param a_pParent Parent parser object of the token reader.
+  */
+  TokenReader::TokenReader(ParserXBase *a_pParent)
+    :m_pParser(a_pParent)
+    ,m_sExpr()
+    ,m_nPos(0)
+    ,m_nNumBra(0)
+    ,m_nNumIndex(0)
+    ,m_nNumIfElse(0)
+    ,m_nSynFlags(0)
+    ,m_vTokens()
+    ,m_eLastTokCode(cmUNKNOWN)
+    ,m_pFunDef(NULL)
+    ,m_pOprtDef(NULL)
+    ,m_pInfixOprtDef(NULL)
+    ,m_pPostOprtDef(NULL)
+    ,m_pConstDef(NULL)
+    ,m_pDynVarShadowValues(NULL)
+    ,m_pVarDef(NULL)
+    ,m_vValueReader()
+    ,m_UsedVar()
+    ,m_fZero(0)
+  {
+    assert(m_pParser);
+    SetParent(m_pParser);
+  }
+    
+  //---------------------------------------------------------------------------
+  /** \brief Destructor (trivial).
+    
+      \throw nothrow
+  */
+  TokenReader::~TokenReader()
+  {
+    DeleteValReader();
+  }
+
+  //---------------------------------------------------------------------------
+  void TokenReader::DeleteValReader()
+  {
+    int iSize = (int)m_vValueReader.size();
+    for (int i=0; i<iSize; ++i)
+      delete m_vValueReader[i];
+    
+    m_vValueReader.clear();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Create instance of a ParserTokenReader identical with this 
+            and return its pointer. 
+
+      This is a factory method the calling function must take care of the object destruction.
+
+      \return A new ParserTokenReader object.
+      \throw nothrow
+  */
+  TokenReader* TokenReader::Clone(ParserXBase *a_pParent) const
+  {
+    std::auto_ptr<TokenReader> ptr(new TokenReader(*this));
+    ptr->SetParent(a_pParent);
+    return ptr.release();
+  }
+
+  //---------------------------------------------------------------------------
+  void TokenReader::AddValueReader(IValueReader *a_pReader)
+  {
+    a_pReader->SetParent(this);
+    m_vValueReader.push_back(a_pReader);
+  }
+
+  //---------------------------------------------------------------------------
+  void TokenReader::AddSynFlags(int flag)
+  {
+    m_nSynFlags |= flag;
+  }
+
+  //---------------------------------------------------------------------------
+  const TokenReader::token_buf_type& TokenReader::GetTokens() const
+  {
+    return m_vTokens;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the current position of the token reader in the formula string. 
+
+      \return #m_nPos
+      \throw nothrow
+  */
+  int TokenReader::GetPos() const
+  {
+    return m_nPos;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a reference to the formula. 
+
+      \return #m_sExpr
+      \throw nothrow
+  */
+  const string_type& TokenReader::GetExpr() const
+  {
+    return m_sExpr;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing the used variables only. */
+  const var_maptype& TokenReader::GetUsedVar() const
+  {
+    return m_UsedVar;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize the token Reader. 
+
+      Sets the expression position index to zero and set Syntax flags to 
+      default for initial parsing. 
+  */
+  void TokenReader::SetExpr(const string_type &a_sFormula)
+  {
+    m_sExpr = a_sFormula;
+    m_vTokens.clear();
+    ReInit();
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Reset the token reader to the start of the formula. 
+      \post #m_nPos==0, #m_nSynFlags = noOPT | noBC | noPOSTOP | noSTR
+      \throw nothrow
+      \sa ESynCodes
+
+      The syntax flags will be reset to a value appropriate for the 
+      start of a formula.
+  */
+  void TokenReader::ReInit()
+  {
+    m_nPos = 0;
+    m_nNumBra = 0;
+    m_nNumIndex = 0;
+    m_nNumIfElse = 0;
+    m_nSynFlags = noOPT | noBC | noPFX | noCOMMA | noIO | noIC | noIF | noELSE;
+    m_UsedVar.clear();
+    m_eLastTokCode = cmUNKNOWN;
+  }
+
+  //---------------------------------------------------------------------------
+  const ptr_tok_type& TokenReader::Store(const ptr_tok_type &t, int token_pos)
+  {
+    m_eLastTokCode = t->GetCode();
+    t->SetExprPos(token_pos);
+    m_vTokens.push_back(t);
+    return t;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Read the next token from the string. */ 
+  ptr_tok_type TokenReader::ReadNextToken()
+  {
+    assert(m_pParser);
+    const char_type *szFormula = m_sExpr.c_str();
+
+    while (szFormula[m_nPos]==' ') 
+      ++m_nPos;
+
+    int token_pos = m_nPos;
+
+    ptr_tok_type pTok;
+
+    // Check for end of expression
+    if (IsEOF(pTok))    
+      return Store(pTok, token_pos); 
+
+    if (IsNewline(pTok))    
+      return Store(pTok, token_pos); 
+
+    if ( !(m_nSynFlags & noOPT) && IsOprt(pTok))       
+      return Store(pTok, token_pos); // Check for user defined binary operator
+
+    if ( !(m_nSynFlags & noIFX) && IsInfixOpTok(pTok)) 
+      return Store(pTok, token_pos); // Check for unary operators
+
+    if (IsValTok(pTok))     
+      return Store(pTok, token_pos); // Check for values / constant tokens
+
+    if (IsBuiltIn(pTok))
+      return Store(pTok, token_pos); // Check built in operators / tokens
+
+    if (IsVarOrConstTok(pTok))     
+      return Store(pTok, token_pos); // Check for variable tokens
+
+    if (IsFunTok(pTok))     
+      return Store(pTok, token_pos);
+
+    if ( !(m_nSynFlags & noPFX) && IsPostOpTok(pTok))  
+      return Store(pTok, token_pos); // Check for unary operators
+
+    // 2.) We have found no token, maybe there is a token that we don't expect here.
+    //     Again call the Identifier functions but this time only those we don't expect 
+    //     to find.
+    if ( (m_nSynFlags & noOPT) && IsOprt(pTok))        
+      return Store(pTok, token_pos); // Check for user defined binary operator
+
+    if ( (m_nSynFlags & noIFX) && IsInfixOpTok(pTok))  
+      return Store(pTok, token_pos); // Check for unary operators
+
+    if ( (m_nSynFlags & noPFX) && IsPostOpTok(pTok))   
+      return Store(pTok, token_pos); // Check for unary operators
+    // </ibg>
+
+    // Now we are in trouble because there is something completely unknown....
+
+    // Check the string for an undefined variable token. This is done 
+    // only if a flag is set indicating to ignore undefined variables.
+    // This is a way to conditionally avoid an error if undefined variables 
+    // occur. The GetExprVar function must supress the error for undefined 
+    // variables in order to collect all variable names including the 
+    // undefined ones.
+    if ( (m_pParser->m_bIsQueryingExprVar || m_pParser->m_bAutoCreateVar) && IsUndefVarTok(pTok) )  
+      return Store(pTok, token_pos);
+
+    // Check for unknown token
+    // 
+    // !!! From this point on there is no exit without an exception possible...
+    // 
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);
+
+    ErrorContext err;
+    err.Errc  = ecUNASSIGNABLE_TOKEN;
+    err.Expr  = m_sExpr;
+    err.Pos   = m_nPos;
+
+    if (iEnd!=m_nPos)
+      err.Ident = sTok;
+    else
+      err.Ident = m_sExpr.substr(m_nPos);
+
+    throw ParserError(err);
+  }
+
+  //---------------------------------------------------------------------------
+  void TokenReader::SetParent(ParserXBase *a_pParent)
+  {
+    m_pParser             =  a_pParent; 
+    m_pFunDef             = &a_pParent->m_FunDef;
+    m_pOprtDef            = &a_pParent->m_OprtDef;
+    m_pInfixOprtDef       = &a_pParent->m_InfixOprtDef;
+    m_pPostOprtDef        = &a_pParent->m_PostOprtDef;
+    m_pVarDef             = &a_pParent->m_VarDef;
+    m_pConstDef           = &a_pParent->m_valConst;
+    m_pDynVarShadowValues = &a_pParent->m_valDynVarShadow;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Extract all characters that belong to a certain charset.
+      \param a_szCharSet [in] Const char array of the characters allowed in the token. 
+      \param a_strTok [out]  The string that consists entirely of characters listed in a_szCharSet.
+      \param a_iPos [in] Position in the string from where to start reading.
+      \return The Position of the first character not listed in a_szCharSet.
+      \throw nothrow
+  */
+  int TokenReader::ExtractToken(const char_type *a_szCharSet, 
+                                string_type &a_sTok, 
+                                int a_iPos) const
+  {
+    int iEnd = (int)m_sExpr.find_first_not_of(a_szCharSet, a_iPos);
+
+    if (iEnd==(int)string_type::npos)
+      iEnd = (int)m_sExpr.length();  
+
+    if (iEnd!=a_iPos)
+      a_sTok.assign(m_sExpr.begin()+a_iPos, m_sExpr.begin()+iEnd);
+
+    return iEnd;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a built in operator or other token can be found.
+  */
+  bool TokenReader::IsBuiltIn(ptr_tok_type &a_Tok)
+  {
+    const char_type **pOprtDef = m_pParser->GetOprtDef(),
+                     *szFormula = m_sExpr.c_str();
+    int i;
+
+    try
+    {
+      // Compare token with function and operator strings
+      // check string for operator/function
+      for (i=0; pOprtDef[i]; i++)
+      {
+        std::size_t len( std::char_traits<char_type>::length(pOprtDef[i]) );
+        if ( string_type(pOprtDef[i]) == string_type(szFormula + m_nPos, szFormula + m_nPos + len) )
+        {
+          switch(i)
+          {
+          case cmARG_SEP:
+		            if (m_nSynFlags & noCOMMA)
+                  throw ecUNEXPECTED_COMMA;
+
+                m_nSynFlags = noBC | noOPT | noEND | noNEWLINE | noCOMMA | noPFX | noIC | noIO | noIF | noELSE;
+                a_Tok = ptr_tok_type(new GenericToken((ECmdCode)i, pOprtDef[i]));
+	              break;
+
+          case cmELSE:
+               if (m_nSynFlags & noELSE)
+                 throw ecUNEXPECTED_CONDITIONAL;
+
+               m_nNumIfElse--;
+               if (m_nNumIfElse<0)
+                 throw ecMISPLACED_COLON;
+
+               m_nSynFlags = noBC | noIO | noIC | noPFX | noEND | noNEWLINE | noCOMMA | noOPT | noIF | noELSE;
+               a_Tok = ptr_tok_type(new TokenIfThenElse(cmELSE));
+               break;
+
+          case cmIF:
+               if (m_nSynFlags & noIF)
+                 throw ecUNEXPECTED_CONDITIONAL;
+
+               m_nNumIfElse++; 
+               m_nSynFlags = noBC | noIO | noPFX | noIC | noEND | noNEWLINE | noCOMMA | noOPT | noIF | noELSE;
+               a_Tok = ptr_tok_type(new TokenIfThenElse(cmIF));
+               break;
+
+          case cmBO:
+                if (m_nSynFlags & noBO)
+                  throw ecUNEXPECTED_PARENS;
+
+                if (m_eLastTokCode==cmFUNC)
+                  m_nSynFlags = noOPT | noEND | noNEWLINE | noCOMMA | noPFX | noIC | noIO | noIF | noELSE;
+                else
+                  m_nSynFlags = noBC | noOPT | noEND | noNEWLINE | noCOMMA | noPFX | noIC | noIO | noIF | noELSE;
+
+		            m_nNumBra++;
+                a_Tok = ptr_tok_type(new GenericToken((ECmdCode)i, pOprtDef[i]));
+                break;
+
+          case cmBC:   
+                if (m_nSynFlags & noBC)
+                  throw ecUNEXPECTED_PARENS;
+
+                m_nSynFlags  = noBO | noVAR | noVAL | noFUN | noIFX | noIO;
+		            m_nNumBra--;
+
+                if (m_nNumBra<0)
+                  throw ecUNEXPECTED_PARENS;
+
+                a_Tok = ptr_tok_type(new GenericToken((ECmdCode)i, pOprtDef[i]));
+                break;
+          
+          case cmIO:
+                if (m_nSynFlags & noIO)
+                  throw ecUNEXPECTED_SQR_BRACKET;
+
+                m_nSynFlags  = noIC | noIO | noOPT | noPFX | noBC | noNEWLINE;
+                m_nNumIndex++;
+                a_Tok = ptr_tok_type(new GenericToken((ECmdCode)i, pOprtDef[i]));
+                break;
+
+          case cmIC:
+                if (m_nSynFlags & noIC)
+                  throw ecUNEXPECTED_SQR_BRACKET;
+
+                m_nSynFlags  = noBO | noIFX;
+                m_nNumIndex--;
+
+                if (m_nNumIndex<0)
+                  throw ecUNEXPECTED_SQR_BRACKET;
+
+//                a_Tok = ptr_tok_type(new GenericToken((ECmdCode)i, pOprtDef[i]));
+                a_Tok = ptr_tok_type(new OprtIndex());
+                break;
+
+          default:  // The operator is listed in c_DefaultOprt, but not here. This is a bad thing...
+                throw ecINTERNAL_ERROR;
+          } // switch operator id
+
+          m_nPos += (int)len;
+          return true;
+        } // if operator string found
+      } // end of for all operator strings
+    }
+    catch (EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc  = e;
+      err.Expr  = m_sExpr;
+      err.Ident = pOprtDef[i];
+      err.Pos   = m_nPos;
+      throw ParserError(err);
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check for End of expression
+  */
+  bool TokenReader::IsNewline(ptr_tok_type &a_Tok)
+  {
+    // nicht nach:  bionop, infixop, argumentseparator, 
+    // erlaubt nach:   Werten, variablen, schließenden klammern, schliessendem index
+    bool bRet(false);
+    try
+    {
+      if ( m_sExpr[m_nPos]=='\n')
+      {
+        // Check if all brackets were closed
+        if ( m_nSynFlags & noNEWLINE )
+          throw ecUNEXPECTED_NEWLINE;
+
+        if (m_nNumBra>0)
+          throw ecMISSING_PARENS;
+
+        if (m_nNumIndex>0)
+          throw ecMISSING_SQR_BRACKET;
+
+        if (m_nNumIfElse>0)
+          throw(ecMISSING_ELSE_CLAUSE);
+
+        m_nPos++;
+        m_nSynFlags = sfSTART_OF_LINE;
+        a_Tok = ptr_tok_type(new TokenNewline());
+        bRet = true;
+      }
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Ident = _T("");
+      err.Expr = m_sExpr;
+      err.Pos = m_nPos;
+      throw ParserError(err);
+    }
+
+    return bRet;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check for End of expression
+  */
+  bool TokenReader::IsEOF(ptr_tok_type &a_Tok)
+  {
+    bool bRet(false);
+    try
+    {
+      if ( m_sExpr.length() && m_nPos>=(int)m_sExpr.length())
+      {
+        if ( m_nSynFlags & noEND )
+          throw ecUNEXPECTED_EOF;
+
+        if (m_nNumBra>0)
+          throw ecMISSING_PARENS;
+
+        if (m_nNumIndex>0)
+          throw ecMISSING_SQR_BRACKET;
+
+        if (m_nNumIfElse>0)
+          throw ecMISSING_ELSE_CLAUSE;
+
+        m_nSynFlags = 0;
+        a_Tok = ptr_tok_type(new GenericToken(cmEOE));
+        bRet = true;
+      }
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Ident = _T("");
+      err.Expr = m_sExpr;
+      err.Pos = m_nPos;
+      throw ParserError(err);
+    }
+
+    return bRet;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a string position contains a unary infix operator. 
+      \return true if a function token has been found false otherwise.
+  */
+  bool TokenReader::IsInfixOpTok(ptr_tok_type &a_Tok)
+  {
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_nPos);
+    
+    if (iEnd==m_nPos)
+      return false;
+    
+    try
+    {
+      // iteraterate over all infix operator strings
+      oprt_ifx_maptype::const_iterator item = m_pInfixOprtDef->begin();
+      for (item=m_pInfixOprtDef->begin(); item!=m_pInfixOprtDef->end(); ++item)
+      {
+        if (sTok.find(item->first)!=0)
+          continue;
+
+        a_Tok = ptr_tok_type(item->second->Clone());
+        m_nPos += (int)item->first.length();
+
+        if (m_nSynFlags & noIFX)
+          throw ecUNEXPECTED_OPERATOR;
+
+        m_nSynFlags = noPFX | noIFX | noOPT | noBC | noIC | noIO | noEND | noCOMMA | noNEWLINE; 
+        return true;
+      }
+      
+      return false;
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Pos = m_nPos;
+      err.Ident = a_Tok->GetIdent();
+      err.Expr = m_sExpr;
+      throw ParserError(err);
+    }
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Check expression for function tokens. */
+  bool TokenReader::IsFunTok(ptr_tok_type &a_Tok)
+  {
+    if (m_pFunDef->size()==0)
+      return false;
+
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);
+    if (iEnd==m_nPos)
+      return false;
+    
+    try
+    {
+      fun_maptype::iterator item = m_pFunDef->find(sTok);
+      if (item==m_pFunDef->end())
+        return false;
+
+      m_nPos = (int)iEnd;
+      a_Tok = ptr_tok_type(item->second->Clone());
+      a_Tok->Compile(_T("xxx"));
+
+      if (m_nSynFlags & noFUN)
+        throw ecUNEXPECTED_FUN;
+
+      m_nSynFlags = sfALLOW_NONE ^ noBO;
+      return true;
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Pos = m_nPos - (int)a_Tok->GetIdent().length();
+      err.Ident = a_Tok->GetIdent();
+      err.Expr = m_sExpr;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a string position contains a unary post value operator. */
+  bool TokenReader::IsPostOpTok(ptr_tok_type &a_Tok)
+  {
+    // Tricky problem with equations like "3m+5":
+    //     m is a postfix operator, + is a valid sign for postfix operators and 
+    //     for binary operators parser detects "m+" as operator string and 
+    //     finds no matching postfix operator.
+    // 
+    // This is a special case so this routine slightly differs from the other
+    // token readers.
+    
+    // Test if there could be a postfix operator
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_nPos);
+    if (iEnd==m_nPos)
+      return false;
+
+    try
+    {
+      // iteraterate over all postfix operator strings
+      oprt_pfx_maptype::const_iterator item;
+      for (item=m_pPostOprtDef->begin(); item!=m_pPostOprtDef->end(); ++item)
+      {
+        if (sTok.find(item->first)!=0)
+          continue;
+
+        a_Tok = ptr_tok_type(item->second->Clone());
+        m_nPos += (int)item->first.length();
+
+        if (m_nSynFlags & noPFX)
+          throw ecUNEXPECTED_OPERATOR;
+
+        m_nSynFlags = noVAL | noVAR | noFUN | noBO | noPFX | noIO;
+        return true;
+      }
+      
+      return false;
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Pos = m_nPos - (int)a_Tok->GetIdent().length();
+      err.Ident = a_Tok->GetIdent();
+      err.Expr = m_sExpr;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a string position contains a binary operator. */
+  bool TokenReader::IsOprt(ptr_tok_type &a_Tok)
+  {
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_nPos);
+    if (iEnd==m_nPos)
+      return false;
+
+    oprt_bin_multimap::reverse_iterator item;
+    try
+    {
+      // Note:
+      // All tokens in oprt_bin_maptype are have been sorted by their length
+      // Long operators must come first! Otherwise short names (like: "add") that
+      // are part of long token names (like: "add123") will be found instead 
+      // of the long ones.
+      // Length sorting is done with ascending length so we use a reverse iterator here.
+      for (item=m_pOprtDef->rbegin(); item!=m_pOprtDef->rend(); ++item)
+      {
+        if (sTok.find(item->first)!=0)
+          continue;
+
+        // operator found, check if we expect one...
+        if (m_nSynFlags & noOPT) 
+        {
+          // An operator was found but is not expected to occur at
+          // this position of the formula, maybe it is an infix 
+          // operator, not a binary operator. Both operator types
+          // can use the same characters in their identifiers.
+          if (IsInfixOpTok(a_Tok))
+            return true;
+
+          // nope, it's no infix operator and we dont expect 
+          // an operator
+          throw ecUNEXPECTED_OPERATOR;
+        }
+        else
+        {
+          a_Tok = ptr_tok_type(item->second->Clone());
+
+          m_nPos += (int)a_Tok->GetIdent().length(); 
+          m_nSynFlags  = noBC | noIO | noIC | noOPT | noCOMMA | noEND | noNEWLINE | noPFX;
+          return true;
+        }
+      }
+
+      return false;
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Pos = m_nPos; // - (int)item->first.length();
+      err.Ident = item->first;
+      err.Expr = m_sExpr;
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check whether the token at a given position is a value token.
+
+    Value tokens are either values or constants.
+
+    \param a_Tok [out] If a value token is found it will be placed here.
+    \return true if a value token has been found.
+  */
+  bool TokenReader::IsValTok(ptr_tok_type &a_Tok)
+  {
+    if (m_vValueReader.size()==0)
+      return false;
+
+    stringstream_type stream(m_sExpr.c_str() + m_nPos);
+    string_type sTok;
+    
+    try
+    {
+      // call the value recognition functions provided by the user
+      // Call user defined value recognition functions
+      int iSize = (int)m_vValueReader.size();
+      Value val;
+      for (int i=0; i<iSize; ++i)
+      {
+        int iStart = m_nPos;
+        if ( m_vValueReader[i]->IsValue(m_sExpr.c_str(), m_nPos, val) )
+        {
+          sTok.assign(m_sExpr.c_str(), iStart, m_nPos);
+          if (m_nSynFlags & noVAL)
+            throw ecUNEXPECTED_VAL;
+
+          m_nSynFlags = noVAL | noVAR | noFUN | noBO | noIFX | noIO;
+          a_Tok = ptr_tok_type(val.Clone());
+          a_Tok->SetIdent( string_type(sTok.begin(), sTok.begin()+(m_nPos-iStart)) );
+          return true;
+        }
+      }
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Pos = m_nPos;
+      err.Ident = sTok;
+      err.Expr = m_sExpr;
+      err.Pos = m_nPos - (int)sTok.length();
+      throw ParserError(err);
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check wheter a token at a given position is a variable token. 
+      \param a_Tok [out] If a variable token has been found it will be placed here.
+      \return true if a variable token has been found.
+  */
+  bool TokenReader::IsVarOrConstTok(ptr_tok_type &a_Tok)
+  {
+    if (!m_pVarDef->size() && !m_pConstDef->size() && !m_pFunDef->size())
+      return false;
+
+    string_type sTok;
+    int iEnd;
+    try
+    {
+      iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);
+      if (iEnd==m_nPos)
+        return false;
+
+      // Check for variables
+      var_maptype::const_iterator item =  m_pVarDef->find(sTok);
+      if (item!=m_pVarDef->end())
+      {
+        if (m_nSynFlags & noVAR)
+          throw ecUNEXPECTED_VAR;
+        
+        m_nPos = iEnd;
+        m_nSynFlags = noVAL | noVAR | noFUN | noBO | noIFX;
+        a_Tok = item->second;
+        a_Tok->SetIdent(sTok);
+        m_UsedVar[item->first] = item->second;  // Add variable to used-var-list
+        return true;
+      }
+
+      // Check for constants
+      item = m_pConstDef->find(sTok);
+      if (item!=m_pConstDef->end())
+      {
+        if (m_nSynFlags & noVAL)
+          throw ecUNEXPECTED_VAL;
+
+        m_nPos = iEnd;
+        m_nSynFlags = noVAL | noVAR | noFUN | noBO | noIFX | noIO;
+        a_Tok = item->second;
+        a_Tok->SetIdent(sTok);
+        return true;
+      }
+
+      return false;
+    }
+    catch(EErrorCodes e)
+    {
+      ErrorContext err;
+      err.Errc = e;
+      err.Pos = m_nPos;
+      err.Ident = sTok;
+      err.Expr = m_sExpr;
+      throw ParserError(err);
+    }
+
+    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  bool TokenReader::IsComment()
+  {
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check wheter a token at a given position is an undefined variable. 
+      \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.
+      \return true if a variable token has been found.
+      \throw nothrow
+  */
+  bool TokenReader::IsUndefVarTok(ptr_tok_type &a_Tok)
+  {
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), sTok, m_nPos);
+    if (iEnd==m_nPos)
+      return false;
+
+    if (m_nSynFlags & noVAR)
+    {
+      ErrorContext err;
+      err.Errc = ecUNEXPECTED_VAR;
+      err.Ident = sTok;
+      err.Expr = m_sExpr;
+      err.Pos = m_nPos - (int)sTok.length();
+      throw ParserError(err);
+    }
+
+    // Create a variable token
+    if (m_pParser->m_bAutoCreateVar)
+    {
+      ptr_val_type val(new Value);                   // Create new value token
+      m_pDynVarShadowValues->push_back(val);         // push to the vector of shadow values 
+      a_Tok = ptr_tok_type(new Variable(val.Get())); // bind variable to the new value item
+      (*m_pVarDef)[sTok] = a_Tok;                    // add new variable to the variable list
+    }
+    else
+      a_Tok = ptr_tok_type(new Variable(NULL));      // bind variable to empty variable
+
+    a_Tok->SetIdent(sTok);
+    m_UsedVar[sTok] = a_Tok;     // add new variable to used-var-list
+
+    m_nPos = iEnd;
+    m_nSynFlags = noVAL | noVAR | noFUN | noBO | noIFX;
+    return true;
+  }
+} // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpTokenReader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpTokenReader.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,130 @@
+/** \file
+    \brief Definition of the token reader used to break the expression string up 
+           into tokens.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+
+#ifndef MUP_TOKEN_READER_H
+#define MUP_TOKEN_READER_H
+
+//--- Standard includes ----------------------------------------------------
+#include <cstdio>
+#include <cstring>
+#include <map>
+#include <stack>
+#include <string>
+#include <list>
+
+//--- muParserX framework --------------------------------------------------
+#include "mpIToken.h"
+#include "mpError.h"
+#include "mpStack.h"
+#include "mpFwdDecl.h"
+
+MUP_NAMESPACE_START
+
+  /** \brief Token reader for the ParserXBase class. */
+  class TokenReader
+  {
+  friend class ParserXBase;
+
+  public:
+
+    typedef std::vector<ptr_tok_type> token_buf_type;
+
+  private:
+
+    TokenReader(const TokenReader &a_Reader);
+    TokenReader& operator=(const TokenReader &a_Reader);
+    void Assign(const TokenReader &a_Reader);
+    void DeleteValReader();
+    void SetParent(ParserXBase *a_pParent);
+
+    int ExtractToken(const char_type *a_szCharSet, string_type &a_sTok, int a_iPos) const;
+
+    bool IsBuiltIn(ptr_tok_type &t);
+    bool IsEOF(ptr_tok_type &t);
+    bool IsNewline(ptr_tok_type &a_Tok);
+    bool IsNewLine(ptr_tok_type &t);
+    bool IsInfixOpTok(ptr_tok_type &t);
+    bool IsFunTok(ptr_tok_type &t);
+    bool IsPostOpTok(ptr_tok_type &t);
+    bool IsOprt(ptr_tok_type &t);
+    bool IsValTok(ptr_tok_type &t);
+    bool IsVarOrConstTok(ptr_tok_type &t);
+    bool IsUndefVarTok(ptr_tok_type &t);
+    bool IsComment();
+
+    const ptr_tok_type& Store(const ptr_tok_type &t, int pos);
+
+    ParserXBase *m_pParser;  ///< Pointer to the parser bound to this token reader
+    string_type m_sExpr;     ///< The expression beeing currently parsed
+    int  m_nPos;             ///< Current parsing position in the expression
+    int  m_nNumBra;          ///< Number of open parenthesis
+    int  m_nNumIndex;        ///< Number of open index paranethesis    
+    int  m_nNumIfElse;       ///< Coubter for if-then-else levels
+    int  m_nSynFlags;        ///< Flags to controll the syntax flow
+
+    token_buf_type m_vTokens;
+    ECmdCode m_eLastTokCode;
+
+    mutable fun_maptype  *m_pFunDef;
+    mutable oprt_bin_multimap *m_pOprtDef;
+    mutable oprt_ifx_maptype *m_pInfixOprtDef;
+    mutable oprt_pfx_maptype *m_pPostOprtDef;
+    mutable val_maptype  *m_pConstDef;
+    val_vec_type *m_pDynVarShadowValues; ///< Value items created for holding values of variables created at parser runtime
+    var_maptype  *m_pVarDef;             ///< The only non const pointer to parser internals
+
+    readervec_type m_vValueReader;  ///< Value token identification function
+    var_maptype m_UsedVar;
+    float_type m_fZero;             ///< Dummy value of zero, referenced by undefined variables
+
+  public:
+
+    TokenReader(ParserXBase *a_pParent);
+   ~TokenReader();
+    TokenReader* Clone(ParserXBase *a_pParent) const;
+    
+    void AddValueReader(IValueReader *a_pReader);
+    void AddSynFlags(int flag);
+    //void SetVarCreator(facfun_type a_pFactory);
+    int GetPos() const;
+    const string_type& GetExpr() const;
+    const var_maptype& GetUsedVar() const;
+    const token_buf_type& GetTokens() const;
+    void SetExpr(const string_type &a_sExpr);
+
+    void ReInit();
+    ptr_tok_type ReadNextToken();
+  }; // class TokenReader
+
+MUP_NAMESPACE_END
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpTypes.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpTypes.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,313 @@
+/** \file
+    \brief Definition of basic types used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_TYPES_H
+#define MUP_TYPES_H
+
+//--- Standard include ------------------------------------------------------
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <complex>
+
+//--- muParserX framework ---------------------------------------------------
+#include "suSortPred.h"  // We need the string utils sorting predicates
+#include "mpDefines.h"
+#include "mpMatrix.h"
+
+
+MUP_NAMESPACE_START
+
+// Forward declarations
+  class IValueReader;
+  class IOprtBin;
+  class IOprtPostfix;
+  class IOprtInfix;
+  class IFunction;
+  class IToken;
+  class IValue;
+  class ParserXBase;
+  class Value;
+  class Variable;
+  class TokenReader;
+
+  // smart pointer types
+  template<typename T>
+  class TokenPtr;
+
+  /** \brief Type of a managed pointer storing parser tokens. */
+  typedef TokenPtr<IToken>   ptr_tok_type;
+
+  /** \brief Type of a managed pointer storing value tokens. */
+  typedef TokenPtr<IValue>   ptr_val_type;
+
+  /** \brief Type of a managed pointer storing binary operator tokens. */
+  typedef TokenPtr<IOprtBin> ptr_binop_type;
+
+  /** \brief Type for a vector of tokens. */
+  typedef std::vector<ptr_tok_type> token_vec_type;
+
+  /** \brief Type for a vector of value items. */
+  typedef std::vector<ptr_val_type> val_vec_type;
+
+  // parser type definitions
+
+  /** \brief Parser datatype for floating point value. */
+  typedef /*long*/ double float_type;
+
+  /** \brief Parser datatype for integer valuse. */
+  typedef int int_type;
+
+  /** \brief The basic type used for representing complex numbers. */
+  typedef std::complex<float_type> cmplx_type;
+
+  /** \brief Parser boolean datatype. 
+
+      This must be bool! The only reason for this typedef is that I need the name bool_type
+      for a preprocessor macro definition to avoid inconsistent naming of the macro parameters.
+  */
+  typedef bool bool_type;   
+
+  /** \brief The parsers underlying matrix type. */
+  typedef Matrix<Value> matrix_type;
+
+  /** \brief Parser datatype for strings. */
+  typedef MUP_STRING_TYPE string_type;
+
+  /** \brief Character type of the parser. */
+  typedef string_type::value_type char_type;
+
+  typedef std::basic_stringstream<char_type, 
+                                  std::char_traits<char_type>,
+                                  std::allocator<char_type> > stringstream_type;
+
+  /** \brief Type of a vector holding pointers to value reader objects. */
+  typedef std::vector<IValueReader*> readervec_type;
+
+  /** \brief type for the parser variable storage. */
+  typedef std::map<string_type, ptr_tok_type> var_maptype;  
+
+  /** \brief type of a container used to store parser values.  */
+  typedef std::map<string_type, ptr_tok_type> val_maptype;
+
+  /** \brief Type of a container that binds Callback object pointer
+             to operator identifiers. */
+  typedef std::map<string_type, ptr_tok_type> fun_maptype;
+
+  /** \brief Type of a container that binds Callback object pointer
+             to operator identifiers. */
+  typedef std::map<string_type, ptr_tok_type, su::pred::SortByLength<string_type> > oprt_bin_maptype;
+
+  typedef std::multimap<string_type, ptr_tok_type, su::pred::SortByLength<string_type> > oprt_bin_multimap;
+
+  /** \brief Type of a map for storing postfix operators by their name. */
+  typedef std::map<string_type, ptr_tok_type> oprt_pfx_maptype;
+
+  /** \brief Type of a map for storing infix operators by their name. */
+  typedef std::map<string_type, ptr_tok_type> oprt_ifx_maptype;
+
+  //------------------------------------------------------------------------------
+  /** \brief Bytecode values.
+      \attention The order of the operator entries must match the order in 
+                 ParserXBase::c_DefaultOprt!
+  */
+  enum ECmdCode
+  {
+    // The following are codes for built in binary operators
+    // apart from built in operators the user has the opportunity to
+    // add user defined operators.
+    cmBO                =  0,  ///< Operator item:  opening bracket
+    cmBC                =  1,  ///< Operator item:  closing bracket
+    cmIO                =  2,  ///< Operator item:  index operator opening
+    cmIC                =  3,  ///< Operator item:  index operator closing
+    cmARG_SEP           =  4,  ///< Operator item:  comma
+    cmIF                =  5,  ///< Ternary if then else operator
+    cmELSE              =  6,  ///< Ternary if then else operator 
+    cmENDIF             =  7,  ///< Ternary if then else operator 
+    cmJMP               =  8,  ///< Reserved for future use
+    cmVAR               =  9,  ///< variable item
+    cmVAL               = 10,  ///< value item
+    cmFUNC              = 11,  ///< Code for a function item
+    cmOPRT_BIN          = 12,  ///< Binary operator
+    cmOPRT_INFIX        = 13,  ///< Infix operator
+    cmOPRT_POSTFIX      = 14,  ///< Postfix operator
+    cmEOE               = 15,  ///< End of expression
+
+    // The following codes are reserved in case i will ever turn this
+    // into a scripting language
+    cmSCRIPT_GOTO       = 16,  ///< Reserved for future use
+    cmSCRIPT_LABEL      = 17,  ///< Reserved for future use
+    cmSCRIPT_FOR        = 18,  ///< Reserved for future use
+    cmSCRIPT_IF         = 19,  ///< Reserved for future use
+    cmSCRIPT_ELSE       = 20,  ///< Reserved for future use
+    cmSCRIPT_ELSEIF     = 21,  ///< Reserved for future use
+    cmSCRIPT_ENDIF      = 22,  ///< Reserved for future use
+    cmSCRIPT_NEWLINE    = 23,  ///< Newline
+    cmSCRIPT_FUNCTION   = 24,  ///< Reserved for future use
+
+    // misc codes
+    cmUNKNOWN           = 25,  ///< uninitialized item
+    cmCOUNT             = 26   ///< Dummy entry for counting the enum values
+  }; // ECmdCode
+
+
+  //------------------------------------------------------------------------------
+  /** \brief Strings assigned to the enum codes of ECmdCode. 
+
+      Used for debugging purposes only.
+  */
+  extern const char_type *g_sCmdCode[];
+
+  //------------------------------------------------------------------------------
+  enum EPackages
+  {
+    pckCOMMON          = 1 << 0,
+    pckUNIT            = 1 << 1,
+    pckCOMPLEX         = 1 << 2,
+    pckNON_COMPLEX     = 1 << 3,
+    pckSTRING          = 1 << 4,
+    pckMATRIX          = 1 << 5,
+    pckALL_COMPLEX     = pckCOMMON | pckCOMPLEX | pckSTRING | pckUNIT | pckMATRIX,
+    pckALL_NON_COMPLEX = pckCOMMON | pckNON_COMPLEX | pckSTRING | pckUNIT | pckMATRIX
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Syntax codes. 
+
+    The syntax codes control the syntax check done during the first time parsing of 
+    the expression string. They are flags that indicate which tokens are allowed next
+    if certain tokens are identified.
+  */
+  enum ESynCodes
+  {
+    noBO      = 1 <<  0,  ///< to avoid i.e. "cos(7)(" 
+    noBC      = 1 <<  1,  ///< to avoid i.e. "sin)" or "()"
+    noIO      = 1 <<  2,  ///< No opening bracket "["
+    noIC      = 1 <<  3,  ///< No closing bracket "]"
+    noVAL     = 1 <<  4,  ///< to avoid i.e. "tan 2" or "sin(8)3.14"
+    noVAR     = 1 <<  5,  ///< to avoid i.e. "sin a" or "sin(8)a"
+    noCOMMA   = 1 <<  6,  ///< to avoid i.e. ",," or "+," ...
+    noFUN     = 1 <<  7,  ///< to avoid i.e. "sqrt cos" or "(1)sin"	
+    noOPT     = 1 <<  8,  ///< to avoid i.e. "(+)"
+    noPFX     = 1 <<  9,  ///< to avoid i.e. "(5!!)" "sin!"
+    noIFX     = 1 << 10,  ///< to avoid i.e. "++4" "!!4"
+    noEND     = 1 << 11,  ///< to avoid unexpected end of expression
+    noIF      = 1 << 12,  
+    noELSE    = 1 << 13,  
+    noNEWLINE = 1 << 14,  ///< to avoid i.e. "a+\nb" or "sin(\na)"
+
+    sfSTART_OF_LINE = noOPT | noBC | noPFX | noCOMMA | noIO | noIC | noIF | noELSE,
+    sfALLOW_NONE    = ~0        ///< All of he above flags set
+  };	
+
+  //------------------------------------------------------------------------------
+  /** \brief Binary operator associativity values. */
+  enum EOprtAsct
+  {
+    oaNONE  = 0,
+    oaLEFT  = 1,
+    oaRIGHT = 2,
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser operator precedence values. 
+  
+    These are predefined values for the operator precedence.
+  */
+  enum EOprtPrecedence
+  {
+    // assignment operators
+    prASSIGN       = -1,
+
+    // if-then-else
+    prIF_THEN_ELSE =  0,
+
+    // binary operators
+    prLOGIC_OR     =  1,
+    prLOGIC_AND    =  2,
+    prBIT_OR       =  3,
+    prBIT_AND      =  4, 
+
+    prRELATIONAL1  =  5, ///< For "==", "!=" 
+    prRELATIONAL2  =  6, ///< Relational operators "<", "<=", ">", ">="
+    prSHIFT        =  7, ///< Shift operators "<<", ">>"
+    
+    prCOLON        =  8, ///< Colon operator
+
+    prADD_SUB      =  9, ///< addition
+    prMUL_DIV      = 10, ///< multiplication/division
+    prPOW          = 11, ///< power operator priority (highest)
+
+    // infix operators
+    prINFIX        = 10, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
+    prPOSTFIX      = 10  ///< Postfix operator priority (currently unused)
+  };
+
+#if defined(_UNICODE)
+
+  //------------------------------------------------------------------------------
+  /** \brief Encapsulate wcout. */
+  inline std::wostream& console()
+  {
+    return std::wcout;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Encapsulate cin. */
+  inline std::wistream& console_in()
+  {
+    return std::wcin;
+  }
+
+#else
+
+  /** \brief Encapsulate cout. 
+  
+    Used for supporting UNICODE more easily.
+  */
+  inline std::ostream& console()
+  {
+    return std::cout;
+  }
+
+  /** \brief Encapsulate cin. 
+
+    Used for supporting UNICODE more easily.
+  */
+  inline std::istream& console_in()
+  {
+    return std::cin;
+  }
+
+#endif // _UNICODE
+
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpValReader.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpValReader.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,279 @@
+/** \file
+    \brief Implementation of classes that interpret values in a string.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#include "mpValReader.h"
+#include "mpError.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for floating point values
+  //
+  //------------------------------------------------------------------------------
+
+  DblValReader::DblValReader()
+    :IValueReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  DblValReader::~DblValReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  bool DblValReader::IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_Val)
+  {
+    stringstream_type stream(a_szExpr + a_iPos);
+    float_type fVal(0);
+    std::streamoff iStart(0), iEnd(0);
+
+    iStart = stream.tellg(); // Record position before reading
+    stream >> fVal;
+    iEnd = stream.tellg();   // Position after reading
+
+    if (iEnd==-1)
+      return false;
+
+    a_iPos += (int)iEnd;
+    
+    // Finally i have to check if the next sign is the "i" for a imaginary unit
+    // if so this is an imaginary value
+    if (a_szExpr[a_iPos]=='i')
+    {
+      a_Val = cmplx_type(0.0, fVal);
+      a_iPos++;
+    }
+    else
+    {
+      a_Val = cmplx_type(fVal, 0.0);
+    }
+
+    return true;
+  }
+
+  //------------------------------------------------------------------------------
+  IValueReader* DblValReader::Clone(TokenReader *pTokenReader) const
+  {
+    IValueReader *pReader = new DblValReader(*this);
+    pReader->SetParent(pTokenReader);
+
+    return pReader;
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for boolean values
+  //
+  //------------------------------------------------------------------------------
+
+  BoolValReader::BoolValReader()
+    :IValueReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  BoolValReader::~BoolValReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  bool BoolValReader::IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_Val)
+  {
+    string_type sExpr(a_szExpr + a_iPos);
+
+    if (sExpr.find(_T("true"))==0)
+    {
+      a_Val = true;
+      a_iPos += 4;
+      return true;
+    }
+    else if (sExpr.find(_T("false"))==0)
+    {
+      a_Val = false;
+      a_iPos += 5;
+      return true;
+    }
+
+    return false;
+  }
+
+  //------------------------------------------------------------------------------
+  IValueReader* BoolValReader::Clone(TokenReader *pTokenReader) const
+  {
+    IValueReader *pReader = new BoolValReader(*this);
+    pReader->SetParent(pTokenReader);
+
+    return pReader;
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for hex values
+  //
+  //------------------------------------------------------------------------------
+
+  HexValReader::HexValReader()
+    :IValueReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  /** \brief Try to read a hex value from a given position in the expression. 
+      \param a_szExpr The Expression
+      \param [in/out] a_iPos The current position in the expression
+      \param [out] a_val The value that was read
+
+    Hex values must start with a "0x" characters. The position a_iPos is advanded in case 
+    a hex value was found.
+  */
+  bool HexValReader::IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_val)
+  {
+		std::size_t len = std::char_traits<char_type>::length(a_szExpr);
+    if ( a_iPos>=(int)len || a_szExpr[a_iPos+1]!='x' || a_szExpr[a_iPos+1]==0 || a_szExpr[a_iPos]!='0') 
+      return 0;
+
+    unsigned iVal(0);
+
+    stringstream_type::pos_type nPos(0);
+    stringstream_type ss(a_szExpr + a_iPos + 2);
+    ss >> std::hex >> iVal;
+    nPos = ss.tellg();
+
+    if (nPos==(stringstream_type::pos_type)0)
+      return 1;
+
+    a_iPos += (int)(2 + nPos);
+    a_val = (int)iVal;
+    return 1;
+  }
+
+  //------------------------------------------------------------------------------
+  IValueReader* HexValReader::Clone(TokenReader *pTokenReader) const
+  {
+    IValueReader *pReader = new HexValReader(*this);
+    pReader->SetParent(pTokenReader);
+    return pReader;
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for binary values
+  //
+  //------------------------------------------------------------------------------
+
+  BinValReader::BinValReader()
+    :IValueReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  BinValReader::~BinValReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  bool BinValReader::IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_Val)
+  {
+    const char_type *szExpr = a_szExpr + a_iPos;
+
+    if (szExpr[0]!='#') 
+      return false;
+
+    unsigned iVal = 0, iBits = sizeof(iVal)*8, i;
+    for (i=0; (szExpr[i+1]=='0' || szExpr[i+1]=='1') && i<iBits; ++i)
+      iVal |= (int)(szExpr[i+1]=='1') << ((iBits-1)-i);
+
+    if (i==0) 
+      return false;
+
+    if (i==iBits)
+      throw ParserError(_T("Binary to integer conversion error (overflow)."));
+
+    a_Val = (int)(iVal >> (iBits-i) );
+    a_iPos += i+1;
+
+    return true;
+  }
+
+  //------------------------------------------------------------------------------
+  IValueReader* BinValReader::Clone(TokenReader *pTokenReader) const
+  {
+    IValueReader *pReader = new BinValReader(*this);
+    pReader->SetParent(pTokenReader);
+
+    return pReader;
+  }
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for string values
+  //
+  //------------------------------------------------------------------------------
+
+  StrValReader::StrValReader()
+    :IValueReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  StrValReader::~StrValReader()
+  {}
+
+  //------------------------------------------------------------------------------
+  bool StrValReader::IsValue(const char_type *a_pszExpr, int &a_iPos, Value &a_Val)
+  {
+    const char_type *szExpr = a_pszExpr + a_iPos;
+
+    
+    if (szExpr[0]!='"') 
+      return false;
+
+    string_type sBuf(&szExpr[1]);
+    std::size_t iEnd(0), iSkip(0);
+
+    // parser over escaped '\"' end replace them with '"'
+    for(iEnd=sBuf.find(_T("\"")); iEnd!=string_type::npos; iEnd=sBuf.find(_T("\""), iEnd))
+    {
+      if (sBuf[iEnd-1]!='\\') break;
+      sBuf.replace(iEnd-1, 2, _T("\""));
+      iSkip++;
+    }
+
+    if (iEnd==string_type::npos)
+      throw ParserError( ErrorContext(ecUNTERMINATED_STRING, a_iPos) );
+
+    string_type sTok(sBuf.begin(), sBuf.begin()+iEnd);
+    a_Val = sTok;
+    a_iPos += (int)(sTok.length() + 2 + iSkip);  // +2 wg Anführungszeichen; +iSkip für entfernte escape zeichen
+    return true;
+  }
+
+  //------------------------------------------------------------------------------
+  IValueReader* StrValReader::Clone(TokenReader *pTokenReader) const
+  {
+    IValueReader *pReader = new StrValReader(*this);
+    pReader->SetParent(pTokenReader);
+
+    return pReader;
+  }
+} // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpValReader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpValReader.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,129 @@
+/** \file
+    \brief Definition of classes that interpret values in a string.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#ifndef MU_PARSER_IMPL_READER_H
+#define MU_PARSER_IMPL_READER_H
+
+#include "mpIValReader.h"
+
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for double values
+  //
+  //------------------------------------------------------------------------------
+
+  /** \brief A class for reading floating point values from an expression string.
+      \ingroup valreader
+  */
+  class DblValReader : public IValueReader
+  {
+  public:    
+      DblValReader();
+      virtual ~DblValReader();
+      virtual bool IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_fVal);
+      virtual IValueReader* Clone(TokenReader *pTokenReader) const;
+  };
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for boolean values
+  //
+  //------------------------------------------------------------------------------
+
+  /** \brief A class for reading boolean values from an expression string.
+      \ingroup valreader
+  */
+  class BoolValReader : public IValueReader
+  {
+  public:    
+      BoolValReader();
+      virtual ~BoolValReader();
+      virtual bool IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_fVal);
+      virtual IValueReader* Clone(TokenReader *pTokenReader) const;
+  };
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for hex values
+  //
+  //------------------------------------------------------------------------------
+
+  /** \brief A class for reading hex values from an expression string.
+      \ingroup valreader
+  */
+  class HexValReader : public IValueReader
+  {
+  public:    
+      HexValReader();
+      virtual bool IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_fVal);
+      virtual IValueReader* Clone(TokenReader *pTokenReader) const;
+  };
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for binary values
+  //
+  //------------------------------------------------------------------------------
+
+  /** \brief A class for reading binary values from an expression string.
+      \ingroup valreader
+  */
+  class BinValReader : public IValueReader
+  {
+  public:    
+      BinValReader();
+      virtual ~BinValReader();
+      virtual bool IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_fVal);
+      virtual IValueReader* Clone(TokenReader *pTokenReader) const;
+  };
+
+  //------------------------------------------------------------------------------
+  //
+  //  Reader for string values
+  //
+  //------------------------------------------------------------------------------
+
+  /** \brief A class for reading strings from an expression string.
+      \ingroup valreader
+  */
+  class StrValReader : public IValueReader
+  {
+  public:    
+      StrValReader();
+      virtual ~StrValReader();
+      virtual bool IsValue(const char_type *a_szExpr, int &a_iPos, Value &a_fVal);
+      virtual IValueReader* Clone(TokenReader *pTokenReader) const;
+  };
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpValue.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpValue.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,795 @@
+/*
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpValue.h"
+#include "mpError.h"
+#include "mpValueCache.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Construct an empty value object of a given type. 
+      \param cType The type of the value to construct (default='v').
+  */
+  Value::Value(char_type cType)
+    :IValue(cmVAL)
+    ,m_val(0,0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType(cType)
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {
+    // strings and arrays must allocate their memory
+    switch (cType)
+    {
+    case 's': m_psVal = new string_type(); break;
+    case 'm': m_pvVal = new matrix_type(0, Value(0)); break;
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(int_type a_iVal)
+    :IValue(cmVAL)
+    ,m_val((float_type)a_iVal, 0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('i')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(bool_type a_bVal)
+    :IValue(cmVAL)
+    ,m_val((float_type)a_bVal, 0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('b')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(string_type a_sVal)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(new string_type(a_sVal))
+    ,m_pvVal(NULL)
+    ,m_cType('s')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(int_type array_size, float_type v)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(NULL)
+    ,m_pvVal(new matrix_type(array_size, Value(v)))
+    ,m_cType('m')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Create a m x n matrix
+  */
+  Value::Value(int_type m, int_type n, float_type v)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(NULL)
+    ,m_pvVal(new matrix_type(m, n, Value(v)))
+    ,m_cType('m')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const char_type *a_szVal)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(new string_type(a_szVal))
+    ,m_pvVal(NULL)
+    ,m_cType('s')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const cmplx_type &v)
+    :IValue(cmVAL)
+    ,m_val(v)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('c')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {
+    if ( (m_val.real()==(int_type)m_val.real()) && (m_val.imag()==0) )
+      m_cType = 'i';
+    else
+      m_cType = (m_val.imag()==0) ? 'f' : 'c';
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(float_type val)
+    :IValue(cmVAL)
+    ,m_val(val, 0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType((val==(int_type)val) ? 'i' : 'f')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const matrix_type &val)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(NULL)
+    ,m_pvVal(new matrix_type(val))
+    ,m_cType('m')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const Value &a_Val)
+    :IValue(cmVAL)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_pCache(NULL)
+  {
+    Assign(a_Val);
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(const IValue &a_Val)
+    :IValue(cmVAL)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_pCache(NULL)
+  {
+    Reset();
+
+    switch(a_Val.GetType())
+    {
+    case 'i': 
+    case 'f': 
+    case 'b': m_val = cmplx_type(a_Val.GetFloat(), 0);
+              break;
+
+
+    case 'c': m_val = cmplx_type(a_Val.GetFloat(), a_Val.GetImag());
+              break;
+
+    case 's': if (!m_psVal)
+                m_psVal = new string_type(a_Val.GetString());
+              else
+               *m_psVal = a_Val.GetString();
+              break;
+
+    case 'm': if (!m_pvVal) 
+                m_pvVal = new matrix_type(a_Val.GetArray());
+              else
+               *m_pvVal  = a_Val.GetArray();  
+              break;
+
+    case 'v': break;
+    default:  MUP_FAIL(INVALID_TYPE_CODE);
+    }
+    
+    m_cType = a_Val.GetType();
+  }
+
+  //---------------------------------------------------------------------------
+  Value& Value::operator=(const Value &a_Val)
+  {
+    Assign(a_Val);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the matrix element at row col.
+      
+    Row and col are the indices of the matrix. If this element does not
+    represent a matrix row and col must be 0 otherwise an index out of bound error
+    is thrown.
+  */
+  IValue& Value::At(const IValue &row, const IValue &col)
+  {
+    if (!row.IsInteger() || !col.IsInteger())
+    {
+      ErrorContext errc(ecTYPE_CONFLICT_IDX, GetExprPos());
+      errc.Hint = _T("Array index must be an integer value.");
+      errc.Type1 = (!row.IsInteger()) ? row.GetType() : col.GetType();
+      errc.Type2 = 'i';
+      throw ParserError(errc);
+    }
+
+    int nRow = row.GetInteger(),
+        nCol = col.GetInteger();
+    return At(nRow, nCol);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::At(int nRow, int nCol)
+  {
+    if (IsMatrix())
+    {
+      if (nRow>=m_pvVal->GetRows() || nCol>=m_pvVal->GetCols() || nRow<0 || nCol<0)
+        throw ParserError( ErrorContext(ecINDEX_OUT_OF_BOUNDS, -1, GetIdent()) ); 
+
+      return m_pvVal->At(nRow, nCol);
+    }
+    else if (nRow==0 && nCol==0)
+    {
+      return *this;
+    }
+    else
+      throw ParserError( ErrorContext(ecINDEX_OUT_OF_BOUNDS) ); 
+  }
+
+  //---------------------------------------------------------------------------
+  Value::~Value()
+  {
+    delete m_psVal;
+    delete m_pvVal;
+  }
+
+  //---------------------------------------------------------------------------
+  IToken* Value::Clone() const
+  {
+    return new Value(*this);
+  }
+
+  //---------------------------------------------------------------------------
+  Value* Value::AsValue()
+  {
+    return this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor. */
+  void Value::Assign(const Value &ref)
+  {
+    if (this==&ref)
+      return;
+
+    m_val    = ref.m_val;
+    m_cType  = ref.m_cType;
+    m_iFlags = ref.m_iFlags;
+
+    // allocate room for a string
+    if (ref.m_psVal)
+    {
+      if (!m_psVal)
+        m_psVal = new string_type(*ref.m_psVal);
+      else
+       *m_psVal = *ref.m_psVal;
+    }
+    else
+    {
+      delete m_psVal;
+      m_psVal = NULL;
+    }
+
+    // allocate room for a vector
+    if (ref.m_pvVal)
+    {
+      if (m_pvVal==NULL)
+        m_pvVal = new matrix_type(*ref.m_pvVal);
+      else
+       *m_pvVal = *ref.m_pvVal;
+    }
+    else
+    {
+      delete m_pvVal;
+      m_pvVal = NULL;
+    }
+
+    // Do NOT access ref beyound this point! If you do, "unboxing" of
+    // a 1 x 1 matrix using:
+    //
+    // this->Assign(m_pvVal->At(0,0));
+    // 
+    // will blow up in your face since ref will become invalid at them very
+    // moment you delete m_pvVal!
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::Reset()
+  {
+    m_val = cmplx_type(0,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+		
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 'f';
+    m_iFlags = flNONE;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(bool val)
+  {
+    m_val = cmplx_type((float_type)val,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 'b';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(int_type a_iVal)
+  {
+    m_val = cmplx_type(a_iVal,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 'i';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(float_type val)
+  {
+    m_val = cmplx_type(val, 0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = (val==(int_type)val) ? 'i' : 'f';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(string_type a_sVal)
+  {
+    m_val = cmplx_type();
+    
+    if (!m_psVal)
+      m_psVal = new string_type(a_sVal);
+    else
+     *m_psVal = a_sVal;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 's';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(const char_type *a_szVal)
+  {
+    m_val = cmplx_type();
+
+    if (!m_psVal)
+      m_psVal = new string_type(a_szVal);
+    else
+     *m_psVal = a_szVal;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 's';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(const matrix_type &a_vVal)
+  {
+    m_val = cmplx_type(0,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+		
+    if (m_pvVal==NULL)
+      m_pvVal = new matrix_type(a_vVal);
+    else
+      *m_pvVal = a_vVal;
+    
+    m_cType = 'm';
+    m_iFlags = flNONE;
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(const cmplx_type &val)
+  {
+    m_val = val;
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = (m_val.imag()==0) ? ( (m_val.real()==(int)m_val.real()) ? 'i' : 'f' ) : 'c';
+    m_iFlags = flNONE;
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator+=(const IValue &val)
+  {
+    if (IsScalar() && val.IsScalar())
+    {
+      // Scalar/Scalar addition
+      m_val += val.GetComplex();
+    }
+    else if (IsMatrix() && val.IsMatrix())
+    {
+      // Matrix/Matrix addition
+      assert(m_pvVal);
+      *m_pvVal += val.GetArray();
+    }
+    else if (IsString() && val.IsString())
+    {
+      // string/string addition
+      assert(m_psVal);
+      *m_psVal += val.GetString();
+    }
+    else
+    {
+      // Type conflict
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, _T("+"), GetType(), val.GetType(), 2));
+    }
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator-=(const IValue &val)
+  {
+    if (IsScalar() && val.IsScalar())
+    {
+      // Scalar/Scalar addition
+      m_val -= val.GetComplex();
+    }
+    else if (IsMatrix() && val.IsMatrix())
+    {
+      // Matrix/Matrix addition
+      assert(m_pvVal);
+      *m_pvVal -= val.GetArray();
+    }
+    else
+    {
+      // There is a typeconflict:
+      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, _T("-"), GetType(), val.GetType(), 2));
+    }
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assign a value with multiplication
+      \param val The value to multiply to this
+
+    When multiplying to values with each value representing a matrix type
+    the result is checked whether it is a 1 x 1 matrix. If so the value is
+    "unboxed" and stored directly in this value object. It is no longer 
+    treated as a matrix internally.
+  */
+  IValue& Value::operator*=(const IValue &val)
+  {
+    if (IsScalar() && val.IsScalar())
+    {
+      // Scalar/Scalar multiplication
+      m_val *= val.GetComplex();
+      
+      // Check whether we're dealing with a complex or integer result, if so set the 
+      // type flag accordingly
+      if (m_val.imag()!=0)
+        m_cType = 'c';
+      else if ((double)(int)m_val.real()==m_val.real())
+        m_cType = 'i';
+    }
+    else if (IsMatrix() && val.IsMatrix())
+    {
+      // Matrix/Matrix addition
+      assert(m_pvVal);
+      *m_pvVal *= val.GetArray();
+
+      // The result may actually be a scalar value, i.e. the scalar product of
+      // two vectors.
+      if (m_pvVal->GetCols()==1 && m_pvVal->GetRows()==1)
+      {
+        Assign(m_pvVal->At(0,0));
+      }
+    }
+    else if ( IsMatrix() && val.IsScalar() )
+    {
+      *m_pvVal *= val;
+    }
+    else if ( IsScalar() * val.IsMatrix() )
+    {
+      // transform this into a matrix and multiply with rhs
+      Value prod = val * (*this);
+      Assign(prod);
+    }
+    else
+    {
+      // Type conflict
+      ErrorContext errc(ecTYPE_CONFLICT_FUN, -1, _T("*"));
+      errc.Type1 = GetType();
+      errc.Type2 = 'm'; //val.GetType();
+      errc.Arg = 2;
+      throw ParserError(errc);
+    }
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns a character representing the type of this value instance. 
+      \return m_cType Either one of 'c' for comlex, 'i' for integer, 
+              'f' for floating point, 'b' for boolean, 's' for string or 
+              'm' for matrix values.
+  */
+  char_type Value::GetType() const
+  {
+    return m_cType;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the value as an integer. 
+    
+    This function should only be called if you really need an integer value and
+    want to make sure your either get one or throw an exception if the value
+    can not be implicitely converted into an integer.
+  */
+  int_type Value::GetInteger() const
+  {
+    float_type v = m_val.real();
+
+    if (m_cType!='i') //!IsScalar() || (int_type)v-v!=0)
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = 'i';
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+
+    return (int_type)v;
+  }
+
+  //---------------------------------------------------------------------------
+  float_type Value::GetFloat() const
+  {
+/*
+    if (!IsScalar() && m_cType!='b')
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = 'c';
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+*/
+    return m_val.real();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Get the imaginary part of the value. 
+      \throw ParserError in case this value represents a string or a matrix
+  */
+  float_type Value::GetImag() const
+  {
+    if (!IsScalar())
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = 'c';
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+
+    return m_val.imag();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns this value as a complex number. 
+      \throw nothrow
+
+    If the value instance does not represent a complex value the returned value
+    is undefined. No exception is triggered. If you are unsure about the type
+    use IsComplex() or GetType() to verify the type.
+  */
+  const cmplx_type& Value::GetComplex() const
+  {
+    return m_val;
+  }
+
+  //---------------------------------------------------------------------------
+  const string_type& Value::GetString() const
+  {
+    CheckType('s');
+    assert(m_psVal!=NULL);
+    return *m_psVal;
+  }
+
+  //---------------------------------------------------------------------------
+  bool Value::GetBool() const
+  {
+    CheckType('b');
+    return m_val.real()==1;
+  }
+
+  //---------------------------------------------------------------------------
+  const matrix_type& Value::GetArray() const
+  {
+    CheckType('m');
+    assert(m_pvVal!=NULL);
+    return *m_pvVal;
+  }
+
+  //---------------------------------------------------------------------------
+  int Value::GetRows() const
+  {
+    return (GetType()!='m') ? 1 : GetArray().GetRows();
+  }
+  
+  //---------------------------------------------------------------------------
+  int Value::GetCols() const
+  {
+    return 1;
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::CheckType(char_type a_cType) const
+  {
+    if (m_cType!=a_cType)
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = a_cType;
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool Value::IsVolatile() const
+  {
+    return IsFlagSet(IValue::flVOLATILE);
+//    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  string_type Value::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; type=\"") << GetType() << _T("\"");
+    ss << _T("; val=");
+
+    switch(m_cType)
+    {
+    case 'i': ss << (int_type)m_val.real(); break;
+    case 'f': ss << m_val.real(); break;
+    case 'm': ss << _T("(matrix)"); break;
+    case 's': 
+              assert(m_psVal!=NULL);
+              ss << _T("\"") << m_psVal << _T("\""); break;
+    }
+
+    ss << ((IsFlagSet(IToken::flVOLATILE)) ? _T("; ") : _T("; not ")) << _T("volatile");
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::Release()
+  {
+    if (m_pCache)
+      m_pCache->ReleaseToCache(this);
+    else
+      delete this;
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::BindToCache(ValueCache *pCache)
+  {
+    m_pCache = pCache;
+  }
+}  // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpValue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpValue.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,128 @@
+/** \file
+    \brief Definition of basic types used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#ifndef MUP_VALUE_H
+#define MUP_VALUE_H
+
+//--- Standard includes ------------------------------------------------------------
+#include <complex>
+#include <list>
+
+//--- Parser framework -------------------------------------------------------------
+#include "mpIValue.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Value class of muParserX
+  
+    This class represents a value to be used with muParserX. It's a Variant like
+    class able to store a variety of types.
+  */
+  class Value : public IValue
+  {
+  public:
+
+    explicit Value(char_type cType = 'v');
+    Value(int_type val);
+    Value(bool_type val);
+    Value(float_type val);
+    Value(string_type val);
+    Value(const char_type *val);
+    Value(const cmplx_type &v);
+    Value(const matrix_type &val);
+
+    // Array and Matrix constructors
+    Value(int_type m, float_type v);
+    Value(int_type m, int_type n, float_type v);
+
+    Value(const Value &a_Val );
+    Value(const IValue &a_Val);
+    Value& operator=(const Value &a_Val);
+
+    virtual ~Value();
+ 
+    virtual IValue& At(int nRow, int nCol = 0);
+    virtual IValue& At(const IValue &row, const IValue &col);
+
+    virtual IValue& operator=(int_type a_iVal);
+    virtual IValue& operator=(float_type a_fVal);
+    virtual IValue& operator=(string_type a_sVal);
+    virtual IValue& operator=(bool val);
+    virtual IValue& operator=(const matrix_type &a_vVal);
+    virtual IValue& operator=(const cmplx_type &val);
+    virtual IValue& operator=(const char_type *a_szVal);
+    virtual IValue& operator+=(const IValue &val);
+    virtual IValue& operator-=(const IValue &val);
+    virtual IValue& operator*=(const IValue &val);
+
+    virtual char_type GetType() const;
+    virtual int_type GetInteger() const;
+    virtual float_type GetFloat() const;
+    virtual float_type GetImag() const;
+    virtual bool GetBool() const;
+    virtual const cmplx_type& GetComplex() const;
+    virtual const string_type& GetString() const;
+    virtual const matrix_type& GetArray() const;
+    virtual int GetRows() const;
+    virtual int GetCols() const;
+
+    virtual bool IsVolatile() const;
+    virtual IToken* Clone() const;
+    virtual Value* AsValue();
+
+    virtual string_type AsciiDump() const;
+    void BindToCache(ValueCache *pCache);
+
+  private:
+
+    cmplx_type   m_val;    ///< Member variable for storing the value of complex, float, int and boolean values
+    string_type *m_psVal;  ///< Variable for storing a string value
+    matrix_type  *m_pvVal;  ///< A Vector for storing array variable content
+    char_type    m_cType;  ///< A byte indicating the type os the represented value
+    EFlags       m_iFlags; ///< Additional flags
+    ValueCache  *m_pCache; ///< Pointer to the Value Cache
+
+    int m_nCols;    ///< Number of columns in this value (for matrices)
+    int m_nRows;    ///< Number of Rows in this value (for matrices)
+
+    void CheckType(char_type a_cType) const;
+    void Assign(const Value &a_Val);
+    void Reset();
+
+    virtual void Release();
+  }; // class Value
+
+
+MUP_NAMESPACE_END
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpValueCache.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpValueCache.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,99 @@
+/** \file
+    \brief Definition of a class for caching unused value items and recycling them.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpValueCache.h"
+
+#include "mpValue.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  ValueCache::ValueCache(int size)
+    :m_nIdx(-1)
+    ,m_vCache(size, (mup::Value*)0) // hint to myself: don't use NULL gcc will go postal...
+  {}
+
+  //------------------------------------------------------------------------------
+  ValueCache::~ValueCache()
+  {
+    ReleaseAll();
+  }
+
+  //------------------------------------------------------------------------------
+  void ValueCache::ReleaseAll()
+  {
+    for (std::size_t i=0; i<m_vCache.size(); ++i)
+    {
+      delete m_vCache[i];
+      m_vCache[i] = NULL;
+    }
+
+    m_nIdx = -1;
+  }
+
+  //------------------------------------------------------------------------------
+  void ValueCache::ReleaseToCache(Value *pValue) 
+  {
+//    std::cout << "dbg: " << ct << " ptr: " << this << " void ValueCache::ReleaseToCache(Value *pValue) \n";
+    if (pValue==NULL)
+      return;
+
+    assert(pValue->GetRef()==0);
+
+    // Add the value to the cache if the cache has room for it 
+    // otherwise release the value item instantly
+    if ( m_nIdx < ((int)m_vCache.size()-1) )
+    {
+      m_nIdx++;
+      m_vCache[m_nIdx] = pValue;
+    }
+    else
+      delete pValue;
+  }
+
+  //------------------------------------------------------------------------------
+  Value* ValueCache::CreateFromCache() 
+  {
+    Value *pValue = NULL;
+    if (m_nIdx>=0)
+    {
+      pValue = m_vCache[m_nIdx];
+      m_vCache[m_nIdx] = NULL;
+      m_nIdx--;
+    }
+    else
+    {
+      pValue = new Value();
+      pValue->BindToCache(this);
+    }
+
+    return pValue;
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpValueCache.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpValueCache.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,67 @@
+#ifndef MUP_VALUE_CACHE_H
+#define MUP_VALUE_CACHE_H
+
+/** \file
+    \brief Implementation of a cache for recycling unused value items.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include <vector>
+
+#include "mpFwdDecl.h"
+
+
+MUP_NAMESPACE_START
+  
+  /** \brief The ValueCache class provides a simple mechanism to recycle 
+             unused value items.
+    
+    This class serves as a factory for value items. It allows skipping
+    unnecessary and slow new/delete calls by storing unused value 
+    objects in an internal buffer for later reuse. By eliminating new/delete
+    calls the parser is sped up approximately by factor 3-4.
+  */
+  class ValueCache
+  {
+  public:
+    ValueCache(int size=10);
+   ~ValueCache();
+
+    void ReleaseAll();
+    void ReleaseToCache(Value *pValue);
+    Value* CreateFromCache();
+
+  private:
+    ValueCache(const ValueCache &ref);
+    ValueCache& operator=(const ValueCache &ref);
+
+    int m_nIdx;
+    std::vector<Value*> m_vCache;
+  };
+
+MUP_NAMESPACE_END
+
+#endif // include guard
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpVariable.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpVariable.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,315 @@
+/** \file
+    \brief Implementation of the muParserX variable class.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpVariable.h"
+#include "mpError.h"
+
+#include "mpValue.h"
+
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Create a variable and bind a value to it.
+      \param pVal Pointer of the value to bind to this variable.
+
+    It is possible to create an empty variable object by setting pVal to null.
+    Such variable objects must be bound later in order to be of any use.
+  */
+  Variable::Variable(IValue *pVal)
+    :IValue(cmVAR)
+    ,m_pVal(pVal)
+  {
+    AddFlags(IToken::flVOLATILE);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  Variable::Variable(const Variable &obj)
+    :IValue(cmVAR)
+  {
+    Assign(obj);
+    AddFlags(IToken::flVOLATILE);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  Variable& Variable::operator=(const Variable &obj)
+  {
+    Assign(obj);
+    return *this;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Assign a value to the variable. 
+      \param ref Reference to the value to be assigned
+  */
+  IValue& Variable::operator=(const Value &ref)
+  {
+    assert(m_pVal);
+    *m_pVal = ref;
+    return *this;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator=(int_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator=(float_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator=(string_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator=(bool_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator=(const matrix_type &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator=(const cmplx_type &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator+=(const IValue &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator+=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator-=(const IValue &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator-=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::operator*=(const IValue &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator*=(val);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::At(int nRow, int nCol)
+  {
+    return m_pVal->At(nRow, nCol);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& Variable::At(const IValue &row, const IValue &col)
+  {
+    try
+    {
+      return m_pVal->At(row, col);
+    }
+    catch(ParserError &exc)
+    {
+      // add the identifier to the error context
+      exc.GetContext().Ident = GetIdent();
+      throw exc;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  Variable::~Variable()
+  {}
+
+  //-----------------------------------------------------------------------------------------------
+  void Variable::Assign(const Variable &ref)
+  {
+    if (this==&ref)
+      return;
+
+    m_pVal = ref.m_pVal;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Returns a character representing the type of the variable. 
+      \throw nothrow  
+  */
+  char_type Variable::GetType() const
+  {
+    return (m_pVal) ? m_pVal->GetType() : 'v';
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Returns the Value pointer bound to this variable. 
+      \throw nothrow
+  */
+  IValue* Variable::GetPtr() const
+  {
+    return m_pVal;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  int_type Variable::GetInteger() const
+  {
+    return m_pVal->GetInteger();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  float_type Variable::GetFloat() const
+  {
+    return m_pVal->GetFloat();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  float_type Variable::GetImag() const
+  {
+    return m_pVal->GetImag();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  const cmplx_type& Variable::GetComplex() const
+  {
+    return m_pVal->GetComplex();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  const string_type& Variable::GetString() const
+  {
+    return m_pVal->GetString();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool Variable::GetBool() const
+  {
+    return m_pVal->GetBool();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  const matrix_type& Variable::GetArray() const
+  {
+    return m_pVal->GetArray();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  int Variable::GetRows() const
+  {
+    return m_pVal->GetRows();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  int Variable::GetCols() const
+  {
+    return m_pVal->GetCols();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void Variable::SetFloat(float_type a_fVal)
+  {
+    assert(m_pVal);
+    *m_pVal = a_fVal;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void Variable::SetString(const string_type &a_sVal)
+  {
+    assert(m_pVal);
+    *m_pVal = a_sVal;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void Variable::SetBool(bool a_bVal)
+  {
+    assert(m_pVal);
+    *m_pVal = a_bVal;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void Variable::Bind(IValue *pValue)
+  {
+    m_pVal = pValue;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool Variable::IsVolatile() const
+  {
+    return true;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IToken* Variable::Clone() const
+  {
+    return new Variable(*this);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  Value* Variable::AsValue()
+  {
+    return NULL;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  string_type Variable::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; id=\"") << GetIdent() << _T("\"");
+    ss << _T("; type=\"") << GetType() << _T("\"");
+    ss << _T("; val=");
+
+    switch(GetType())
+    {
+    case 'i': ss << (int_type)GetFloat(); break;
+    case 'f': ss << GetFloat(); break;
+    case 'm': ss << _T("(array)"); break;
+    case 's': ss << _T("\"") << GetString() << _T("\""); break;
+    }
+
+    ss << ((IsFlagSet(IToken::flVOLATILE)) ? _T("; ") : _T("; not ")) << _T("volatile");
+    ss << _T("]");
+
+    return ss.str();
+  }
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/mpVariable.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/mpVariable.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,108 @@
+/** \file
+    \brief Definition of the muParserX variable class.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+
+#ifndef MP_VARIABLE_H
+#define MP_VARIABLE_H
+
+#include "mpIValue.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief The variable class represents a parser variable. 
+  
+    This class stores a pointer to a value object and refers all
+    operations to this value object.
+  */
+  class Variable : public IValue
+  {
+  public:
+
+    Variable(IValue *pVal);
+
+    Variable(const Variable &a_Var);
+    Variable& operator=(const Variable &a_Var);
+
+    virtual IValue& At(int nRow, int nCol);
+    virtual IValue& At(const IValue &nRows, const IValue &nCols);
+
+    virtual IValue& operator=(const Value &val);
+    virtual IValue& operator=(const matrix_type &val);
+    virtual IValue& operator=(const cmplx_type &val);
+    virtual IValue& operator=(int_type val);
+    virtual IValue& operator=(float_type val);
+    virtual IValue& operator=(string_type val);
+    virtual IValue& operator=(bool_type val);
+    virtual IValue& operator+=(const IValue &ref);
+    virtual IValue& operator-=(const IValue &ref);
+    virtual IValue& operator*=(const IValue &val);
+
+    virtual ~Variable();
+
+    virtual char_type GetType() const;
+    
+    virtual int_type GetInteger() const;
+    virtual float_type GetFloat() const;
+    virtual float_type GetImag() const;
+    virtual bool GetBool() const;
+    virtual const cmplx_type& GetComplex() const;
+    virtual const string_type& GetString() const;
+    virtual const matrix_type& GetArray() const;
+    virtual int GetRows() const;
+    virtual int GetCols() const;
+
+    virtual bool IsVolatile() const;
+    virtual IToken* Clone() const;
+    virtual Value* AsValue();
+
+    //void Set(Value &val);
+    void SetFloat(float_type a_fVal);
+    void SetString(const string_type &a_sVal);
+    void SetBool(bool a_bVal);
+
+    void Bind(IValue *pValue);
+
+    IValue* GetPtr() const;
+    string_type AsciiDump() const;
+
+  private:
+
+    IValue *m_pVal;    ///< Pointer to the value object bound to this variable
+
+    void Assign(const Variable &a_Var);
+    void CheckType(char_type a_cType) const;
+  }; // class Variable
+
+MUP_NAMESPACE_END
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/muParser.suo
Binary file muparserx/parser/muParser.suo has changed
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/suSortPred.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/suSortPred.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,58 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef SU_PRED_H
+#define SU_PRED_H
+
+#include <functional>
+
+
+/** \brief Namespace containing utility functions and classes for string processing. */
+namespace su
+{
+  namespace pred
+  {
+    /** \brief Sort two strings based on their length.
+    */
+    template<class TString>
+	  struct SortByLength
+      :public std::binary_function<TString, TString, bool>
+	  {	
+	    bool operator()(const TString& a_sLeft, const TString& a_sRight) const
+		  {	
+        if (a_sLeft.length() == a_sRight.length())
+        {
+          return a_sLeft < a_sRight;
+        }
+        else
+        {
+          return a_sLeft.length() < a_sRight.length();
+        }
+		  }
+	  };
+  } // namespace pred
+} // end of namespace
+
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/parser/utGeneric.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/parser/utGeneric.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,53 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef _UT_GENERIC_H
+#define _UT_GENERIC_H
+
+namespace utils
+{
+  template<typename T>
+  class scoped_setter
+  {
+  public:
+
+    scoped_setter(T &ref, T new_val)
+      :m_ref(ref)
+      ,m_buf(ref)
+    {
+      ref = new_val;
+    }
+
+   ~scoped_setter()
+    {
+      m_ref = m_buf;
+    }
+
+  private:
+    T &m_ref;
+    T  m_buf;
+  };
+}
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/sample/example.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/sample/example.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,911 @@
+/** \example example.cpp
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+
+  This is example code showing you how to use muParserX.
+*/
+
+//---------------------------------------------------------------------------
+//
+//  muParserX 
+//
+//  example.cpp - Demonstrates how to use muParserX
+//
+//---------------------------------------------------------------------------
+
+/** \brief This macro will enable mathematical constants like M_PI. */
+#define _USE_MATH_DEFINES		
+
+//--- Standard include ------------------------------------------------------
+#if defined(_WIN32) && defined(_DEBUG)
+  #define _CRTDBG_MAP_ALLOC
+  #include <stdlib.h>
+  #include <crtdbg.h>
+  #define CREATE_LEAKAGE_REPORT
+#endif
+
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <cstdio>
+#include <cmath>
+#include <string>
+#include <iostream>
+
+//--- muParserX framework ---------------------------------------------------
+#include "mpParser.h"
+#include "mpDefines.h"
+#include "mpTest.h"
+
+//--- other includes --------------------------------------------------------
+#include "timer.h"
+
+using namespace std;
+using namespace mup;
+
+#if defined(CREATE_LEAKAGE_REPORT)
+
+// Dumping memory leaks in the destructor of the static guard
+// guarantees i won't get false positives from the ParserErrorMsg 
+// class wich is a singleton with a static instance.
+struct DumpLeaks
+{
+ ~DumpLeaks()
+  {
+    _CrtDumpMemoryLeaks();
+  }
+} static LeakDumper;
+
+#endif
+
+const string_type sPrompt = _T("muParserX> ");
+
+//-------------------------------------------------------------------------------------------------
+// The following classes will be used to list muParserX variables, constants
+// from this console application
+//-------------------------------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------------------------------
+class FunPrint : public ICallback
+{
+public:
+  FunPrint() : ICallback(cmFUNC, _T("print"), 1) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+    console() << a_pArg[0].Get()->ToString() << _T("\n");
+    *ret = 0;
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunPrint();
+  }
+}; // class FunPrint
+
+//-------------------------------------------------------------------------------------------------
+class FunTest0 : public ICallback
+{
+public:
+  FunTest0() : ICallback(cmFUNC, _T("test0"), 0) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+    *ret = 0;
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunTest0();
+  }
+}; // class FunTest0
+
+//-------------------------------------------------------------------------------------------------
+class FunListVar : public ICallback
+{
+public:
+
+  FunListVar() : ICallback(cmFUNC, _T("list_var"), 0) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+
+    console() << _T("\nParser variables:\n");
+    console() << _T(  "-----------------\n");
+
+    // Query the used variables (must be done after calc)
+    var_maptype vmap = parser.GetVar();
+    if (!vmap.size())
+    {
+      console() << _T("Expression does not contain variables\n");
+    }
+    else
+    {
+      var_maptype::iterator item = vmap.begin();
+      for (; item!=vmap.end(); ++item)
+      {
+        // You can dump the token into a stream via the "<<" operator
+        console() << _T("  ") << item->first << _T(" =  ") << *(item->second)/* << _T("\n")*/;
+
+        // If you need more specific information cast the token to a variable object
+        Variable &v = (Variable&)(*(item->second));
+        console() << _T("  (type=\"") << v.GetType() << _T("\"; ptr=0x") << hex << v.GetPtr() << _T(")\n");
+      }
+    }
+
+    *ret = (int)vmap.size();
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("list_var() - List all variables of the parser bound to this function and returns the number of defined variables.");
+  }
+
+  virtual IToken* Clone() const
+  {
+    return new FunListVar();
+  }
+}; // class FunListVar
+
+
+//-------------------------------------------------------------------------------------------------
+class FunListConst : public ICallback
+{
+public:
+
+  FunListConst() : ICallback(cmFUNC, _T("list_const"), 0) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+
+    console() << _T("\nParser constants:\n");
+    console() << _T(  "-----------------\n");
+
+    val_maptype cmap = parser.GetConst();
+    if (!cmap.size())
+    {
+      console() << _T("No constants defined\n");
+    }
+    else
+    {
+      val_maptype::iterator item = cmap.begin();
+      for (; item!=cmap.end(); ++item)
+        console() << _T("  ") << item->first << _T(" =  ") << (Value&)(*(item->second)) << _T("\n");
+    }
+
+    *ret = (int)cmap.size();
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("list_const() - List all constants of the parser bound to this function and returns the number of defined constants.");
+  }
+
+  virtual IToken* Clone() const
+  {
+    return new FunListConst();
+  }
+}; // class FunListConst
+
+
+//-------------------------------------------------------------------------------------------------
+class FunBenchmark : public ICallback
+{
+public:
+  FunBenchmark() : ICallback(cmFUNC, _T("bench"), 0) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    char outstr[200];
+    time_t t = time(NULL);
+
+    #ifdef _DEBUG
+    strftime(outstr, sizeof(outstr), "Result_%Y%m%d_%H%M%S_dbg.txt", localtime(&t));
+    #else
+    strftime(outstr, sizeof(outstr), "Result_%Y%m%d_%H%M%S_release.txt", localtime(&t));
+    #endif
+
+    const char_type* sExpr[] = { 
+                                 _T("sin(a)"),
+                                 _T("cos(a)"),
+                                 _T("tan(a)"),
+                                 _T("sqrt(a)"),
+                                 _T("(a+b)*3"),
+                                 _T("a^2+b^2"),
+                                 _T("a^3+b^3"),
+                                 _T("a^4+b^4"),
+                                 _T("a^5+b^5"),
+                                 _T("a*2+b*2"),
+                                 _T("-(b^1.1)"),
+                                 _T("a + b * c"),
+                                 _T("a * b + c"),
+                                 _T("a+b*(a+b)"),
+                                 _T("(1+b)*(-3)"),
+                                 _T("e^log(7*a)"),
+                                 _T("10^log(3+b)"),
+                                 _T("a+b-e*pi/5^6"),
+                                 _T("a^b/e*pi-5+6"),
+                                 _T("sin(a)+sin(b)"),
+                                 _T("(cos(2.41)/b)"),
+                                 _T("-(sin(pi+a)+1)"),
+                                 _T("a-(e^(log(7+b)))"),
+                                 _T("sin(((a-a)+b)+a)"),
+                                 _T("((0.09/a)+2.58)-1.67"),
+                                 _T("abs(sin(sqrt(a^2+b^2))*255)"),
+                                 _T("abs(sin(sqrt(a*a+b*b))*255)"),
+                                 _T("cos(0.90-((cos(b)/2.89)/e)/a)"),
+                                 _T("(1*(2*(3*(4*(5*(6*(a+b)))))))"),
+                                 _T("abs(sin(sqrt(a^2.1+b^2.1))*255)"),
+                                 _T("(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"),
+                                 _T("1/(a*sqrt(2*pi))*e^(-0.5*((b-a)/a)^2)"),
+                                 _T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"),
+                                 _T("1+b-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12*a"),
+                                 _T("(b+1)*(b+2)*(b+3)*(b+4)*(b+5)*(b+6)*(b+7)*(b+8)*(b+9)*(b+10)*(b+11)*(b+12)"),
+                                 _T("(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))"),
+                                 _T("(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"),
+                                 0 };
+
+
+
+    ParserX  parser;      
+    Value a((float_type)1.0);
+    Value b((float_type)2.0);
+    Value c((float_type)3.0);
+
+    parser.DefineVar(_T("a"),  Variable(&a));
+    parser.DefineVar(_T("b"),  Variable(&b));
+    parser.DefineVar(_T("c"),  Variable(&c));
+    parser.DefineConst(_T("pi"), (float_type)M_PI);
+    parser.DefineConst(_T("e"), (float_type)M_E);
+
+    FILE *pFile = fopen(outstr, "w");
+    int iCount = 400000;
+
+    #ifdef _DEBUG
+    string_type sMode = _T("# debug mode\n");
+    #else
+    string_type sMode = _T("# release mode\n");
+    #endif
+
+    fprintf(pFile, "%s; muParserX V%s\n", sMode.c_str(), ParserXBase::GetVersion().c_str());
+    fprintf(pFile, "\"Eqn no.\", \"number\", \"result\", \"time in ms\", \"eval per second\", \"expr\"\n");
+
+    printf("%s", sMode.c_str());
+    printf("\"Eqn no.\", \"number\", \"result\", \"time in ms\", \"eval per second\", \"expr\"\n");
+
+    double avg_eval_per_sec = 0;
+    int ct=0;
+    for (int i=0; sExpr[i]; ++i)
+    {
+      ct++;
+      StartTimer();
+      Value val;
+      parser.SetExpr(sExpr[i]);
+
+      // implicitely create reverse polish notation
+      parser.Eval(); 
+
+      for (int n=0; n<iCount; ++n)
+      {
+        val = parser.Eval();
+      }
+
+      double diff = StopTimer();
+      
+      float_type eval_per_sec = (float_type)iCount*1000.0/diff;
+      avg_eval_per_sec += eval_per_sec;
+
+      #if !defined _UNICODE
+      fprintf(pFile, "Eqn_%d, %d, %lf, %lf, %lf, %s\n", i, iCount, val.GetFloat(), diff, eval_per_sec, sExpr[i]);
+      printf("Eqn_%d, %d, %lf, %lf, %lf, %s\n"        , i, iCount, val.GetFloat(), diff, eval_per_sec, sExpr[i]);
+      #else
+      fwprintf(pFile, _T("Eqn_%d, %d, %lf, %lf, %lf, %s\n"), i, iCount, val.GetFloat(), diff, eval_per_sec, sExpr[i]);
+      wprintf(_T("Eqn_%d, %d, %lf, %lf, %lf, %s\n")        , i, iCount, val.GetFloat(), diff, eval_per_sec, sExpr[i]);
+      #endif
+    }
+
+    avg_eval_per_sec /= (float_type)ct;
+
+    fprintf(pFile, "# Eval per s: %d", (long)avg_eval_per_sec);
+
+    fflush(pFile);
+    *ret = (float_type)avg_eval_per_sec;
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("bench() - Perform a benchmark with a set of standard functions.");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunBenchmark();
+  }
+}; // class FunBenchmark
+
+
+//-------------------------------------------------------------------------------------------------
+class FunListFunctions : public ICallback
+{
+public:
+  FunListFunctions() : ICallback(cmFUNC, _T("list_fun"), 0) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+
+    console() << _T("\nParser functions:\n");
+    console() << _T(  "----------------\n");
+
+    fun_maptype fmap = parser.GetFunDef();
+    if (!fmap.size())
+    {
+      console() << _T("No functions defined\n");
+    }
+    else
+    {
+      val_maptype::iterator item = fmap.begin();
+      for (; item!=fmap.end(); ++item)
+      {
+        ICallback *pFun = (ICallback*)item->second.Get();
+        console() << pFun->GetDesc() << _T("\n");
+      }
+    }
+
+    *ret = (int)fmap.size();
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("list_fun() - List all parser functions and returns the total number of defined functions.");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunListFunctions();
+  }
+}; // class FunListFunctions
+
+
+//-------------------------------------------------------------------------------------------------
+class FunEnableOptimizer : public ICallback
+{
+public:
+  FunEnableOptimizer() : ICallback(cmFUNC, _T("enable_optimizer"), 1) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase &parser = *GetParent();
+    parser.EnableOptimizer(a_pArg[0]->GetBool());
+    *ret = a_pArg[0]->GetBool();
+  }
+  virtual const char_type* GetDesc() const
+  {
+    return _T("enable_optimizer(bool) - Enables the parsers built in expression optimizer.");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunEnableOptimizer();
+  }
+}; // class FunListFunctions
+
+
+//-------------------------------------------------------------------------------------------------
+class FunSelfTest : public ICallback
+{
+public:
+  FunSelfTest() : ICallback(cmFUNC, _T("test"), 0) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase::EnableDebugDump(0, 0);
+    ParserTester pt;
+    pt.Run();
+    *ret = 0;
+  }
+  virtual const char_type* GetDesc() const
+  {
+    return _T("test() - Runs the unit test of muparserx.");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunSelfTest();
+  }
+}; // class FunSelfTest
+
+//-------------------------------------------------------------------------------------------------
+class FunEnableDebugDump : public ICallback
+{
+public:
+  FunEnableDebugDump() : ICallback(cmFUNC, _T("dump"), 2) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    ParserXBase::EnableDebugDump(a_pArg[0]->GetBool(), a_pArg[1]->GetBool());
+    *ret = 0;
+  }
+  virtual const char_type* GetDesc() const
+  {
+    return _T("dump(bDumpRPN, bDumpStack) - Enable dumping of RPN and stack content.");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunEnableDebugDump();
+  }
+}; // class FunEnableDebugDump
+
+
+
+/*
+//-------------------------------------------------------------------------------------------------
+class FunGeneric : public ICallback
+{
+public:
+
+  FunGeneric(string_type sIdent, string_type sFunction) 
+    :ICallback(cmFUNC, sIdent.c_str()) 
+    ,m_parser()
+    ,m_vars()
+    ,m_val()
+  {
+    m_parser.SetExpr(sFunction);
+    m_vars = m_parser.GetExprVar();
+    SetArgc(m_vars.size());
+
+    // Create values for the undefined variables and bind them
+    // to the variables
+    var_maptype::iterator item = m_vars.begin();
+    for (; item!=m_vars.end(); ++item)
+    {
+      ptr_val_type val(new Value());
+      m_val.push_back(val);
+
+      // assign a parser variable
+      m_parser.DefineVar(item->second->GetIdent(), Variable(val.Get()));
+    }
+  }
+
+  virtual ~FunGeneric()
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    // Set the variables
+    for (std::size_t i=0; i<(std::size_t)a_iArgc; ++i)
+    {
+      *m_val[i] = *a_pArg[i];
+    }
+
+    *ret = m_parser.Eval();
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("xxx(...) - Dynamically defined function");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunGeneric(*this);
+  }
+
+private:
+
+  ParserX m_parser;
+  mup::var_maptype m_vars;
+  val_vec_type m_val;
+}; // class FunGeneric
+
+//---------------------------------------------------------------------------
+class FunDefine : public ICallback
+{
+public:
+  FunDefine() : ICallback(cmFUNC, _T("define"), 2) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    string_type sFun = a_pArg[0]->GetString();
+    string_type sDef = a_pArg[1]->GetString();
+
+    ParserXBase &parser = *GetParent();
+    parser.DefineFun(new FunGeneric(sFun, sDef));
+
+    *ret = 0;
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("define(Function, Definition) - Define a new parser function.");
+  }
+  
+  virtual IToken* Clone() const
+  {
+    return new FunDefine();
+  }
+}; // class FunDefine
+
+//---------------------------------------------------------------------------
+class FunDerive : public ICallback
+{
+public:
+  FunDerive() : ICallback(cmFUNC, _T("derive")) 
+  {}
+
+  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
+  {
+    *ret = 0;
+  }
+
+  virtual const char_type* GetDesc() const
+  {
+    return _T("...");
+  }
+
+  void Compile(const string_type &sArg)
+  {
+  }
+
+  virtual IToken* Clone() const
+  {
+    return new FunDerive();
+  }
+}; // class FunDerive
+*/
+
+
+//---------------------------------------------------------------------------
+void SelfTest()
+{
+  console() << _T("-------------------------------------------------------------------------\n\n");
+  console() << _T("               __________                                 ____  ___\n");
+  console() << _T("    _____  __ _\\______   \\_____ _______  ______ __________\\   \\/  /\n");
+  console() << _T("   /     \\|  |  \\     ___/\\__  \\\\_  __ \\/  ___// __ \\_  __ \\     / \n");
+  console() << _T("  |  Y Y  \\  |  /    |     / __ \\|  | \\/\\___ \\\\  ___/|  | \\/     \\ \n");
+  console() << _T("  |__|_|  /____/|____|    (____  /__|  /____  >\\___  >__| /___/\\  \\\n");
+  console() << _T("        \\/                     \\/           \\/     \\/           \\_/\n");
+
+
+  console() << _T("  Version ") << ParserXBase::GetVersion() << _T("\n");
+  console() << _T("  Copyright (C) 2011 Ingo Berg");
+  console() << _T("\n");
+
+  console() << _T("-------------------------------------------------------------------------\n\n");
+  console() << _T( "Configuration:\n\n");
+
+#if defined(_DEBUG)
+  console() << _T( "- DEBUG build\n");
+#else
+  console() << _T( "- RELEASE build\n");
+#endif
+
+  console() << _T( "- ") << sizeof(void*)*8 << _T(" bit\n");
+
+#if defined(_UNICODE)
+  console() << _T( "- UNICODE build\n");
+#else  
+  console() << _T( "- ASCII build\n");
+#endif
+
+  console() << _T("-------------------------------------------------------------------------\n\n");
+  console() << _T( "Running test suite:\n\n");
+
+  ParserTester pt;
+  pt.Run();
+
+  console() << _T("-------------------------------------------------------------------------\n\n");
+  console() << _T("Special parser functions:\n");
+  console() << _T("  list_var()   - list parser variables and return the number of variables.\n");
+  console() << _T("  list_fun()   - list parser functions and return  the number of functions\n");
+  console() << _T("  list_const() - list all numeric parser constants\n");
+  console() << _T("Command line commands:\n");
+  console() << _T("  exprvar      - list all variables found in the last expression\n");
+  console() << _T("  rpn          - Dump reverse polish notation of the current expression\n");
+  console() << _T("  quit         - exits the parser\n");
+  console() << _T("Constants:\n");
+  console() << _T("  \"e\"   2.718281828459045235360287\n");
+  console() << _T("  \"pi\"  3.141592653589793238462643\n");
+  console() << _T("-------------------------------------------------------------------------\n\n");
+}
+
+//---------------------------------------------------------------------------
+void ListExprVar(ParserXBase &parser)
+{
+  console() << _T("\nVariables found in : \"") << parser.GetExpr() << _T("\"\n");
+  console() << _T(  "-----------------------------\n");
+
+  // Query the used variables (must be done after calc)
+  var_maptype vmap = parser.GetExprVar();
+  if (!vmap.size())
+  {
+    console() << _T("Expression does not contain variables\n");
+  }
+  else
+  {
+    var_maptype::iterator item = vmap.begin();
+    for (; item!=vmap.end(); ++item)
+      console() << _T("  ") << item->first << _T(" =  ") << (Variable&)(*(item->second)) << _T("\n");
+  }
+}
+
+//---------------------------------------------------------------------------
+/** \brief Check for external keywords.
+*/
+int CheckKeywords(const char_type *a_szLine, ParserXBase &a_Parser)
+{
+  string_type sLine(a_szLine);
+
+  if (sLine==_T("quit"))
+  {
+    return -1;
+  }
+  else if (sLine==_T("exprvar"))
+  {
+    ListExprVar(a_Parser);
+    return 1;
+  }
+  else if (sLine==_T("rpn"))
+  {
+    a_Parser.DumpRPN();
+    return 1;
+  }
+
+  return 0;
+}
+
+//---------------------------------------------------------------------------
+void Calc()
+{
+//  ParserX  parser(pckALL_NON_COMPLEX);
+  ParserX  parser(pckALL_COMPLEX);
+
+  // Create an array variable
+  Value arr1(3, 0);
+  arr1.At(0) = (float_type)1.0;
+  arr1.At(1) = (float_type)2.0;
+  arr1.At(2) = (float_type)3.0;
+
+  Value arr2(3, 0);
+  arr2.At(0) = (float_type)4.0;
+  arr2.At(1) = (float_type)3.0;
+  arr2.At(2) = (float_type)2.0;
+
+  Value arr3(4, 0);
+  arr3.At(0) = (float_type)1.0;
+  arr3.At(1) = (float_type)2.0;
+  arr3.At(2) = (float_type)3.0;
+  arr3.At(3) = (float_type)4.0;
+
+  Value arr4(3, 0);
+  arr4.At(0) = (float_type)4.0;
+  arr4.At(1) = false;
+  arr4.At(2) = _T("hallo");
+
+  // Create a 3x3 matrix with zero elements
+  Value m1(3, 3, 0);
+  m1.At(0, 0) = 1;
+  m1.At(1, 1) = 1;
+  m1.At(2, 2) = 1;
+
+  Value m2(3, 3, 0);
+  m2.At(0, 0) = 1;
+  m2.At(0, 1) = 2;
+  m2.At(0, 2) = 3;
+  m2.At(1, 0) = 4;
+  m2.At(1, 1) = 5;
+  m2.At(1, 2) = 6;
+  m2.At(2, 0) = 7;
+  m2.At(2, 1) = 8;
+  m2.At(2, 2) = 9;
+
+  Value val[5];
+  val[0] = (float_type)1.1;
+  val[1] = 1;
+  val[2] = false;
+  val[3] = _T("Hello");
+  val[4] = _T("World");
+
+  Value fVal[3];
+  fVal[0] = (float_type)1.11;
+  fVal[1] = (float_type)2.22;
+  fVal[2] = (float_type)3.33;
+
+  Value iVal[3];
+  iVal[0] = 1;
+  iVal[1] = 2;
+  iVal[2] = 3;
+
+  Value sVal[3];
+  sVal[0] = _T("hello");
+  sVal[1] = _T("world");
+  sVal[2] = _T("test");
+
+  Value cVal[3];
+  cVal[0] = mup::cmplx_type(1, 1);
+  cVal[1] = mup::cmplx_type(2, 2);
+  cVal[2] = mup::cmplx_type(3, 3);
+
+  Value ans;
+  parser.DefineVar(_T("ans"), Variable(&ans));
+
+  // some tests for vectors
+  parser.DefineVar(_T("va"), Variable(&arr1));
+  parser.DefineVar(_T("vb"), Variable(&arr2));
+  parser.DefineVar(_T("vc"), Variable(&arr3));
+  parser.DefineVar(_T("vd"), Variable(&arr4));
+  parser.DefineVar(_T("m1"), Variable(&m1));
+  parser.DefineVar(_T("m2"), Variable(&m2));
+
+  parser.DefineVar(_T("a"),  Variable(&fVal[0]));
+  parser.DefineVar(_T("b"),  Variable(&fVal[1]));
+  parser.DefineVar(_T("c"),  Variable(&fVal[2]));
+
+  parser.DefineVar(_T("ia"), Variable(&iVal[0]));
+  parser.DefineVar(_T("ib"), Variable(&iVal[1]));
+  parser.DefineVar(_T("ic"), Variable(&iVal[2]));
+
+  parser.DefineVar(_T("ca"), Variable(&cVal[0]));
+  parser.DefineVar(_T("cb"), Variable(&cVal[1]));
+  parser.DefineVar(_T("cc"), Variable(&cVal[2]));
+
+  parser.DefineVar(_T("sa"), Variable(&sVal[0]));
+  parser.DefineVar(_T("sb"), Variable(&sVal[1]));
+
+  // Add functions for inspecting the parser properties
+  parser.DefineFun(new FunListVar);
+  parser.DefineFun(new FunListFunctions);
+  parser.DefineFun(new FunListConst);
+  parser.DefineFun(new FunBenchmark);
+  parser.DefineFun(new FunEnableOptimizer);
+  parser.DefineFun(new FunSelfTest);
+  parser.DefineFun(new FunEnableDebugDump);
+  parser.DefineFun(new FunTest0);
+  parser.DefineFun(new FunPrint);
+ 
+  parser.EnableAutoCreateVar(true);
+
+//#ifdef _DEBUG
+//  ParserXBase::EnableDebugDump(1, 0);
+//#endif
+
+  for(;;)
+  {
+    try
+    {
+      console() << sPrompt;
+
+      string_type sLine;
+      std::getline(mup::console_in(), sLine);
+      if (sLine.length()==0)
+        continue;
+
+      if (sLine==_T("dbg"))
+      {
+        sLine  = _T("sum(3)/sum(3,4,5)");
+        mup::console() << sLine << endl;
+      }
+
+      switch(CheckKeywords(sLine.c_str(), parser)) 
+      {
+      case  0: break;
+      case  1: continue;
+      case -1: return;
+      }
+    
+      parser.SetExpr(sLine);
+
+      // The returned result is of type Value, value is a Variant like
+      // type that can be either a boolean an integer or a floating point value
+      ans = parser.Eval();
+//      ans = parser.Eval();
+
+      // Value supports C++ streaming like this:
+      //console() << _T("Result (type: '" << ans.GetType() <<  "'):\n");
+      console() << _T("ans = ") << ans << _T("\n");
+
+      // Or if you need the specific type use this:
+      //switch (result.GetType())
+      //{
+      //case 's': cout << result.GetString() << " (string)" << "\n"; break;
+      //case 'i': cout << result.GetInt() << " (int)" << "\n"; break;
+      //case 'f': cout << result.GetFloat() << " (float)" << "\n"; break;
+      //case 'c': cout << result.GetFloat() << "+" << result.GetImag() << "i (complex)" << "\n"; break;
+      //case 'b': break;
+      //}
+    }
+    catch(ParserError &e)
+    {
+      if (e.GetPos()!=-1)
+      {
+        string_type sMarker;
+        sMarker.insert(0, sPrompt.size() + e.GetPos(), ' ');
+        sMarker += _T("^\n");
+        console() << sMarker;
+      }
+
+      console() << e.GetMsg() << _T(" (Errc: ") << e.GetCode() << _T(")") << _T("\n\n");
+
+      //if (e.GetContext().Ident.length()) 
+      //  console() << _T("Ident.: ") << e.GetContext().Ident << _T("\n");
+
+      //if (e.GetToken().length()) 
+      //  console() << _T("Token: \"") << e.GetToken() << _T("\"\n");
+    } // try / catch
+  } // for (;;)
+}
+
+//---------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+  SelfTest();
+
+  try
+  {
+    Calc();
+  }
+  catch(ParserError &e)
+  {
+    // Only erros raised during the initialization will end up here
+    // expression related errors are treated in Calc()
+    console() << _T("Initialization error:  ") << e.GetMsg() << endl;
+  }
+  catch(std::runtime_error &)
+  {
+    console() << _T("aborting...") << endl;
+  }
+  
+#ifdef MUP_LEAKAGE_REPORT  
+  IToken::LeakageReport();  
+#endif
+
+  return 0;
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/sample/timer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/sample/timer.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,52 @@
+
+#include "timer.h"
+
+#include <stdio.h>
+#include <time.h>
+
+#if defined(__WIN32__) || defined(WIN32)
+#include <Windows.h>
+DWORD tvs, tve;
+#else
+#include <sys/time.h>
+struct timeval	tvs, tve;
+#endif
+
+
+void StartTimer(void)
+{
+#if defined(__WIN32__) || defined(WIN32)
+  tvs = GetTickCount();
+#else
+  if (gettimeofday(&tvs,0)) fprintf(stderr,"cant get time!\n");
+#endif
+}
+
+double StopTimer(void)
+{
+#if defined(__WIN32__) || defined(WIN32)
+  tve = GetTickCount();
+  return tve - tvs;
+#else
+  if (gettimeofday(&tve,0)) fprintf(stderr,"cant get time!\n");
+  return 1000 * (tve.tv_sec - tvs.tv_sec + (double)(tve.tv_usec - tvs.tv_usec) / 1000000.0);
+#endif
+}
+
+double PrintTimer(void)
+{
+  double t;
+
+#if defined(__WIN32__) || defined(WIN32)
+  tve = GetTickCount();
+  t = (double)(tve - tvs) / 1000.0;
+  printf("%.3f ",t);
+  return t;
+#else
+  if (gettimeofday(&tve,0)) fprintf(stderr,"cant get time!\n");
+  t = 1000 * (tve.tv_sec - tvs.tv_sec + (double)(tve.tv_usec - tvs.tv_usec)/1000000.0);
+  printf("%.3f ",t);
+  return t;
+#endif
+}
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/sample/timer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/sample/timer.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,9 @@
+
+#ifndef timer_H
+#define timer_H
+
+void StartTimer(void);
+double StopTimer(void);
+double PrintTimer(void);
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/AssemblyInfo.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/AssemblyInfo.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,40 @@
+#include "stdafx.h"
+
+using namespace System;
+using namespace System::Reflection;
+using namespace System::Runtime::CompilerServices;
+using namespace System::Runtime::InteropServices;
+using namespace System::Security::Permissions;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly:AssemblyTitleAttribute("value_test")];
+[assembly:AssemblyDescriptionAttribute("")];
+[assembly:AssemblyConfigurationAttribute("")];
+[assembly:AssemblyCompanyAttribute("")];
+[assembly:AssemblyProductAttribute("value_test")];
+[assembly:AssemblyCopyrightAttribute("Copyright (c)  2011")];
+[assembly:AssemblyTrademarkAttribute("")];
+[assembly:AssemblyCultureAttribute("")];
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the value or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly:AssemblyVersionAttribute("1.0.*")];
+
+[assembly:ComVisible(false)];
+
+[assembly:CLSCompliantAttribute(true)];
+
+[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/ReadMe.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/ReadMe.txt	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,28 @@
+========================================================================
+    APPLICATION : value_test Project Overview
+========================================================================
+
+AppWizard has created this value_test Application for you.  
+
+This file contains a summary of what you will find in each of the files that
+make up your value_test application.
+
+value_test.vcproj
+    This is the main project file for VC++ projects generated using an Application Wizard. 
+    It contains information about the version of Visual C++ that generated the file, and 
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+value_test.cpp
+    This is the main application source file.
+
+AssemblyInfo.cpp
+	Contains custom attributes for modifying assembly metadata.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/UpgradeLog.XML
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/UpgradeLog.XML	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type='text/xsl' href='_UpgradeReport_Files/UpgradeReport.xslt'?><UpgradeLog>
+<Properties><Property Name="Solution" Value="value_test">
+</Property><Property Name="Solution File" Value="C:\Projekte\muparser_sf\branches\muParserX\value_test\value_test.sln">
+</Property><Property Name="User Options File" Value="C:\Projekte\muparser_sf\branches\muParserX\value_test\value_test.suo">
+</Property><Property Name="Date" Value="Montag, 22. August 2011">
+</Property><Property Name="Time" Value="18:49">
+</Property></Properties><Event ErrorLevel="0" Project="" Source="value_test.sln" Description="File successfully backed up as C:\Projekte\muparser_sf\branches\muParserX\value_test\value_test.sln.old">
+</Event><Event ErrorLevel="0" Project="" Source="value_test.suo" Description="File successfully backed up as C:\Projekte\muparser_sf\branches\muParserX\value_test\value_test.suo.old">
+</Event><Event ErrorLevel="0" Project="value_test" Source="value_test.vcproj" Description="Converting project file 'C:\Projekte\muparser_sf\branches\muParserX\value_test\value_test.vcproj'.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="VCWebServiceProxyGeneratorTool is no longer supported. The tool has been removed from your project settings.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="Attribute 'CopyLocalDependencies' of 'AssemblyReference' is not supported in this version and has been removed during conversion.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="Attribute 'UseDependenciesInBuild' of 'AssemblyReference' is not supported in this version and has been removed during conversion.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="Attribute 'CopyLocalDependencies' of 'AssemblyReference' is not supported in this version and has been removed during conversion.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="Attribute 'UseDependenciesInBuild' of 'AssemblyReference' is not supported in this version and has been removed during conversion.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="Attribute 'CopyLocalDependencies' of 'AssemblyReference' is not supported in this version and has been removed during conversion.">
+</Event><Event ErrorLevel="1" Project="value_test" Source="value_test.vcproj" Description="Attribute 'UseDependenciesInBuild' of 'AssemblyReference' is not supported in this version and has been removed during conversion.">
+</Event><Event ErrorLevel="0" Project="value_test" Source="value_test.vcproj" Description="Done converting to new project file 'C:\Projekte\muparser_sf\branches\muParserX\value_test\value_test.vcxproj'.">
+</Event><Event ErrorLevel="3" Project="value_test" Source="value_test.vcproj" Description="Converted">
+</Event><Event ErrorLevel="0" Project="" Source="value_test.sln" Description="Solution converted successfully">
+</Event><Event ErrorLevel="3" Project="" Source="value_test.sln" Description="Converted">
+</Event></UpgradeLog>
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/app.ico
Binary file muparserx/value_test/app.ico has changed
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/app.rc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/app.rc	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,63 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon placed first or with lowest ID value becomes application icon
+
+LANGUAGE 7, 1
+#pragma code_page(1252)
+1           ICON         "app.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE  
+BEGIN
+    "resource.h\0"
+    "\0"
+END
+
+2 TEXTINCLUDE  
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE  
+BEGIN
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpDefines.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpDefines.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,106 @@
+/** \file
+    \brief A file containing macros used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_DEFINES_H
+#define MUP_DEFINES_H
+
+#include <cassert>
+
+
+#if defined(_UNICODE)
+  #if !defined(_T)
+  #define _T(x) L##x
+  #endif // not defined _T
+  #define MUP_STRING_TYPE std::wstring
+#else
+  #ifndef _T
+  /** \brief Macro needed for the "unicodification" of strings.
+  */
+  #define _T(x) x
+  #endif
+  
+  /** \brief The string type used by muParserX. 
+  
+    This macro is needed for UNICODE support.
+  */
+  #define MUP_STRING_TYPE std::string
+#endif
+
+/** \brief A macro containing the version of muParserX. */
+#define MUP_PARSER_VERSION _T("1.10.1 (20110709)")
+
+/** \brief A macro for setting the parser namespace. */
+#define MUP_NAMESPACE_START namespace mup {
+
+/** \brief Closing bracket for the parser namespace macro. */
+#define MUP_NAMESPACE_END }
+
+/** \brief A macro for casting between different token types.
+    \param TYPE The token type
+    \param POINTER Pointer to the token object
+
+  This macro uses a dynamic_cast in debugbuilds and a static_cast
+  in release builds for doing the cast operation.
+*/
+#define MUP_TOK_CAST(TYPE, POINTER)  static_cast<TYPE>(POINTER);
+
+#if defined(_DEBUG)
+
+  /** \brief Debug macro to force an abortion of the programm with a certain message.
+  */
+  #define MUP_FAIL(MSG)    \
+          bool MSG=false;  \
+          assert(MSG);
+
+  /** \brief An assertion that does not kill the program.
+
+      This macro is neutralised in UNICODE builds. It's
+      too difficult to translate.
+  */
+  #define MUP_ASSERT(COND)                         \
+          if (!(COND))                             \
+          {                                        \
+            stringstream_type ss;                  \
+            ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \
+               << __FILE__ << _T(" line ")         \
+               << __LINE__ << _T(".");             \
+            throw ParserError( ss.str() );         \
+          }
+  #define MUP_LEAKAGE_REPORT
+#else
+  #define MUP_FAIL(MSG)
+  #define MUP_ASSERT(COND)
+#endif
+
+  /** \brief Include tests for features about to be implemented in 
+             the future in the unit test.
+  */
+  //#define MUP_NICE_TO_HAVE
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpError.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpError.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,307 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpError.h"
+#include "mpIToken.h"
+
+
+MUP_NAMESPACE_START
+
+  const ParserErrorMsg ParserErrorMsg::m_Instance;
+
+  //------------------------------------------------------------------------------
+  const ParserErrorMsg& ParserErrorMsg::Instance()
+  {
+    return m_Instance;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type ParserErrorMsg::operator[](unsigned a_iIdx) const
+  {
+    return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
+  }
+
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::~ParserErrorMsg()
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignement operator is deactivated.
+  */
+  ParserErrorMsg& ParserErrorMsg::operator=(const ParserErrorMsg& )
+  {
+    assert(false);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::ParserErrorMsg()
+    :m_vErrMsg(0)
+  {
+    m_vErrMsg.resize(ecCOUNT);
+
+    m_vErrMsg[ecUNASSIGNABLE_TOKEN]      = _T("Undefined token \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecINTERNAL_ERROR]          = _T("Internal error");
+    m_vErrMsg[ecINVALID_NAME]            = _T("Invalid function-, variable- or constant name");
+    m_vErrMsg[ecINVALID_FUN_PTR]         = _T("Invalid pointer to callback function");
+    m_vErrMsg[ecINVALID_VAR_PTR]         = _T("Invalid pointer to variable");
+    m_vErrMsg[ecUNEXPECTED_OPERATOR]     = _T("Unexpected operator \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_EOF]          = _T("Unexpected end of expression at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_COMMA]        = _T("Unexpected comma at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_PARENS  ]     = _T("Unexpected parenthesis \"$IDENT$\" at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_FUN]          = _T("Unexpected function \"$IDENT$\" at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_VAL]          = _T("Unexpected value \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_VAR]          = _T("Unexpected variable \"$IDENT$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_STR]          = _T("Unexpected string token found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_CONDITIONAL]  = _T("The \"$IDENT$\" operator must be preceeded by a closing bracket");
+    m_vErrMsg[ecUNEXPECTED_NEWLINE]      = _T("Unexprected newline");
+    m_vErrMsg[ecMISSING_PARENS]          = _T("Missing parenthesis");
+    m_vErrMsg[ecMISSING_ELSE_CLAUSE]     = _T("If-then-else operator is missing an else clause");
+    m_vErrMsg[ecMISPLACED_COLON]         = _T("Misplaced colon at position $POS$");
+    m_vErrMsg[ecTOO_MANY_PARAMS]         = _T("Too many parameters for function \"$IDENT$\"");
+    m_vErrMsg[ecTOO_FEW_PARAMS]          = _T("Too few parameters for function \"$IDENT$\"");
+    m_vErrMsg[ecDIV_BY_ZERO]             = _T("Divide by zero");
+    m_vErrMsg[ecDOMAIN_ERROR]            = _T("Domain error");
+    m_vErrMsg[ecNAME_CONFLICT]           = _T("Name conflict");
+    m_vErrMsg[ecOPT_PRI]                 = _T("Invalid value for operator priority (must be greater or equal to zero)");
+    m_vErrMsg[ecBUILTIN_OVERLOAD]        = _T("Binary operator identifier conflicts with a built in operator");
+    m_vErrMsg[ecUNTERMINATED_STRING]     = _T("Unterminated string starting at position $POS$");
+    m_vErrMsg[ecSTRING_EXPECTED]         = _T("String function called with a non string type of argument");
+    m_vErrMsg[ecVAL_EXPECTED]            = _T("Numerical function called with a non value type of argument");
+    m_vErrMsg[ecTYPE_CONFLICT]           = _T("Value \"$IDENT$\" is of type '$TYPE1$'. There is no implicit conversion to type '$TYPE2$'");
+    m_vErrMsg[ecTYPE_CONFLICT_FUN]       = _T("Argument $ARG$ of function/operator \"$IDENT$\" is of type '$TYPE1$' whereas type '$TYPE2$' was expected");
+    m_vErrMsg[ecTYPE_CONFLICT_IDX]       = _T("Index to variable \"$IDENT$\" must be a positive integer value");
+    m_vErrMsg[ecGENERIC]                 = _T("Parser error");
+    m_vErrMsg[ecINVALID_TYPE]            = _T("Invalid argument type");
+    m_vErrMsg[ecINVALID_TYPECAST]        = _T("Value type conversion from type '$TYPE1$' to '$TYPE2$' is not supported!");
+    m_vErrMsg[ecARRAY_SIZE_MISMATCH]     = _T("Array size mismatch");
+    m_vErrMsg[ecNOT_AN_ARRAY]            = _T("Using the index operator on the scalar variable \"$IDENT$\" is not allowed");
+    m_vErrMsg[ecUNEXPECTED_SQR_BRACKET]  = _T("Unexpected \"]\"");
+    m_vErrMsg[ecAPI_INVALID_PROTOTYPE]   = _T("Invalid prototype (use something like: \"f:fff\")");
+    m_vErrMsg[ecAPI_NOT_AN_ARRAY]        = _T("Not an array");
+    m_vErrMsg[ecAPI_INVALID_DIMENSION]   = _T("Invalid matrix dimensions");
+    m_vErrMsg[ecINDEX_OUT_OF_BOUNDS]     = _T("Index to variable \"$IDENT$\" is out of bounds");
+    m_vErrMsg[ecMISSING_SQR_BRACKET]     = _T("Missing \"]\"");
+    m_vErrMsg[ecASSIGNEMENT_TO_VALUE]    = _T("Assignment operator \"$IDENT$\" can't be used in this context");
+    m_vErrMsg[ecEVAL]                    = _T("Can't evaluate function/operator \"$IDENT$\": $HINT$");
+
+    #if defined(_DEBUG)
+      for (int i=0; i<ecCOUNT; ++i)
+        if (!m_vErrMsg[i].length())
+          assert(false);
+    #endif
+  }
+
+  //---------------------------------------------------------------------------
+  //
+  //  Error context
+  //
+  //---------------------------------------------------------------------------
+
+  /** \brief Constructs an empty Error context structure. */
+  ErrorContext::ErrorContext(EErrorCodes a_iErrc, 
+                             int a_iPos, 
+                             string_type a_sIdent)
+    :Expr()
+    ,Ident(a_sIdent)
+    ,Hint()
+    ,Errc(a_iErrc)
+    ,Type1(0)
+    ,Type2(0)
+    ,Arg(-1)
+    ,Pos(a_iPos)
+  {}
+
+  //---------------------------------------------------------------------------
+  ErrorContext::ErrorContext(EErrorCodes iErrc, 
+                             int iPos, 
+                             string_type sIdent,
+                             char_type cType1,
+                             char_type cType2,
+                             int nArg)
+    :Expr()
+    ,Ident(sIdent)
+    ,Hint()
+    ,Errc(iErrc)
+    ,Type1(cType1)
+    ,Type2(cType2)
+    ,Arg(nArg)
+    ,Pos(iPos)
+  {}
+
+  //---------------------------------------------------------------------------
+  //
+  //  ParserError class
+  //
+  //---------------------------------------------------------------------------
+
+  ParserError::ParserError()
+    :m_Err()
+    ,m_sMsg()
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {}
+
+  //------------------------------------------------------------------------------
+  ParserError::ParserError(const string_type &sMsg) 
+    :m_Err()
+    ,m_sMsg(sMsg)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {}
+
+  //------------------------------------------------------------------------------
+  ParserError::ParserError(const ErrorContext &a_Err) 
+    :m_Err(a_Err)
+    ,m_sMsg()
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    m_sMsg = m_ErrMsg[a_Err.Errc];
+  }
+
+  //------------------------------------------------------------------------------
+  ParserError::ParserError(const ParserError &a_Obj)
+    :m_Err(a_Obj.m_Err)
+    ,m_sMsg(a_Obj.m_sMsg)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {}
+
+  //------------------------------------------------------------------------------
+  ParserError& ParserError::operator=(const ParserError &a_Obj)
+  {
+    if (this==&a_Obj)
+      return *this;
+
+    m_sMsg = a_Obj.m_sMsg;
+    m_Err = a_Obj.m_Err;
+    return *this;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurences of a substring with another string. */
+  void ParserError::ReplaceSubString( string_type &sSource,
+                                      const string_type &sFind,
+                                      const string_type &sReplaceWith) const
+  {
+    string_type sResult;
+    string_type::size_type iPos(0), iNext(0);
+
+    for(;;)
+    {
+      iNext = sSource.find(sFind, iPos);
+      sResult.append(sSource, iPos, iNext-iPos);
+
+      if( iNext==string_type::npos )
+        break;
+
+      sResult.append(sReplaceWith);
+      iPos = iNext + sFind.length();
+    } 
+
+    sSource.swap(sResult);
+  }
+
+
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurences of a substring with another string. */
+  void ParserError::ReplaceSubString( string_type &sSource,
+                                      const string_type &sFind,
+                                      int iReplaceWith) const
+  {
+    stringstream_type stream;
+    stream << iReplaceWith;
+    ReplaceSubString(sSource, sFind, stream.str());
+  }
+  
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurences of a substring with another string. */
+  void ParserError::ReplaceSubString( string_type &sSource,
+                                      const string_type &sFind,
+                                      char_type cReplaceWith) const
+  {
+    stringstream_type stream;
+    stream << cReplaceWith;
+    ReplaceSubString(sSource, sFind, stream.str());
+  }
+  
+  //------------------------------------------------------------------------------
+  void ParserError::Reset()
+  {
+    m_sMsg = _T("");
+    m_Err = ErrorContext();
+  }
+      
+  //------------------------------------------------------------------------------
+  const string_type& ParserError::GetExpr() const 
+  {
+    return m_Err.Expr;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type ParserError::GetMsg() const
+  {
+    string_type sMsg(m_sMsg);
+    ReplaceSubString(sMsg, _T("$EXPR$"),  m_Err.Expr);
+    ReplaceSubString(sMsg, _T("$IDENT$"), m_Err.Ident);
+    ReplaceSubString(sMsg, _T("$POS$"),   m_Err.Pos);
+    ReplaceSubString(sMsg, _T("$ARG$"),   m_Err.Arg);
+    ReplaceSubString(sMsg, _T("$TYPE1$"), m_Err.Type1);
+    ReplaceSubString(sMsg, _T("$TYPE2$"), m_Err.Type2);
+    ReplaceSubString(sMsg, _T("$HINT$"),  m_Err.Hint);
+    return sMsg;
+  }
+
+  //------------------------------------------------------------------------------
+  ErrorContext& ParserError::GetContext()
+  {
+    return m_Err;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the expression position related to the error. 
+
+    If the error is not related to a distinct position this will return -1
+  */
+  int ParserError::GetPos() const
+  {
+    return m_Err.Pos;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return string related with this token (if available). */
+  const string_type& ParserError::GetToken() const
+  {
+    return m_Err.Ident;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the error code. */
+  EErrorCodes ParserError::GetCode() const
+  {
+    return m_Err.Errc;
+  }
+}  // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpError.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpError.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,201 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_ERROR_H
+#define MUP_ERROR_H
+
+#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <memory>
+
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+    /** \brief Error codes. 
+    
+      This is the complete list of all error codes used by muParserX
+    */
+    enum EErrorCodes
+    {
+      // Expression syntax errors
+      ecUNEXPECTED_OPERATOR    =  0, ///< Unexpected binary operator found
+      ecUNASSIGNABLE_TOKEN     =  1, ///< Token cant be identified.
+      ecUNEXPECTED_EOF         =  2, ///< Unexpected end of expression. (Example: "2+sin(")
+      ecUNEXPECTED_COMMA       =  3, ///< An unexpected comma has been found. (Example: "1,23")
+      ecUNEXPECTED_VAL         =  4, ///< An unexpected value token has been found
+      ecUNEXPECTED_VAR         =  5, ///< An unexpected variable token has been found
+      ecUNEXPECTED_PARENS      =  6, ///< Unexpected Parenthesis, opening or closing
+      ecUNEXPECTED_STR         =  7, ///< A string has been found at an inapropriate position
+      ecUNEXPECTED_CONDITIONAL =  8,
+      ecUNEXPECTED_NEWLINE     =  9, 
+      ecSTRING_EXPECTED        = 10, ///< A string function has been called with a different type of argument
+      ecVAL_EXPECTED           = 11, ///< A numerical function has been called with a non value type of argument
+      ecMISSING_PARENS         = 12, ///< Missing parens. (Example: "3*sin(3")
+      ecMISSING_ELSE_CLAUSE    = 13, 
+      ecMISPLACED_COLON        = 14,
+      ecUNEXPECTED_FUN         = 15, ///< Unexpected function found. (Example: "sin(8)cos(9)")
+      ecUNTERMINATED_STRING    = 16, ///< unterminated string constant. (Example: "3*valueof("hello)")
+      ecTOO_MANY_PARAMS        = 17, ///< Too many function parameters
+      ecTOO_FEW_PARAMS         = 18, ///< Too few function parameters. (Example: "ite(1<2,2)")
+      ecTYPE_CONFLICT          = 19, ///< Generic type conflict       
+      ecTYPE_CONFLICT_FUN      = 20, ///< Function argument type conflict.
+      ecTYPE_CONFLICT_IDX      = 21, ///< Function argument type conflict.
+      ecINVALID_TYPE           = 22,       
+      ecINVALID_TYPECAST       = 23, ///< Invalid Value token cast.
+      ecARRAY_SIZE_MISMATCH    = 24, ///< Array size mismatch during a vector operation
+      ecNOT_AN_ARRAY           = 25, ///< Using the index operator on a scalar variable
+      ecUNEXPECTED_SQR_BRACKET = 26, ///< Invalid use of the index operator 
+
+      // Invalid Parser input Parameters
+      ecINVALID_NAME           = 27, ///< Invalid function, variable or constant name.
+      ecBUILTIN_OVERLOAD       = 28, ///< Trying to overload builtin operator
+      ecINVALID_FUN_PTR        = 29, ///< Invalid callback function pointer 
+      ecINVALID_VAR_PTR        = 30, ///< Invalid variable pointer 
+
+      ecNAME_CONFLICT          = 31, ///< Name conflict
+      ecOPT_PRI                = 32, ///< Invalid operator priority
+      ecASSIGNEMENT_TO_VALUE   = 33, ///< Assignment to operator (3=4 instead of a=4)
+
+      // 
+      ecDOMAIN_ERROR           = 34, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
+      ecDIV_BY_ZERO            = 35, ///< Division by zero (currently unused)
+      ecGENERIC                = 36, ///< Generic error
+
+      ecAPI_INVALID_PROTOTYPE  = 37, ///< API error: tried to create a callback with an invalid prototype definition
+      ecAPI_NOT_AN_ARRAY       = 38, ///< Trying to access a non array type as an array
+      ecAPI_INVALID_DIMENSION  = 39, ///< Trying to access a non array type as an array
+      ecINDEX_OUT_OF_BOUNDS    = 40, ///< Array index is out of bounds
+      ecMISSING_SQR_BRACKET    = 41, ///< The index operator was not closed properly (i.e. "v[3")
+      ecEVAL                   = 42, ///< Error while evaluating function / operator
+
+      // internal errors
+      ecINTERNAL_ERROR         = 43, ///< Internal error of any kind.
+
+      // The last two are special entries 
+      ecCOUNT,                    ///< This is no error code, It just stores just the total number of error codes
+      ecUNDEFINED              = -1, ///< Undefined message, placeholder to detect unassigned error messages
+    };
+
+    //---------------------------------------------------------------------------
+    class ParserErrorMsg
+    {
+    public:
+        typedef ParserErrorMsg self_type;
+
+      ~ParserErrorMsg();
+
+        static const ParserErrorMsg& Instance();
+        string_type operator[](unsigned a_iIdx) const;
+
+    private:
+        std::vector<string_type>  m_vErrMsg;
+        static const self_type m_Instance;
+
+        ParserErrorMsg& operator=(const ParserErrorMsg &);
+        ParserErrorMsg(const ParserErrorMsg&);
+        ParserErrorMsg();
+    };
+
+    //---------------------------------------------------------------------------
+    /** \brief Error context class. 
+    
+       This struct contains the data associated with parser erros. 
+    */
+    struct ErrorContext
+    {
+      /** \brief Creates an empty ErrorContext object.
+      
+        All Members are initialised to an invalid state.
+      */
+      ErrorContext(EErrorCodes a_iErrc = ecUNDEFINED, 
+                   int a_iPos = -1, 
+                   string_type a_sIdent = string_type() );
+
+      ErrorContext(EErrorCodes a_iErrc, 
+                   int a_iPos, 
+                   string_type a_sIdent,
+                   char_type cType1,
+                   char_type cType2,
+                   int nArg);
+
+      string_type Expr;  ///> The expression string.
+      string_type Ident; ///> The identifier of the token that caused the error.
+      string_type Hint;  ///> Additional message
+      EErrorCodes Errc;  ///> The error code
+      char_type Type1;   ///> For type conflicts only! This is the type that was expected.
+      char_type Type2;   ///> For type conflicts only! This is the type that was actually found.
+      int Arg;           ///> The number of arguments that were expected.
+      int Pos;           ///> Position inside the expression where the error occured.
+    };
+
+    //---------------------------------------------------------------------------
+    /** \brief Error class of the parser. 
+        \author Ingo Berg
+
+      Part of the math parser package.
+    */
+    class ParserError
+    {
+    private:
+        //------------------------------------------------------------------------------
+        /** \brief Replace all ocuurences of a substring with another string. */
+        void ReplaceSubString(string_type &strSource, 
+                              const string_type &strFind,
+                              const string_type &strReplaceWith) const;
+        void ReplaceSubString(string_type &sSource,
+                              const string_type &sFind,
+                              int iReplaceWith) const;
+        void ReplaceSubString(string_type &sSource,
+                              const string_type &sFind,
+                              char_type cReplaceWith) const;
+        void Reset();
+
+    public:
+        ParserError();
+        ParserError(const string_type &sMsg);
+        ParserError(const ErrorContext &a_Err);
+        ParserError(const ParserError &a_Obj);
+        ParserError& operator=(const ParserError &a_Obj);
+
+        const string_type& GetExpr() const;
+        string_type GetMsg() const;
+        int GetPos() const;
+        const string_type& GetToken() const;
+        EErrorCodes GetCode() const;
+        ErrorContext& GetContext();
+
+    private:
+        ErrorContext m_Err;  ///< Error context data
+        string_type m_sMsg;  ///< The message string with all wildcards still in place.
+        const ParserErrorMsg &m_ErrMsg;
+    };		
+} // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpFwdDecl.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpFwdDecl.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,48 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MUP_FWD_DECL_H
+#define MUP_FWD_DECL_H
+
+#include "mpDefines.h"
+
+
+MUP_NAMESPACE_START
+
+  class ParserXBase;
+
+  class ICallback;
+  class IToken;
+  class IValue;
+  class IValueReader;
+  class IPrecedence;
+  class Value;
+  class ValueCache;
+
+  template<typename T>
+  class TokenPtr;
+
+MUP_NAMESPACE_END
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpIPrecedence.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpIPrecedence.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,50 @@
+/** \file mpIPrecedence.h
+    \brief Definition of base classes needed for parser operator definitions.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_IPRECEDENCE_H
+#define MUP_IPRECEDENCE_H
+
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Interface for binary and ternary operators
+      \ingroup binop
+  */
+  class IPrecedence
+  {
+  public:
+    virtual int GetPri() const = 0;
+    virtual EOprtAsct GetAssociativity() const = 0;
+  };
+}  // namespace mu
+
+#endif
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpIToken.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpIToken.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,315 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#include "mpIToken.h"
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <list>
+#include <cassert>
+
+#include "mpIPrecedence.h"
+
+MUP_NAMESPACE_START
+
+#ifdef MUP_LEAKAGE_REPORT
+  std::list<IToken*> IToken::s_Tokens;
+#endif
+
+#ifndef _UNICODE
+
+  //---------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is not defined.
+  */
+  std::ostream& operator<<(std::ostream &a_Stream, const IToken &tok)
+  {
+    return a_Stream << tok.ToString();
+  }  
+
+#else
+
+  //---------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is defined.
+  */
+  std::wostream& operator<<(std::wostream &a_Stream, const IToken &tok)
+  {
+    return a_Stream << tok.ToString();
+  }  
+#endif
+
+#ifdef MUP_LEAKAGE_REPORT
+
+  void IToken::LeakageReport()
+  {
+    using namespace std;
+
+    console() << "\n";     
+    console() << "Memory leakage report:\n\n";     
+    if (IToken::s_Tokens.size())
+    {
+      list<IToken*>::const_iterator item = IToken::s_Tokens.begin();
+      std::vector<int> stat(cmCOUNT, 0);
+      for (; item!=IToken::s_Tokens.end(); ++item)
+      {
+        console() << "Addr: 0x" << hex << *item << "  Ident: \"" << (*item)->GetIdent() << "\"";
+        console() << "\tCode: " << g_sCmdCode[(*item)->GetCode()] << "\n"; 
+        stat[(*item)->GetCode()]++;
+      }
+      console() << "Leaked tokens: " << dec << (int)IToken::s_Tokens.size() << std::endl;
+      
+      for (int i=0; i<cmCOUNT; ++i)
+        console() << g_sCmdCode[i] << ":" << stat[i] << "\n";
+
+      console() << endl;
+    }
+    else
+    {
+      console() << "No tokens leaked!\n";
+    }
+  }
+
+#endif
+
+  //------------------------------------------------------------------------------
+  IToken::IToken(ECmdCode a_iCode)
+    :m_eCode(a_iCode)
+    ,m_sIdent()
+    ,m_nPosExpr(-1)
+    ,m_nRefCount(0)
+    ,m_flags(0)
+  {
+#ifdef MUP_LEAKAGE_REPORT
+    IToken::s_Tokens.push_back(this);
+#endif
+  }
+
+  //------------------------------------------------------------------------------
+  IToken::IToken(ECmdCode a_iCode, string_type a_sIdent)
+    :m_eCode(a_iCode)
+    ,m_sIdent(a_sIdent)
+    ,m_nPosExpr(-1)
+    ,m_nRefCount(0)
+    ,m_flags(0)
+  {
+#ifdef MUP_LEAKAGE_REPORT
+    IToken::s_Tokens.push_back(this);
+#endif
+  }
+
+  /** \brief Destructor (trivial). */
+  IToken::~IToken()
+  {
+#ifdef MUP_LEAKAGE_REPORT
+    std::list<IToken*>::iterator it = std::find(IToken::s_Tokens.begin(), IToken::s_Tokens.end(), this);
+    IToken::s_Tokens.remove(this);
+#endif
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Copy constructor. 
+      \param ref The token to copy basic state information from.
+
+    The copy constructor must be implemented in order not to screw up
+    the reference count of the created object. CC's are used in the
+    Clone function and they would start with a reference count != 0 
+    introducing memory leaks if the default CC where used.
+  */
+  IToken::IToken(const IToken &ref)
+  {
+    m_eCode  = ref.m_eCode;
+    m_sIdent = ref.m_sIdent;
+    m_flags  = ref.m_flags;
+    m_nPosExpr = ref.m_nPosExpr;
+
+    // The following items must be initialised 
+    // (rather than just beeing copied)
+    m_nRefCount = 0;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::ResetRef()
+  {
+    m_nRefCount = 0;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::Release()
+  {
+    delete this;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type IToken::ToString() const
+  {
+    return AsciiDump();
+  }
+
+  //------------------------------------------------------------------------------
+  int IToken::GetExprPos() const
+  {
+    return m_nPosExpr;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::SetExprPos(int nPos)
+  {
+    m_nPosExpr = nPos;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief return the token code. 
+     
+      \sa ECmdCode
+  */
+  ECmdCode IToken::GetCode() const
+  {
+    return m_eCode;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the token identifier string. */
+  const string_type& IToken::GetIdent() const
+  {
+    return m_sIdent;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::SetIdent(const string_type &a_sIdent)
+  {
+    m_sIdent = a_sIdent;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type IToken::AsciiDump() const
+  {
+    stringstream_type ss;
+    ss << g_sCmdCode[m_eCode];
+    return ss.str().c_str();
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::IncRef() const
+  {
+    ++m_nRefCount;
+  }
+
+  //------------------------------------------------------------------------------
+  long IToken::DecRef() const
+  {
+    return --m_nRefCount;
+  }
+
+  //------------------------------------------------------------------------------
+  long IToken::GetRef() const
+  {
+    return m_nRefCount;
+  }
+
+  //---------------------------------------------------------------------------
+  void IToken::AddFlags(int flags)
+  {
+    m_flags |= flags;
+  }
+
+  //---------------------------------------------------------------------------
+  bool IToken::IsFlagSet(int flags) const
+  {
+    return (m_flags & flags)==flags;
+  }
+
+  //---------------------------------------------------------------------------
+  ICallback* IToken::AsICallback()
+  {
+    return NULL;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue* IToken::AsIValue()
+  {
+    return NULL;
+  }
+
+  //---------------------------------------------------------------------------
+  IPrecedence* IToken::AsIPrecedence()
+  {
+    return NULL;
+  }
+
+  //------------------------------------------------------------------------------
+  void IToken::Compile(const string_type &sArg)
+  {
+  }
+
+  //---------------------------------------------------------------------------
+  //
+  // Generic token implementation
+  //
+  //---------------------------------------------------------------------------
+
+  GenericToken::GenericToken(ECmdCode a_iCode, string_type a_sIdent)
+    :IToken(a_iCode, a_sIdent)
+  {}
+
+  //---------------------------------------------------------------------------
+  GenericToken::GenericToken(ECmdCode a_iCode)
+    :IToken(a_iCode, _T(""))
+  {}
+
+  //---------------------------------------------------------------------------
+  GenericToken::~GenericToken()
+  {}
+
+  //---------------------------------------------------------------------------
+  GenericToken::GenericToken(const GenericToken &a_Tok)
+    :IToken(a_Tok)
+  {}
+
+  //---------------------------------------------------------------------------
+  IToken* GenericToken::Clone() const
+  {
+    return new GenericToken(*this);
+  }
+  
+  //------------------------------------------------------------------------------
+  string_type GenericToken::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << _T("]");
+
+    return ss.str();
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpIToken.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpIToken.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,222 @@
+/*
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_ITOKEN_H
+#define MUP_ITOKEN_H
+
+#include <list>
+#include "mpTypes.h"
+#include "mpFwdDecl.h"
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Generic token interface for expression tokens. 
+      \author (C) 2010 Ingo Berg 
+
+      Tokens can either be Functions, operators, values, variables or necessary 
+      base tokens like brackets. ´The IToken baseclass implements reference 
+      counting. Only TokenPtr<...> templates may be used as pointers to tokens.
+  */
+  class IToken
+  {
+  friend std::ostream& operator<<(std::ostream &a_Stream, const IToken &a_Val);
+  friend std::wostream& operator<<(std::wostream &a_Stream, const IToken &a_Val);
+
+  friend class TokenPtr<IToken>;
+  friend class TokenPtr<IValue>;
+  friend class TokenPtr<IOprtBin>;
+  friend class TokenPtr<IFunction>;
+  friend class TokenPtr<Value>;
+  friend class TokenPtr<Variable>;
+
+  public:
+
+    enum EFlags
+    {
+      flNONE = 0,
+      flVOLATILE = 1
+    };
+
+    virtual IToken* Clone() const = 0;
+    virtual string_type ToString() const;
+    virtual string_type AsciiDump() const;
+    
+    virtual ICallback* AsICallback();
+    virtual IValue* AsIValue();
+    virtual IPrecedence* AsIPrecedence();
+
+    virtual void Compile(const string_type &sArg);
+
+    ECmdCode GetCode() const;
+    int GetExprPos() const;
+    
+    const string_type& GetIdent() const;
+    long GetRef() const;
+    void SetIdent(const string_type &a_sIdent);
+    void SetExprPos(int nPos);
+
+    void AddFlags(int flags);
+    bool IsFlagSet(int flags) const;
+
+  protected:
+
+    explicit IToken(ECmdCode a_iCode);
+    virtual ~IToken();
+    IToken(ECmdCode a_iCode, string_type a_sIdent);
+    IToken(const IToken &ref);
+
+    void ResetRef();
+
+  private:
+
+    /** \brief Release the token. 
+    
+      This Function either deletes the token or releases it to
+      the value cache for reuse without deletion.
+    */
+    virtual void Release();
+
+    void IncRef() const;
+    long DecRef() const;
+
+    ECmdCode m_eCode;
+    string_type m_sIdent;
+    int m_nPosExpr;           ///< Original position of the token in the expression
+    mutable long m_nRefCount; ///< Reference counter.
+    int m_flags;
+
+#ifdef MUP_LEAKAGE_REPORT
+    static std::list<IToken*> s_Tokens;
+
+  public:
+    static void LeakageReport();
+#endif
+  };
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Default token implentation. 
+  */
+  class GenericToken : public IToken
+  {
+  public:
+      GenericToken(ECmdCode a_iCode, string_type a_sIdent);
+      explicit GenericToken(ECmdCode a_iCode);
+      GenericToken(const GenericToken &a_Tok);      
+      virtual ~GenericToken();
+      virtual IToken* Clone() const;
+      virtual string_type AsciiDump() const;
+  };
+
+  //------------------------------------------------------------------------------
+  template<typename T>
+  class TokenPtr
+  {
+  public:
+     
+      typedef T* token_type;
+
+      //---------------------------------------------------------------------------
+      explicit TokenPtr(token_type p = 0)
+        :m_pTok(p)
+      {
+        if (m_pTok)
+          m_pTok->IncRef();
+      }
+
+      //---------------------------------------------------------------------------
+      TokenPtr(const TokenPtr &p)
+        :m_pTok(p.m_pTok)
+      {
+        if (m_pTok)
+          m_pTok->IncRef();
+      }
+
+      //---------------------------------------------------------------------------
+     ~TokenPtr()
+      {
+        if (m_pTok && m_pTok->DecRef()==0)
+          m_pTok->Release();
+      }
+
+      //---------------------------------------------------------------------------
+      token_type operator->() const
+      {
+        return static_cast<token_type>(m_pTok);
+      }
+  
+      //---------------------------------------------------------------------------
+      T& operator*() const
+      {
+        assert(m_pTok);
+        return *(static_cast<token_type>(m_pTok));
+      }
+
+      //---------------------------------------------------------------------------
+      token_type Get() const
+      {
+        return static_cast<token_type>(m_pTok);
+      }
+
+      //---------------------------------------------------------------------------
+      /** \brief Release the managed pointer and assign a new pointer. */
+      void Reset(token_type tok)
+      {
+        if (m_pTok && m_pTok->DecRef()==0) 
+        {
+          m_pTok->Release();
+          //delete m_pTok;
+        }
+
+        tok->IncRef();
+        m_pTok = tok;
+      }
+
+      //---------------------------------------------------------------------------
+      TokenPtr& operator=(const TokenPtr &p)
+      {
+        if (p.m_pTok) 
+          p.m_pTok->IncRef();
+
+        if (m_pTok && m_pTok->DecRef()==0) 
+        {
+          m_pTok->Release();
+          //delete m_pTok;
+        }
+
+        m_pTok = p.m_pTok;
+
+        return *this;
+      }
+
+  private:
+      IToken *m_pTok;
+  };
+
+MUP_NAMESPACE_END
+
+#endif // include guard
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpIValReader.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpIValReader.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,85 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef MU_IPARSER_VALUE_READER_H
+#define MU_IPARSER_VALUE_READER_H
+
+#include "mpValue.h"
+#include "mpIToken.h"
+#include "mpTokenReader.h"
+
+
+MUP_NAMESPACE_START
+
+  class TokenReader;
+
+  /** \brief Interface for custom value reader objects. 
+  
+    Value readers are objects used for identifying values 
+    in an expression.
+  */
+  class IValueReader
+  {
+  public:
+
+    IValueReader();
+    IValueReader(const IValueReader &ref);
+
+    virtual ~IValueReader();
+
+    /** \brief Check a certain position in an expression for the presence of a value. 
+        \param a_iPos [in/out] Reference to an integer value representing the current 
+                      position of the parser in the expression.
+        \param a_Val If a value is found it is stored in a_Val
+        \return true if a value was found
+    */
+    virtual bool IsValue(const char_type *a_szExpr,
+                         int &a_iPos, 
+                         Value &a_Val ) = 0;
+
+    /** \brief Clone this ValueReader object. 
+        \return Pointer to the cloned value reader object.
+    */
+    virtual IValueReader* Clone(TokenReader *pParent) const = 0;
+    
+    /** \brief Assign this value reader object to a token 
+               reader object. 
+    
+      The token reader does the tokenization of the expression.
+      It uses this value reader to detect values.
+    */
+    virtual void SetParent(TokenReader *pTokenReader);
+
+  protected:
+
+    const IToken* TokenHistory(std::size_t pos) const;
+
+  private:
+
+    TokenReader *m_pTokenReader;  ///< Pointer to the TokenReader class used for token recognition
+  }; // class IValueReader
+
+MUP_NAMESPACE_END
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpIValue.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpIValue.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,415 @@
+/** \file
+    \brief Implementation of the virtual base class used for all parser values.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpIValue.h"
+
+//--- Standard includes ---------------------------------------------------------------------------
+#include <cassert>
+
+//--- muParserX framework -------------------------------------------------------------------------
+#include "mpError.h"
+#include "mpValue.h"
+
+
+MUP_NAMESPACE_START
+
+#ifndef _UNICODE
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is not defined.
+  */
+  std::ostream& operator<<(std::ostream &a_Stream, const IValue &a_Val)
+  {
+    return a_Stream << a_Val.ToString();
+  }  
+
+#else
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Overloaded streaming operator for outputting the value type 
+             into an std::ostream. 
+      \param a_Stream The stream object
+      \param a_Val The value object to be streamed
+
+    This function is only present if _UNICODE is defined.
+  */
+  std::wostream& operator<<(std::wostream &a_Stream, const IValue &a_Val)
+  {
+    return a_Stream << a_Val.ToString();
+  }  
+#endif
+
+  //-----------------------------------------------------------------------------------------------
+  IValue::IValue(ECmdCode a_iCode)
+    :IToken(a_iCode)
+  {
+    assert(a_iCode==cmVAL || a_iCode==cmVAR);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue::IValue(ECmdCode a_iCode, const string_type &a_sIdent)
+    :IToken(a_iCode, a_sIdent)
+  {
+    assert(a_iCode==cmVAL || a_iCode==cmVAR);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue::~IValue()
+  {}
+
+  //-----------------------------------------------------------------------------------------------
+  ICallback* IValue::AsICallback()
+  {
+    return NULL;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue* IValue::AsIValue()
+  {
+    return this;
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  string_type IValue::ToString() const
+  {
+    stringstream_type ss;
+    switch (GetType())
+    {
+    case 'a':  
+               {
+                 const array_type &arr(GetArray());
+                 ss << _T("["); 
+                 for (std::size_t i=0; i<arr.size(); ++i)
+                 {
+                   ss << arr[i];
+                   if (i!=arr.size()-1)
+                   {
+                     if (arr[i].GetType()!='a')
+                       ss << _T("; ");
+                     else
+                       ss << _T("\n ");
+                   }
+                 }
+                 ss << _T("]"); 
+               }
+               break;
+    case 'c':
+              {
+                float_type re = GetFloat(),
+                           im = GetImag();
+								
+								// realteil nicht ausgeben, wenn es eine rein imaginäre Zahl ist
+								if (im==0 || re!=0 || (im==0 && re==0))
+									ss << re;
+
+                if (im!=0)
+                {
+	                if (im>0 && re!=0)
+	                  ss << _T("+");
+									
+									if (im!=1)
+	                  ss << im;
+
+                  ss << _T("i");
+                }
+              }
+              break;
+            
+    case 'i':  
+    case 'f':  ss << GetFloat(); break;
+    case 's':  ss << _T("\"") << GetString() << _T("\""); break;
+    case 'b':  ss << ((GetBool()==true) ? _T("true"):_T("false")); break;
+    case 'v':  ss << _T("void"); break;
+    default:   ss << _T("internal error: unknown value type."); break;
+    }
+
+    return ss.str();
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool IValue::operator==(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 'i': 
+      case 'f': return GetFloat()   == a_Val.GetFloat();
+      case 'c': return GetComplex() == a_Val.GetComplex();
+      case 's': return GetString()  == a_Val.GetString();
+      case 'b': return GetBool()    == a_Val.GetBool();
+      case 'v': return false;
+      case 'a': if (GetDim()!=a_Val.GetDim())
+                {
+                  return false;
+                }
+                else
+                {
+                  for (std::size_t i=0; i<GetDim(); ++i)
+                  {
+                    if (const_cast<IValue*>(this)->operator[](i)!=const_cast<IValue&>(a_Val)[i])
+                      return false;
+                  }
+
+                  return true;
+                }
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+      } // switch this type
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool IValue::operator!=(const IValue &a_Val) const
+  {
+      char_type type1 = GetType(),
+                type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() != a_Val.GetString();
+      case 'i': 
+      case 'f': return GetFloat() != a_Val.GetFloat();
+      case 'c': return (GetFloat() != a_Val.GetFloat()) || (GetImag() != a_Val.GetImag());
+      case 'b': return GetBool() != a_Val.GetBool();
+      case 'v': return true;
+      case 'a': if (GetDim()!=a_Val.GetDim())
+                {
+                  return true;
+                }
+                else
+                {
+                  for (std::size_t i=0; i<GetDim(); ++i)
+                  {
+                    if (const_cast<IValue*>(this)->operator[](i)!=const_cast<IValue&>(a_Val)[i])
+                      return true;
+                  }
+
+                  return false;
+                }
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type2 = GetType();
+                err.Type1 = a_Val.GetType();
+                throw ParserError(err);
+      } // switch this type
+    }
+    else
+    {
+      return true;
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool IValue::operator<(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() < a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() < a_Val.GetFloat();
+      case 'b': return GetBool() < a_Val.GetBool();
+                
+      default: 
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool IValue::operator> (const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() > a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() > a_Val.GetFloat();
+      case 'b': return GetBool()  > a_Val.GetBool();
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool IValue::operator>=(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() >= a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() >= a_Val.GetFloat();
+      case 'b': return GetBool() >= a_Val.GetBool();
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  bool IValue::operator<=(const IValue &a_Val) const
+  {
+    char_type type1 = GetType(),
+              type2 = a_Val.GetType(); 
+
+    if (type1==type2 || IsScalar() && a_Val.IsScalar())
+    {
+      switch(GetType())
+      {
+      case 's': return GetString() <= a_Val.GetString();
+      case 'i': 
+      case 'f': 
+      case 'c': return GetFloat() <= a_Val.GetFloat();
+      case 'b': return GetBool()  <= a_Val.GetBool();
+      default:  
+                ErrorContext err;
+                err.Errc = ecINTERNAL_ERROR;
+                err.Pos = -1;
+                err.Type1 = GetType();
+                err.Type2 = a_Val.GetType();
+                throw ParserError(err);
+
+      } // switch this type
+    }
+    else
+    {
+      ErrorContext err;
+      err.Errc    = ecTYPE_CONFLICT_FUN;
+      err.Arg     = (type1!='f' && type1!='i') ? 1 : 2;
+      err.Type1   = type2;
+      err.Type2   = type1;
+      throw ParserError(err);
+    }
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  IValue& IValue::operator=(const IValue &ref)
+  {
+    if (this==&ref)
+      return *this;
+
+    switch(ref.GetType())
+    {
+    case 'i': 
+    case 'f': 
+    case 'c': return *this = cmplx_type(ref.GetFloat(), ref.GetImag());
+    case 's': return *this = ref.GetString();
+    case 'a': return *this = ref.GetArray();
+    case 'b': return *this = ref.GetBool();
+    case 'v': 
+      throw ParserError(_T("Assignment from void type is not possible"));
+
+    default:  
+      throw ParserError(_T("Internal error: unexpected data type identifier in IValue& operator=(const IValue &ref)"));
+    }
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpIValue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpIValue.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,155 @@
+/** \file
+    \brief Definition of the virtual base class used for all parser values.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_IVALUE_H
+#define MUP_IVALUE_H
+
+#include "mpIToken.h"
+#include "mpFwdDecl.h"
+
+MUP_NAMESPACE_START
+
+  //-----------------------------------------------------------------------------------------------
+  /** \brief Interface to be implemented by all classes representing values. 
+  
+    IValue is the common base class of both the Value and Variable classes.
+  */
+  class IValue : public IToken
+  {
+  friend std::ostream& operator<<(std::ostream &a_Stream, const IValue &a_Val);
+  friend std::wostream& operator<<(std::wostream &a_Stream, const IValue &a_Val);
+
+  public:
+
+    explicit IValue(ECmdCode a_iCode);
+    IValue(ECmdCode a_iCode, const string_type &a_sIdent);
+    
+    bool operator==(const IValue &a_Val) const;
+    bool operator!=(const IValue &a_Val) const;
+    bool operator< (const IValue &a_Val) const;
+    bool operator> (const IValue &a_Val) const;
+    bool operator<=(const IValue &a_Val) const;
+    bool operator>=(const IValue &a_Val) const;
+
+    virtual ICallback* AsICallback();
+    virtual IValue* AsIValue();
+    virtual Value* AsValue() = 0;
+
+    virtual IValue& operator=(int_type val) = 0;
+    virtual IValue& operator=(float_type val) = 0;
+    virtual IValue& operator=(string_type val) = 0;
+    virtual IValue& operator=(bool_type val) = 0;
+    virtual IValue& operator=(const cmplx_type &val) = 0;
+    virtual IValue& operator=(const array_type &val) = 0;
+            IValue& operator=(const IValue &ref);
+
+    virtual IValue& operator[](std::size_t idx) = 0;
+    virtual int_type GetInteger() const = 0;
+    virtual float_type GetFloat() const = 0;
+    virtual float_type GetImag() const = 0;
+    virtual bool GetBool() const = 0;
+    virtual const cmplx_type& GetComplex() const = 0;
+    virtual const string_type&  GetString() const = 0;
+    virtual const array_type& GetArray() const = 0;
+    virtual char_type GetType() const = 0;
+
+    virtual bool IsVolatile() const = 0;
+    virtual string_type ToString() const;
+    
+    //---------------------------------------------------------------------------
+    inline std::size_t GetDim() const
+    {
+      return (GetType()!='a') ? 1 : GetArray().size();
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if the type is either floating point or interger. 
+        \throw nothrow
+    */
+    inline bool IsNonComplexScalar() const
+    {
+      char_type t = GetType();
+      return t=='f' || t=='i';
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if the type is not a vector and not a string.
+        \throw nothrow
+    */
+    inline bool IsScalar() const
+    {
+      char_type t = GetType();
+      return t=='f' || t=='i' || t=='c';
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is a noncomplex integer. 
+        \throw nothrow
+    */
+    inline bool IsInteger() const
+    {
+      // checking the type is is insufficient. The integer could be disguised
+      // as a float or a complex value
+      return IsScalar() && GetImag()==0 && GetFloat()==(int_type)GetFloat();
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is an array. 
+        \throw nothrow
+    */  
+    inline bool IsArray() const 
+    {
+      return GetType() == 'a';  
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is a complex value. 
+        \throw nothrow
+    */
+    inline bool IsComplex() const
+    {
+      return GetType() == 'c' && GetImag()!=0;
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Returns true if this value is a string value. 
+        \throw nothrow
+    */
+    inline bool IsString() const 
+    {
+      return GetType() == 's';  
+    }
+
+  protected:
+    virtual ~IValue();
+  }; // class IValue
+}  // namespace mu
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpTypes.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpTypes.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,309 @@
+/** \file
+    \brief Definition of basic types used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#ifndef MUP_TYPES_H
+#define MUP_TYPES_H
+
+//--- Standard include ------------------------------------------------------
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <complex>
+
+//--- muParserX framework ---------------------------------------------------
+#include "suSortPred.h"  // We need the string utils sorting predicates
+#include "mpDefines.h"
+
+
+MUP_NAMESPACE_START
+
+// Forward declarations
+  class IValueReader;
+  class IOprtBin;
+  class IOprtPostfix;
+  class IOprtInfix;
+  class IFunction;
+  class IToken;
+  class IValue;
+  class ParserXBase;
+  class Value;
+  class Variable;
+  class TokenReader;
+
+  // smart pointer types
+  template<typename T>
+  class TokenPtr;
+
+  /** \brief Type of a managed pointer storing parser tokens. */
+  typedef TokenPtr<IToken>   ptr_tok_type;
+
+  /** \brief Type of a managed pointer storing value tokens. */
+  typedef TokenPtr<IValue>   ptr_val_type;
+
+  /** \brief Type of a managed pointer storing binary operator tokens. */
+  typedef TokenPtr<IOprtBin> ptr_binop_type;
+
+  /** \brief Type for a vector of tokens. */
+  typedef std::vector<ptr_tok_type> token_vec_type;
+
+  /** \brief Type for a vector of value items. */
+  typedef std::vector<ptr_val_type> val_vec_type;
+
+  // parser type definitions
+
+  /** \brief Parser datatype for floating point value. */
+  typedef /*long*/ double float_type;
+
+  /** \brief Parser datatype for integer valuse. */
+  typedef int int_type;
+
+  /** \brief The basic type used for representing complex numbers. */
+  typedef std::complex<float_type> cmplx_type;
+
+  /** \brief Parser boolean datatype. 
+
+      This must be bool! The only reason for this typedef is that I need the name bool_type
+      for a preprocessor macro definition to avoid inconsistent naming of the macro parameters.
+  */
+  typedef bool bool_type;   
+
+  /** \brief The parsers array type. */
+  typedef std::vector<Value> array_type;
+
+  /** \brief Parser datatype for strings. */
+  typedef MUP_STRING_TYPE string_type;
+
+  /** \brief Character type of the parser. */
+  typedef string_type::value_type char_type;
+
+  typedef std::basic_stringstream<char_type, 
+                                  std::char_traits<char_type>,
+                                  std::allocator<char_type> > stringstream_type;
+
+  /** \brief Type of a vector holding pointers to value reader objects. */
+  typedef std::vector<IValueReader*> readervec_type;
+
+  /** \brief type for the parser variable storage. */
+  typedef std::map<string_type, ptr_tok_type> var_maptype;  
+
+  /** \brief type of a container used to store parser values.  */
+  typedef std::map<string_type, ptr_tok_type> val_maptype;
+
+  /** \brief Type of a container that binds Callback object pointer
+             to operator identifiers. */
+  typedef std::map<string_type, ptr_tok_type> fun_maptype;
+
+  /** \brief Type of a container that binds Callback object pointer
+             to operator identifiers. */
+  typedef std::map<string_type, ptr_tok_type, su::pred::SortByLength<string_type> > oprt_bin_maptype;
+
+  typedef std::multimap<string_type, ptr_tok_type, su::pred::SortByLength<string_type> > oprt_bin_multimap;
+
+  /** \brief Type of a map for storing postfix operators by their name. */
+  typedef std::map<string_type, ptr_tok_type> oprt_pfx_maptype;
+
+  /** \brief Type of a map for storing infix operators by their name. */
+  typedef std::map<string_type, ptr_tok_type> oprt_ifx_maptype;
+
+  //------------------------------------------------------------------------------
+  /** \brief Bytecode values.
+      \attention The order of the operator entries must match the order in 
+                 ParserXBase::c_DefaultOprt!
+  */
+  enum ECmdCode
+  {
+    // The following are codes for built in binary operators
+    // apart from built in operators the user has the opportunity to
+    // add user defined operators.
+    cmBO                =  0,  ///< Operator item:  opening bracket
+    cmBC                =  1,  ///< Operator item:  closing bracket
+    cmIO                =  2,  ///< Operator item:  index operator opening
+    cmIC                =  3,  ///< Operator item:  index operator closing
+    cmARG_SEP           =  4,  ///< Operator item:  comma
+    cmIF                =  5,  ///< Ternary if then else operator
+    cmELSE              =  6,  ///< Ternary if then else operator 
+    cmENDIF             =  7,  ///< Ternary if then else operator 
+    cmJMP               =  8,  ///< Reserved for future use
+    cmVAR               =  9,  ///< variable item
+    cmVAL               = 10,  ///< value item
+    cmFUNC              = 11,  ///< Code for a function item
+    cmOPRT_BIN          = 12,  ///< Binary operator
+    cmOPRT_INFIX        = 13,  ///< Infix operator
+    cmOPRT_POSTFIX      = 14,  ///< Postfix operator
+    cmEOE               = 15,  ///< End of expression
+
+    // The following codes are reserved in case i will ever turn this
+    // into a scripting language
+    cmSCRIPT_GOTO       = 16,  ///< Reserved for future use
+    cmSCRIPT_LABEL      = 17,  ///< Reserved for future use
+    cmSCRIPT_FOR        = 18,  ///< Reserved for future use
+    cmSCRIPT_IF         = 19,  ///< Reserved for future use
+    cmSCRIPT_ELSE       = 20,  ///< Reserved for future use
+    cmSCRIPT_ELSEIF     = 21,  ///< Reserved for future use
+    cnSCRIPT_ENDIF      = 22,  ///< Reserved for future use
+    cmSCRIPT_NEWLINE    = 23,  ///< Newline
+    cmSCRIPT_FUNCTION   = 24,  ///< Reserved for future use
+
+    // misc codes
+    cmUNKNOWN           = 25,  ///< uninitialized item
+    cmCOUNT             = 26   ///< Dummy entry for counting the enum values
+  }; // ECmdCode
+
+
+  //------------------------------------------------------------------------------
+  /** \brief Strings assigned to the enum codes of ECmdCode. 
+
+      Used for debugging purposes only.
+  */
+  extern const char_type *g_sCmdCode[];
+
+  //------------------------------------------------------------------------------
+  enum EPackages
+  {
+    pckCOMMON          = 1 << 0,
+    pckUNIT            = 1 << 1,
+    pckCOMPLEX         = 1 << 2,
+    pckNON_COMPLEX     = 1 << 3,
+    pckSTRING          = 1 << 4,
+    pckALL_COMPLEX     = pckCOMMON | pckCOMPLEX | pckSTRING | pckUNIT,
+    pckALL_NON_COMPLEX = pckCOMMON | pckNON_COMPLEX | pckSTRING | pckUNIT
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Syntax codes. 
+
+    The syntax codes control the syntax check done during the first time parsing of 
+    the expression string. They are flags that indicate which tokens are allowed next
+    if certain tokens are identified.
+  */
+  enum ESynCodes
+  {
+    noBO      = 1 <<  0,  ///< to avoid i.e. "cos(7)(" 
+    noBC      = 1 <<  1,  ///< to avoid i.e. "sin)" or "()"
+    noIO      = 1 <<  2,  ///< No opening bracket "["
+    noIC      = 1 <<  3,  ///< No closing bracket "]"
+    noVAL     = 1 <<  4,  ///< to avoid i.e. "tan 2" or "sin(8)3.14"
+    noVAR     = 1 <<  5,  ///< to avoid i.e. "sin a" or "sin(8)a"
+    noCOMMA   = 1 <<  6,  ///< to avoid i.e. ",," or "+," ...
+    noFUN     = 1 <<  7,  ///< to avoid i.e. "sqrt cos" or "(1)sin"	
+    noOPT     = 1 <<  8,  ///< to avoid i.e. "(+)"
+    noPFX     = 1 <<  9,  ///< to avoid i.e. "(5!!)" "sin!"
+    noIFX     = 1 << 10,  ///< to avoid i.e. "++4" "!!4"
+    noEND     = 1 << 11,  ///< to avoid unexpected end of expression
+    noIF      = 1 << 12,  
+    noELSE    = 1 << 13,  
+    noNEWLINE = 1 << 14,  ///< to avoid i.e. "a+\nb" or "sin(\na)"
+
+    sfSTART_OF_LINE = noOPT | noBC | noPFX | noCOMMA | noIO | noIC | noIF | noELSE,
+    sfALLOW_NONE    = ~0        ///< All of he above flags set
+  };	
+
+  //------------------------------------------------------------------------------
+  /** \brief Binary operator associativity values. */
+  enum EOprtAsct
+  {
+    oaNONE  = 0,
+    oaLEFT  = 1,
+    oaRIGHT = 2,
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser operator precedence values. 
+  
+    These are predefined values for the operator precedence.
+  */
+  enum EOprtPrecedence
+  {
+    // assignment operators
+    prASSIGN       = -1,
+
+    // if-then-else
+    prIF_THEN_ELSE =  0,
+
+    // binary operators
+    prLOGIC_OR     =  1,
+    prLOGIC_AND    =  2,
+    prBIT_OR       =  3,
+    prBIT_AND      =  4, 
+
+    prRELATIONAL1  =  5, ///< For "==", "!=" 
+    prRELATIONAL2  =  6, ///< Relational operators "<", "<=", ">", ">="
+    prSHIFT        =  7, ///< Shift operators "<<", ">>"
+
+    prADD_SUB      =  8, ///< addition
+    prMUL_DIV      =  9, ///< multiplication/division
+    prPOW          = 10, ///< power operator priority (highest)
+
+    // infix operators
+    prINFIX        =  9, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
+    prPOSTFIX      =  9  ///< Postfix operator priority (currently unused)
+  };
+
+#if defined(_UNICODE)
+
+  //------------------------------------------------------------------------------
+  /** \brief Encapsulate wcout. */
+  inline std::wostream& console()
+  {
+    return std::wcout;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Encapsulate cin. */
+  inline std::wistream& console_in()
+  {
+    return std::wcin;
+  }
+
+#else
+
+  /** \brief Encapsulate cout. 
+  
+    Used for supporting UNICODE more easily.
+  */
+  inline std::ostream& console()
+  {
+    return std::cout;
+  }
+
+  /** \brief Encapsulate cin. 
+
+    Used for supporting UNICODE more easily.
+  */
+  inline std::istream& console_in()
+  {
+    return std::cin;
+  }
+
+#endif // _UNICODE
+
+}  // namespace mu
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpValue.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpValue.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,640 @@
+/*
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpValue.h"
+#include "mpError.h"
+#include "mpValueCache.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Construct an empty value object of a given type. 
+      \param cType The type of the value to construct (default='v').
+  */
+  Value::Value(char_type cType)
+    :IValue(cmVAL)
+    ,m_val(0,0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType(cType)
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {
+    // strings and arrays must allocate their memory
+    switch (cType)
+    {
+    case 's': m_psVal = new string_type(); break;
+    case 'a': m_pvVal = new array_type(0, Value(0)); break;
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(int_type a_iVal)
+    :IValue(cmVAL)
+    ,m_val((float_type)a_iVal, 0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('i')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(bool_type a_bVal)
+    :IValue(cmVAL)
+    ,m_val((float_type)a_bVal, 0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('b')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(string_type a_sVal)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(new string_type(a_sVal))
+    ,m_pvVal(NULL)
+    ,m_cType('s')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(int_type array_size, float_type val)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(NULL)
+    ,m_pvVal(new array_type(array_size, Value(val)))
+    ,m_cType('a')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(int_type m, int_type n, float_type val)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('a')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {
+/*
+    <ibg 20110808> Neuer Code für zukünftige Matriximplementierung
+    if (m<=0 || n<=0)
+      throw ParserError( ErrorContext(ecAPI_INVALID_DIMENSIONS) ); 
+  
+    m_pVal = new array_type(m*n, Value()); 
+    for (int_type i=0; i<n; ++i)
+    {
+      (*m_pvVal)[i] = Value(val);
+    }
+*/
+    m_pvVal = new array_type(n, Value()); 
+    for (int_type i=0; i<n; ++i)
+    {
+      (*m_pvVal)[i] = Value(m, val);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(const char_type *a_szVal)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(new string_type(a_szVal))
+    ,m_pvVal(NULL)
+    ,m_cType('s')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const cmplx_type &v)
+    :IValue(cmVAL)
+    ,m_val(v)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType('c')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {
+    if ( (m_val.real()==(int_type)m_val.real()) && (m_val.imag()==0) )
+      m_cType = 'i';
+    else
+      m_cType = (m_val.imag()==0) ? 'f' : 'c';
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(float_type val)
+    :IValue(cmVAL)
+    ,m_val(val, 0)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_cType((val==(int_type)val) ? 'i' : 'f')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const array_type &val)
+    :IValue(cmVAL)
+    ,m_val()
+    ,m_psVal(NULL)
+    ,m_pvVal(new array_type(val))
+    ,m_cType('a')
+    ,m_iFlags(flNONE)
+    ,m_pCache(NULL)
+  {}
+
+  //---------------------------------------------------------------------------
+  Value::Value(const Value &a_Val)
+    :IValue(cmVAL)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_pCache(NULL)
+  {
+    Assign(a_Val);
+  }
+
+  //---------------------------------------------------------------------------
+  Value::Value(const IValue &a_Val)
+    :IValue(cmVAL)
+    ,m_psVal(NULL)
+    ,m_pvVal(NULL)
+    ,m_pCache(NULL)
+  {
+    Reset();
+
+    switch(a_Val.GetType())
+    {
+    case 'i': 
+    case 'f': 
+    case 'b': m_val = cmplx_type(a_Val.GetFloat(), 0);
+              break;
+
+
+    case 'c': m_val = cmplx_type(a_Val.GetFloat(), a_Val.GetImag());
+              break;
+
+    case 's': if (!m_psVal)
+                m_psVal = new string_type(a_Val.GetString());
+              else
+               *m_psVal = a_Val.GetString();
+              break;
+
+    case 'a': if (!m_pvVal) 
+                m_pvVal = new array_type(a_Val.GetArray());
+              else
+               *m_pvVal  = a_Val.GetArray();  
+              break;
+
+    case 'v': break;
+    default:  MUP_FAIL(INVALID_TYPE_CODE);
+    }
+    
+    m_cType = a_Val.GetType();
+  }
+
+  //---------------------------------------------------------------------------
+  Value& Value::operator=(const Value &a_Val)
+  {
+    Assign(a_Val);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator[](std::size_t i)
+  {
+    if (m_cType!='a' || m_pvVal==NULL)
+      throw ParserError( ErrorContext(ecAPI_NOT_AN_ARRAY) ); 
+
+    if (i>=m_pvVal->size())
+      throw ParserError( ErrorContext(ecINDEX_OUT_OF_BOUNDS) ); 
+
+    return (*m_pvVal)[i];
+  }
+
+  //---------------------------------------------------------------------------
+  Value::~Value()
+  {
+    delete m_psVal;
+    delete m_pvVal;
+  }
+
+  //---------------------------------------------------------------------------
+  IToken* Value::Clone() const
+  {
+    return new Value(*this);
+  }
+
+  //---------------------------------------------------------------------------
+  Value* Value::AsValue()
+  {
+    return this;
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::Assign(const Value &ref)
+  {
+    if (this==&ref)
+      return;
+
+    m_val   = ref.m_val;
+
+    // allocate room for a string
+    if (ref.m_psVal)
+    {
+      if (!m_psVal)
+        m_psVal = new string_type(*ref.m_psVal);
+      else
+       *m_psVal = *ref.m_psVal;
+    }
+    else
+    {
+      delete m_psVal;
+      m_psVal = NULL;
+    }
+
+    // allocate room for a vector
+    if (ref.m_pvVal)
+    {
+      if (m_pvVal==NULL)
+        m_pvVal = new array_type(*ref.m_pvVal);
+      else
+       *m_pvVal = *ref.m_pvVal;
+    }
+    else
+    {
+      delete m_pvVal;
+      m_pvVal = NULL;
+    }
+
+    m_cType  = ref.m_cType;
+    m_iFlags = ref.m_iFlags;
+
+    // Do not copy the value cache pointer!
+    // Value cache should be assigned expplicitely and
+    // not implicitely (i.e. when retrieving the final result.)
+    //m_pCache = ref.m_pCache;
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::Reset()
+  {
+    m_val = cmplx_type(0,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+		
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 'f';
+    m_iFlags = flNONE;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(bool val)
+  {
+    m_val = cmplx_type((float_type)val,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 'b';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(int_type a_iVal)
+  {
+    m_val = cmplx_type(a_iVal,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 'i';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(float_type val)
+  {
+    m_val = cmplx_type(val, 0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = (val==(int_type)val) ? 'i' : 'f';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(string_type a_sVal)
+  {
+    m_val = cmplx_type();
+    
+    if (!m_psVal)
+      m_psVal = new string_type(a_sVal);
+    else
+     *m_psVal = a_sVal;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 's';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(const char_type *a_szVal)
+  {
+    m_val = cmplx_type();
+
+    if (!m_psVal)
+      m_psVal = new string_type(a_szVal);
+    else
+     *m_psVal = a_szVal;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = 's';
+    m_iFlags = flNONE;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(const array_type &a_vVal)
+  {
+    m_val = cmplx_type(0,0);
+
+    delete m_psVal;
+    m_psVal = NULL;
+		
+    if (m_pvVal==NULL)
+      m_pvVal = new array_type(a_vVal);
+    else
+      *m_pvVal = a_vVal;
+    
+    m_cType = 'a';
+    m_iFlags = flNONE;
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Value::operator=(const cmplx_type &val)
+  {
+    m_val = val;
+
+    delete m_psVal;
+    m_psVal = NULL;
+
+    delete m_pvVal;
+    m_pvVal = NULL;
+
+    m_cType = (m_val.imag()==0) ? ( (m_val.real()==(int)m_val.real()) ? 'i' : 'f' ) : 'c';
+    m_iFlags = flNONE;
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  char_type Value::GetType() const
+  {
+    return m_cType;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the value as an integer. 
+    
+    This function should only be called if you really need an integer value and
+    want to make sure your either get one or throw an exception if the value
+    can not be implicitely converted into an integer.
+  */
+  int_type Value::GetInteger() const
+  {
+    float_type v = m_val.real();
+
+    if (m_cType!='i') //!IsScalar() || (int_type)v-v!=0)
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = 'i';
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+
+    return (int_type)v;
+  }
+
+  //---------------------------------------------------------------------------
+  float_type Value::GetFloat() const
+  {
+/*
+    if (!IsScalar() && m_cType!='b')
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = 'c';
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+*/
+    return m_val.real();
+  }
+
+  //---------------------------------------------------------------------------
+  float_type Value::GetImag() const
+  {
+    if (!IsScalar())
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = 'c';
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+
+    return m_val.imag();
+  }
+
+  //---------------------------------------------------------------------------
+  const cmplx_type& Value::GetComplex() const
+  {
+    return m_val;
+  }
+
+  //---------------------------------------------------------------------------
+  const string_type& Value::GetString() const
+  {
+    CheckType('s');
+    assert(m_psVal!=NULL);
+    return *m_psVal;
+  }
+
+  //---------------------------------------------------------------------------
+  bool Value::GetBool() const
+  {
+    CheckType('b');
+    return m_val.real()==1;
+  }
+
+  //---------------------------------------------------------------------------
+  const array_type& Value::GetArray() const
+  {
+    CheckType('a');
+    assert(m_pvVal!=NULL);
+    return *m_pvVal;
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::CheckType(char_type a_cType) const
+  {
+    if (m_cType!=a_cType)
+    {
+      ErrorContext err;
+      err.Errc  = ecTYPE_CONFLICT;
+      err.Type1 = m_cType;
+      err.Type2 = a_cType;
+      
+      if (GetIdent().length())
+      {
+        err.Ident = GetIdent();
+      }
+      else
+      {
+        stringstream_type ss;
+        ss << *this;
+        err.Ident = ss.str();
+      }
+
+      throw ParserError(err);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  bool Value::IsVolatile() const
+  {
+    return IsFlagSet(IValue::flVOLATILE);
+//    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  string_type Value::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; type=\"") << GetType() << _T("\"");
+    ss << _T("; val=");
+
+    switch(m_cType)
+    {
+    case 'i': ss << (int_type)m_val.real(); break;
+    case 'f': ss << m_val.real(); break;
+    case 'a': ss << _T("(array)"); break;
+    case 's': 
+              assert(m_psVal!=NULL);
+              ss << _T("\"") << m_psVal << _T("\""); break;
+    }
+
+    ss << ((IsFlagSet(IToken::flVOLATILE)) ? _T("; ") : _T("; not ")) << _T("volatile");
+    ss << _T("]");
+
+    return ss.str();
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::Release()
+  {
+    if (m_pCache)
+      m_pCache->ReleaseToCache(this);
+    else
+      delete this;
+  }
+
+  //---------------------------------------------------------------------------
+  void Value::BindToCache(ValueCache *pCache)
+  {
+    m_pCache = pCache;
+  }
+}  // namespace mu
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpValue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpValue.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,119 @@
+/** \file
+    \brief Definition of basic types used by muParserX
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+  </pre>
+*/
+#ifndef MUP_VALUE_H
+#define MUP_VALUE_H
+
+//--- Standard includes ------------------------------------------------------------
+#include <complex>
+#include <list>
+
+//--- Parser framework -------------------------------------------------------------
+#include "mpIValue.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief Value class of muParserX
+  
+    This class represents a value to be used with muParserX. It's a Variant like
+    class able to store a variety of types.
+  */
+  class Value : public IValue
+  {
+  public:
+
+    explicit Value(char_type cType = 'v');
+    Value(int_type val);
+    Value(bool_type val);
+    Value(float_type val);
+    Value(string_type val);
+    Value(const char_type *val);
+    Value(const cmplx_type &v);
+    Value(const array_type &val);
+
+    // Array constructor
+    Value(int_type m, float_type v);
+
+    // Matrix constructor
+    Value(int_type m, int_type n, float_type v);
+
+    Value(const Value &a_Val );
+    Value(const IValue &a_Val);
+    Value& operator=(const Value &a_Val);
+
+    virtual ~Value();
+
+    virtual IValue& operator[](std::size_t idx);
+    virtual IValue& operator=(int_type a_iVal);
+    virtual IValue& operator=(float_type a_fVal);
+    virtual IValue& operator=(string_type a_sVal);
+    virtual IValue& operator=(bool val);
+    virtual IValue& operator=(const array_type &a_vVal);
+    virtual IValue& operator=(const cmplx_type &val);
+    virtual IValue& operator=(const char_type *a_szVal);
+
+    virtual char_type GetType() const;
+    virtual int_type GetInteger() const;
+    virtual float_type GetFloat() const;
+    virtual float_type GetImag() const;
+    virtual bool GetBool() const;
+    virtual const cmplx_type& GetComplex() const;
+    virtual const string_type& GetString() const;
+    virtual const array_type& GetArray() const;
+
+    virtual bool IsVolatile() const;
+    virtual IToken* Clone() const;
+    virtual Value* AsValue();
+
+    virtual string_type AsciiDump() const;
+    void BindToCache(ValueCache *pCache);
+
+  private:
+
+    cmplx_type   m_val;    ///< Member variable for storing the value of complex, float, int and boolean values
+    string_type *m_psVal;  ///< Variable for storing a string value
+    array_type  *m_pvVal;  ///< A Vector for storing array variable content
+    char_type    m_cType;  ///< A byte indicating the type os the represented value
+    EFlags       m_iFlags; ///< Additional flags
+    ValueCache  *m_pCache; ///< Pointer to the Value Cache
+
+    void CheckType(char_type a_cType) const;
+    void Assign(const Value &a_Val);
+    void Reset();
+
+    virtual void Release();
+  }; // class Value
+
+MUP_NAMESPACE_END
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpValueCache.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpValueCache.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,99 @@
+/** \file
+    \brief Definition of a class for caching unused value items and recycling them.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpValueCache.h"
+
+#include "mpValue.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  ValueCache::ValueCache(int size)
+    :m_nIdx(-1)
+    ,m_vCache(size, (mup::Value*)0) // hint to myself: don't use NULL gcc will go postal...
+  {}
+
+  //------------------------------------------------------------------------------
+  ValueCache::~ValueCache()
+  {
+    ReleaseAll();
+  }
+
+  //------------------------------------------------------------------------------
+  void ValueCache::ReleaseAll()
+  {
+    for (std::size_t i=0; i<m_vCache.size(); ++i)
+    {
+      delete m_vCache[i];
+      m_vCache[i] = NULL;
+    }
+
+    m_nIdx = -1;
+  }
+
+  //------------------------------------------------------------------------------
+  void ValueCache::ReleaseToCache(Value *pValue) 
+  {
+//    std::cout << "dbg: " << ct << " ptr: " << this << " void ValueCache::ReleaseToCache(Value *pValue) \n";
+    if (pValue==NULL)
+      return;
+
+    assert(pValue->GetRef()==0);
+
+    // Add the value to the cache if the cache has room for it 
+    // otherwise release the value item instantly
+    if ( m_nIdx < ((int)m_vCache.size()-1) )
+    {
+      m_nIdx++;
+      m_vCache[m_nIdx] = pValue;
+    }
+    else
+      delete pValue;
+  }
+
+  //------------------------------------------------------------------------------
+  Value* ValueCache::CreateFromCache() 
+  {
+    Value *pValue = NULL;
+    if (m_nIdx>=0)
+    {
+      pValue = m_vCache[m_nIdx];
+      m_vCache[m_nIdx] = NULL;
+      m_nIdx--;
+    }
+    else
+    {
+      pValue = new Value();
+      pValue->BindToCache(this);
+    }
+
+    return pValue;
+  }
+
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpValueCache.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpValueCache.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,67 @@
+#ifndef MUP_VALUE_CACHE_H
+#define MUP_VALUE_CACHE_H
+
+/** \file
+    \brief Implementation of a cache for recycling unused value items.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include <vector>
+
+#include "mpFwdDecl.h"
+
+
+MUP_NAMESPACE_START
+  
+  /** \brief The ValueCache class provides a simple mechanism to recycle 
+             unused value items.
+    
+    This class serves as a factory for value items. It allows skipping
+    unnecessary and slow new/delete calls by storing unused value 
+    objects in an internal buffer for later reuse. By eliminating new/delete
+    calls the parser is sped up approximately by factor 3-4.
+  */
+  class ValueCache
+  {
+  public:
+    ValueCache(int size=10);
+   ~ValueCache();
+
+    void ReleaseAll();
+    void ReleaseToCache(Value *pValue);
+    Value* CreateFromCache();
+
+  private:
+    ValueCache(const ValueCache &ref);
+    ValueCache& operator=(const ValueCache &ref);
+
+    int m_nIdx;
+    std::vector<Value*> m_vCache;
+  };
+
+MUP_NAMESPACE_END
+
+#endif // include guard
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpVariable.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpVariable.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,267 @@
+/** \file
+    \brief Implementation of the muParserX variable class.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+#include "mpVariable.h"
+#include "mpError.h"
+
+#include "mpValue.h"
+
+
+MUP_NAMESPACE_START
+
+  //---------------------------------------------------------------------------
+  /** \brief Create a variable and bind a value to it.
+      \param pVal Pointer of the value to bind to this variable.
+
+    It is possible to create an empty variable object by setting pVal to null.
+    Such variable objects must be bound later in order to be of any use.
+  */
+  Variable::Variable(IValue *pVal)
+    :IValue(cmVAR)
+    ,m_pVal(pVal)
+  {
+    AddFlags(IToken::flVOLATILE);
+  }
+
+  //---------------------------------------------------------------------------
+  Variable::Variable(const Variable &obj)
+    :IValue(cmVAR)
+  {
+    Assign(obj);
+    AddFlags(IToken::flVOLATILE);
+  }
+
+  //---------------------------------------------------------------------------
+  Variable& Variable::operator=(const Variable &obj)
+  {
+    Assign(obj);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assign a value to the variable. 
+      \param ref Reference to the value to be assigned
+  */
+  IValue& Variable::operator=(const Value &ref)
+  {
+    assert(m_pVal);
+    *m_pVal = ref;
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator=(int_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator=(float_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator=(string_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator=(bool_type val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator=(const array_type &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator=(const cmplx_type &val)
+  {
+    assert(m_pVal);
+    return m_pVal->operator=(val);
+  }
+
+  //---------------------------------------------------------------------------
+  IValue& Variable::operator[](std::size_t i)
+  {
+    return m_pVal->operator[](i);
+  }
+
+  //---------------------------------------------------------------------------
+  Variable::~Variable()
+  {}
+
+  //---------------------------------------------------------------------------
+  void Variable::Assign(const Variable &ref)
+  {
+    if (this==&ref)
+      return;
+
+    m_pVal = ref.m_pVal;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns a character representing the type of the variable. 
+      \throw nothrow  
+  */
+  char_type Variable::GetType() const
+  {
+    return (m_pVal) ? m_pVal->GetType() : 'v';
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns the Value pointer bound to this variable. 
+      \throw nothrow
+  */
+  IValue* Variable::GetPtr() const
+  {
+    return m_pVal;
+  }
+
+  //---------------------------------------------------------------------------
+  int_type Variable::GetInteger() const
+  {
+    return m_pVal->GetInteger();
+  }
+
+  //---------------------------------------------------------------------------
+  float_type Variable::GetFloat() const
+  {
+    return m_pVal->GetFloat();
+  }
+
+  //---------------------------------------------------------------------------
+  float_type Variable::GetImag() const
+  {
+    return m_pVal->GetImag();
+  }
+
+  //---------------------------------------------------------------------------
+  const cmplx_type& Variable::GetComplex() const
+  {
+    return m_pVal->GetComplex();
+  }
+
+  //---------------------------------------------------------------------------
+  const string_type& Variable::GetString() const
+  {
+    return m_pVal->GetString();
+  }
+
+  //---------------------------------------------------------------------------
+  bool Variable::GetBool() const
+  {
+    return m_pVal->GetBool();
+  }
+
+  //---------------------------------------------------------------------------
+  const array_type& Variable::GetArray() const
+  {
+    return m_pVal->GetArray();
+  }
+
+  //---------------------------------------------------------------------------
+  void Variable::SetFloat(float_type a_fVal)
+  {
+    assert(m_pVal);
+    *m_pVal = a_fVal;
+  }
+
+  //---------------------------------------------------------------------------
+  void Variable::SetString(const string_type &a_sVal)
+  {
+    assert(m_pVal);
+    *m_pVal = a_sVal;
+  }
+
+  //---------------------------------------------------------------------------
+  void Variable::SetBool(bool a_bVal)
+  {
+    assert(m_pVal);
+    *m_pVal = a_bVal;
+  }
+
+  //---------------------------------------------------------------------------
+  void Variable::Bind(IValue *pValue)
+  {
+    m_pVal = pValue;
+  }
+
+  //---------------------------------------------------------------------------
+  bool Variable::IsVolatile() const
+  {
+    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  IToken* Variable::Clone() const
+  {
+    return new Variable(*this);
+  }
+
+  //---------------------------------------------------------------------------
+  Value* Variable::AsValue()
+  {
+    return NULL;
+  }
+
+  //---------------------------------------------------------------------------
+  string_type Variable::AsciiDump() const
+  {
+    stringstream_type ss;
+
+    ss << g_sCmdCode[ GetCode() ];
+    ss << _T(" [addr=0x") << std::hex << this << std::dec;
+    ss << _T("; id=\"") << GetIdent() << _T("\"");
+    ss << _T("; type=\"") << GetType() << _T("\"");
+    ss << _T("; val=");
+
+    switch(GetType())
+    {
+    case 'i': ss << (int_type)GetFloat(); break;
+    case 'f': ss << GetFloat(); break;
+    case 'a': ss << _T("(array)"); break;
+    case 's': ss << _T("\"") << GetString() << _T("\""); break;
+    }
+
+    ss << ((IsFlagSet(IToken::flVOLATILE)) ? _T("; ") : _T("; not ")) << _T("volatile");
+    ss << _T("]");
+
+    return ss.str();
+  }
+MUP_NAMESPACE_END
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/mpVariable.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/mpVariable.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,101 @@
+/** \file
+    \brief Definition of the muParserX variable class.
+
+<pre>
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+</pre>
+*/
+
+#ifndef MP_VARIABLE_H
+#define MP_VARIABLE_H
+
+#include "mpIValue.h"
+#include "mpTypes.h"
+
+
+MUP_NAMESPACE_START
+
+  //------------------------------------------------------------------------------
+  /** \brief The variable class represents a parser variable. 
+  
+    This class stores a pointer to a value object and refers all
+    operations to this value object.
+  */
+  class Variable : public IValue
+  {
+  public:
+
+    Variable(IValue *pVal);
+
+    Variable(const Variable &a_Var);
+    Variable& operator=(const Variable &a_Var);
+
+    virtual IValue& operator[](std::size_t idx);
+    virtual IValue& operator=(const Value &val);
+    virtual IValue& operator=(const array_type &val);
+    virtual IValue& operator=(const cmplx_type &val);
+    virtual IValue& operator=(int_type val);
+    virtual IValue& operator=(float_type val);
+    virtual IValue& operator=(string_type val);
+    virtual IValue& operator=(bool_type val);
+
+    virtual ~Variable();
+
+    virtual char_type GetType() const;
+    
+    virtual int_type GetInteger() const;
+    virtual float_type GetFloat() const;
+    virtual float_type GetImag() const;
+    virtual bool GetBool() const;
+    virtual const cmplx_type& GetComplex() const;
+    virtual const string_type& GetString() const;
+    virtual const array_type& GetArray() const;
+
+    virtual bool IsVolatile() const;
+    virtual IToken* Clone() const;
+    virtual Value* AsValue();
+
+    //void Set(Value &val);
+    void SetFloat(float_type a_fVal);
+    void SetString(const string_type &a_sVal);
+    void SetBool(bool a_bVal);
+
+    void Bind(IValue *pValue);
+
+    IValue* GetPtr() const;
+    string_type AsciiDump() const;
+
+  private:
+
+    IValue *m_pVal;    ///< Pointer to the value object bound to this variable
+
+    void Assign(const Variable &a_Var);
+    void CheckType(char_type a_cType) const;
+  }; // class Variable
+
+MUP_NAMESPACE_END
+
+#endif
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/muMatrix.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/muMatrix.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,397 @@
+#ifndef MU_MATRIX_H
+#define MU_MATRIX_H
+
+#include <vector>
+#include <cassert>
+#include <iostream>
+#include <stdexcept>
+#include <sstream>
+#include <initializer_list>
+#include "muMatrixError.h"
+
+
+namespace mu
+{
+  //-----------------------------------------------------------------------------------------------
+  template<typename T>
+  class Matrix  
+  {
+  template<typename T>
+  friend Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs);
+
+  template<typename T>
+  friend Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs);
+
+  public:
+
+    //---------------------------------------------------------------------------------------------
+    enum EMatrixStorageScheme
+    {
+      mssROWS_FIRST,
+      mssCOLS_FIRST
+    };
+
+    //---------------------------------------------------------------------------------------------
+    Matrix()
+      :m_nRows(1)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(1)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    explicit Matrix(int nRows)
+      :m_nRows(nRows)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(m_nRows)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    /* Constructs a Matrix object representing a scalar value
+    */
+    Matrix(const T &v)
+      :m_nRows(1)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(1, v)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    /* \brief Constructs a Matrix object representing a vector
+    */
+    Matrix(const std::vector<T> &v)
+      :m_nRows(v.size())
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(v)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    /* Constructs a Matrix object representing a vector
+    */
+    template<size_t TSize>
+    Matrix(T (&v)[TSize])
+      :m_nRows(TSize)
+      ,m_nCols(1)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(v, v + TSize)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    template<size_t TRows, size_t TCols>
+    Matrix(T (&v)[TRows][TCols])
+      :m_nRows(TRows)
+      ,m_nCols(TCols)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(TRows*TCols, 0)
+    {
+      for (int m=0; m<TRows; ++m)
+      {
+        for (int n=0; n<TCols; ++n)
+        {
+          At(m,n) = v[m][n];
+        }
+      }
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix(int nRows, int nCols)
+      :m_nRows(nRows)
+      ,m_nCols(nCols)
+      ,m_eStorageScheme(mssROWS_FIRST)
+      ,m_vData(m_nRows*m_nCols)
+    {}
+
+    //---------------------------------------------------------------------------------------------
+    Matrix(const Matrix &ref)
+    {
+      Assign(ref);
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator=(const Matrix &ref)
+    {
+      if (this!=&ref)
+        Assign(ref);
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator=(const T &v)
+    {
+      m_nCols = 1;
+      m_nRows = 1;
+      m_eStorageScheme = mssROWS_FIRST;
+      m_vData.assign(1, v);
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator+=(const Matrix &lhs)
+    {
+      if (m_nRows!=lhs.m_nRows || m_nCols!=lhs.m_nCols)
+        throw MatrixError("Matrix dimension mismatch");
+
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          At(i,j) += lhs.At(i,j);
+        }
+      }
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator-=(const Matrix &lhs)
+    {
+      if (m_nRows!=lhs.m_nRows || m_nCols!=lhs.m_nCols)
+        throw MatrixError("Matrix dimension mismatch");
+
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          At(i,j) -= lhs.At(i,j);
+        }
+      }
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix& operator*=(const Matrix &rhs)
+    {
+      // Matrix x Matrix multiplication
+      if (rhs.GetDim()==0)
+      {
+        T v = rhs.At(0,0);
+        for (int m=0; m<m_nRows; ++m)
+        {
+          for (int n=0; n<m_nCols; ++n)
+          {
+            At(m, n) *= v;
+          }
+        }
+      }
+      else if (GetDim()==0)
+      {
+        T v = At(0,0);
+        Assign(rhs);
+        for (int m=0; m<m_nRows; ++m)
+        {
+          for (int n=0; n<m_nCols; ++n)
+          {
+            At(m, n) *= v;
+          }
+        }
+      }
+      else if (m_nCols==rhs.m_nRows)
+      {
+        Matrix<T> out(m_nRows, rhs.m_nCols);
+        
+        // For each cell in the output matrix
+        for (int m=0; m<m_nRows; ++m)
+        {
+          for (int n=0; n<rhs.m_nCols; ++n)
+          {
+            T buf = 0;
+            for (int i=0; i<m_nCols; ++i)
+            {
+              buf += At(m, i) * rhs.At(i, n);
+            }
+            out.At(m,n) = buf;
+          } // for all rows
+        } // for all columns
+
+        Assign(out);
+      }
+      else
+        throw MatrixError("Matrix dimensions don't allow multiplication");
+      
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    void AsciiDump(const char *szTitle) const
+    {
+      using namespace std;
+
+      cout << szTitle << "\n";
+      cout << "------------------\n";
+      cout << "Cols: " << m_nCols << "\n";
+      cout << "Rows: " << m_nRows << "\n";
+      cout << "Dim:  "  << GetDim() << "\n";
+
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          cout << At(i, j) << "  ";
+        }
+        cout << "\n";
+      }
+
+        cout << "\n\n";
+    }
+
+    //---------------------------------------------------------------------------------------------
+    std::string ToString() const
+    {
+      std::stringstream ss;
+      for (int i=0; i<m_nRows; ++i)
+      {
+        for (int j=0; j<m_nCols; ++j)
+        {
+          ss << At(i, j) << "  ";
+        }
+        ss << "\n";
+      }
+
+      return ss.str();
+    }
+
+    //---------------------------------------------------------------------------------------------
+   ~Matrix()
+    {
+      m_vData.clear();
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int GetRows() const
+    {
+      return m_nRows;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int GetCols() const
+    {
+      return m_nCols;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int GetDim() const
+    {
+      if (m_nCols==1)
+      {
+        return (m_nRows==1) ? 0 : 1;
+      }
+      else
+        return 2;
+    }
+  
+    //---------------------------------------------------------------------------------------------
+    T& At(int nRow, int nCol = 0)
+    {
+      int i;
+      if (m_eStorageScheme==mssROWS_FIRST)
+      {
+        i = nRow * m_nCols + nCol;
+      }
+      else
+      {
+        i = nCol * m_nRows + nRow;
+      }
+
+      assert(i<(int)m_vData.size());
+      return m_vData[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    const T& At(int nRow, int nCol = 0) const
+    {
+      int i;
+      if (m_eStorageScheme==mssROWS_FIRST)
+      {
+        i = nRow * m_nCols + nCol;
+      }
+      else
+      {
+        i = nCol * m_nRows + nRow;
+      }
+
+      assert(i<(int)m_vData.size());
+      return m_vData[i];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    const T* GetData() const
+    {
+      assert(m_vData.size());
+      return &m_vData[0];
+    }
+
+    //---------------------------------------------------------------------------------------------
+    void SetStorageScheme(EMatrixStorageScheme eSheme)
+    {
+      m_eStorageScheme = eScheme;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    EMatrixStorageScheme GetStorageScheme() const
+    {
+      return m_eScheme;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    Matrix<T>& Transpose()
+    {
+      if (GetDim()==0)
+        return *this;
+
+      m_eStorageScheme = (m_eStorageScheme==mssROWS_FIRST) ? mssCOLS_FIRST : mssROWS_FIRST;
+      m_nRows ^= m_nCols ^= m_nRows ^= m_nCols;
+
+      return *this;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    void Fill(const T &v)
+    {
+      m_vData.assign(m_vData.size(), v);
+    }
+
+  private:
+    int m_nCols;
+    int m_nRows;
+    std::vector<T> m_vData;
+
+    EMatrixStorageScheme m_eStorageScheme;
+
+    //---------------------------------------------------------------------------------------------
+    void Assign(const Matrix &ref)
+    {
+      m_nCols = ref.m_nCols;
+      m_nRows = ref.m_nRows;
+      m_eStorageScheme = ref.m_eStorageScheme;
+      m_vData = ref.m_vData;
+    }
+  };
+
+
+  //---------------------------------------------------------------------------------------------
+  template<typename T>
+  Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs)
+  {
+    return Matrix<T>(lhs) *= rhs;
+  }
+
+  //---------------------------------------------------------------------------------------------
+  template<typename T>
+  Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs)
+  {
+    return Matrix<T>(lhs) += rhs;
+  }
+
+  //---------------------------------------------------------------------------------------------
+  template<typename T>
+  Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs)
+  {
+    return Matrix<T>(lhs) -= rhs;
+  }
+} // namespace mu
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/muMatrixError.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/muMatrixError.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,18 @@
+#ifndef MU_MATRIX_ERROR_H
+#define MU_MATRIX_ERROR_H
+
+#include <stdexcept>
+#include <string>
+
+namespace mu
+{
+  class MatrixError : public std::runtime_error
+  {
+  public:
+    explicit MatrixError(const std::string &sMsg)
+        :std::runtime_error(sMsg)
+    {}
+  };
+}
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/muMatrixTest.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/muMatrixTest.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,253 @@
+#include "muMatrixTest.h"
+
+using namespace std;
+
+
+namespace mu
+{
+  //-----------------------------------------------------------------------------------------------
+  MatrixTest::MatrixTest()
+    :m_nTests(0)
+    ,m_vTests()
+  {
+    
+#if defined(_UNICODE)
+    m_stream = &std::wcout;
+#else
+    m_stream = &std::cout;
+#endif
+
+    AddTest(&MatrixTest::TestInitialization);
+    AddTest(&MatrixTest::TestAddSub);
+    AddTest(&MatrixTest::TestMul);
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void MatrixTest::AddTest(MatrixTest::testfun_type a_pFun)
+  {
+    m_vTests.push_back(a_pFun);
+  }
+  
+  //-----------------------------------------------------------------------------------------------
+  int MatrixTest::TestInitialization()
+  {
+    int nFail = 0;
+
+    *m_stream << "testing matrix initialization...";
+
+    // Array initialization
+    double ref_v3[] = { 1.0, 2.0, 3.0};
+    
+    // 1.1) Create empty array,initialize cell by cell afterwards
+    Matrix<double> v1(3);
+    v1.At(0) = ref_v3[0];
+    v1.At(1) = ref_v3[1];
+    v1.At(2) = ref_v3[2];
+
+    // Create a reference matrix
+    double ref[3][3] = { {1,2,3}, 
+                         {4,5,6}, 
+                         {7,8,9} };
+
+    // 1.) Construct empty matrix, fill afterwards cell by cell
+    Matrix<double> m1(3,3);
+    m1.At(0,0) = ref[0][0]; m1.At(0,1) = ref[0][1]; m1.At(0,2) = ref[0][2];
+    m1.At(1,0) = ref[1][0]; m1.At(1,1) = ref[1][1]; m1.At(1,2) = ref[1][2];
+    m1.At(2,0) = ref[2][0]; m1.At(2,1) = ref[2][1]; m1.At(2,2) = ref[2][2];
+
+    // 2.) Construct matrix from multidimensional array
+    Matrix<double> m2(ref);
+
+
+    if (nFail==0) 
+      *m_stream << "passed" << endl;
+    else 
+      *m_stream << "\n  failed with " << nFail << " errors" << endl;
+
+    return nFail;  
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  int MatrixTest::TestAddSub()
+  {
+    int nFail = 0;
+
+    *m_stream << "testing addition and subtraction...";
+
+    Matrix<double> a,b,c,d;
+    a = 1;
+    b = 2;
+    c = 3;
+    d = 6;
+
+    Matrix<double> va3(3,3), vb3(3,3), vc3(3,3), vd3(3,3), m44(4,4), m34(3,4), m43(4,3);
+
+    va3.At(0,0) = 1; va3.At(0,1) = 2; va3.At(0,2) = 3;
+    va3.At(1,0) = 4; va3.At(1,1) = 5; va3.At(1,2) = 6;
+    va3.At(2,0) = 7; va3.At(2,1) = 8; va3.At(2,2) = 9;
+
+    vb3.At(0,0) = 9; vb3.At(0,1) = 8; vb3.At(0,2) = 7;
+    vb3.At(1,0) = 6; vb3.At(1,1) = 5; vb3.At(1,2) = 4;
+    vb3.At(2,0) = 3; vb3.At(2,1) = 2; vb3.At(2,2) = 1;
+
+    vc3.Fill(10);
+    vd3.Fill(0);
+
+    // Addition von Skalaren
+    nFail += Eval(a+b, c);
+    nFail += Eval(b+a, c);
+    nFail += Eval(a+b+c, d);
+    nFail += Eval(c-b, a);
+    nFail += Eval(d-c, c);
+
+#define THROWTEST(EXPR)                     \
+    {                                       \
+      m_nTests++;                           \
+      try                                   \
+      {                                     \
+        EXPR;                               \
+        nFail++;                            \
+      }                                     \
+      catch(...)                            \
+      {                                     \
+      }                                     \
+    }
+
+    // Addition von Matrizen mit nicht passenden Zeilen/Spaltenzahl
+    THROWTEST(a+va3);
+    THROWTEST(va3+a);
+    THROWTEST(a+va3);
+    THROWTEST(va3+a);
+    THROWTEST(va3+m44);
+    THROWTEST(va3+m34);
+    THROWTEST(va3+m43);
+    THROWTEST(m44+va3);
+    THROWTEST(m34+va3);
+    THROWTEST(m43+va3);
+    
+    THROWTEST(a-va3);
+    THROWTEST(va3-a);
+    THROWTEST(a-va3);
+    THROWTEST(va3-a);
+    THROWTEST(va3-m44);
+    THROWTEST(va3-m34);
+    THROWTEST(va3-m43);
+    THROWTEST(m44-va3);
+    THROWTEST(m34-va3);
+    THROWTEST(m43-va3);
+
+    // Addition von Matrizen
+    nFail += Eval(va3+vb3, vc3);
+    nFail += Eval(vb3+va3, vc3);
+    nFail += Eval(vc3-vb3, va3);
+    nFail += Eval(vc3-va3, vb3);
+
+    if (nFail==0) 
+      *m_stream << "passed" << endl;
+    else 
+      *m_stream << "\n  failed with " << nFail << " errors" << endl;
+
+    return nFail;  
+  }
+
+
+  //-----------------------------------------------------------------------------------------------
+  int MatrixTest::TestMul()
+  {
+    int nFail = 0;
+    *m_stream << "testing multiplication...";
+
+    Matrix<double> a,b,c,d;
+    a = 1;
+    b = 2;
+    c = 3;
+    d = 6;
+
+    // Try assigning from array
+    double buf[]= { 1,2,3 };  
+    Matrix<double> va3 = buf;
+
+    // Manual assignment
+    Matrix<double> vb3(3), vc3(3), vd3(3);
+    vb3.At(0) = 4, vc3.At(0) = 3, vd3.At(0) = 12;
+    vb3.At(1) = 5, vc3.At(1) = 4, vd3.At(1) = 15;
+    vb3.At(2) = 6, vc3.At(2) = 3, vd3.At(2) = 18;
+
+    // Skalarprodukt
+    THROWTEST(va3*vb3);
+    THROWTEST(vb3*va3);
+
+    double res1[3][3] = { { 4,  5,  6},
+                          { 8, 10, 12},
+                          {12, 15, 18} };
+    nFail += Eval(va3 * Matrix<double>(vb3).Transpose(), res1);
+    nFail += Eval(Matrix<double>(vb3).Transpose() * va3, 32);
+
+    double res2[3][3] = { { 4,  8, 12},
+                          { 5, 10, 15},
+                          { 6, 12, 18} };
+    nFail += Eval(vb3 * Matrix<double>(va3).Transpose(), res2);
+
+    double ma[2][3] = { {1, 2, 3},
+                        {4, 5, 6} };
+    double mb[3][2] = { {6, -1},
+                        {3,  2},
+                        {0, -3}};
+    double res3[2][2] = { {12,  -6},
+                          {39, -12} };
+    nFail += Eval(Matrix<double>(ma)*Matrix<double>(mb), res3);
+    
+    // Skalar-Vektor Multiplikatione
+    nFail += Eval(c*vb3, vd3);
+    nFail += Eval(vb3*c, vd3);
+
+    // gemischte Multiplikation
+    double res4[3][3] = { {12*3, 15*3, 18*3},
+                          {16*3, 20*3, 24*3},
+                          {12*3, 15*3, 18*3} };
+    nFail += Eval(c*vc3*Matrix<double>(vb3).Transpose(), res4);
+    nFail += Eval(vc3*c*Matrix<double>(vb3).Transpose(), res4);
+    nFail += Eval(vc3*Matrix<double>(vb3).Transpose()*c, res4);
+
+    if (nFail==0) 
+      *m_stream << "passed" << endl;
+    else 
+      *m_stream << "\n  failed with " << nFail << " errors" << endl;
+
+    return nFail;  
+  }
+
+  //-----------------------------------------------------------------------------------------------
+  void MatrixTest::Run()
+  {
+    int nFail = 0;
+    try
+    {
+      for (int i=0; i<(int)m_vTests.size(); ++i)
+        nFail += (this->*m_vTests[i])();
+
+      if (nFail==0) 
+      {
+        *m_stream << _T("Test passed (") <<  m_nTests << _T(" distinct test)") << endl;
+      }
+      else 
+      {
+        *m_stream << _T("Test failed with ") << nFail 
+                  << _T(" errors (") <<  m_nTests 
+                  << _T(" expressions)") << endl;
+      }
+    }
+    catch(std::exception &e)
+    {
+      *m_stream << _T("\nTest failed (unexpected exception):\n");
+      *m_stream << e.what() << endl;
+    }
+    catch(...)
+    {
+      *m_stream << _T("\nTest failed (unexpected exception):\n");
+      *m_stream << _T("Internal error");
+    }
+
+    m_nTests = 0;
+  }
+}
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/muMatrixTest.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/muMatrixTest.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,78 @@
+#ifndef MU_MATRIX_TEST_H
+#define MU_MATRIX_TEST_H
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+#include "muMatrix.h"
+
+#ifndef _T 
+#define _T
+#endif
+
+namespace mu
+{
+  class MatrixTest
+  {
+  public:
+      MatrixTest();
+
+     void Run();
+
+  private:
+      typedef int (MatrixTest::*testfun_type)();
+
+      int m_nTests;
+      std::vector<testfun_type> m_vTests;
+
+#if defined(_UNICODE)
+      std::wostream *m_stream;
+#else
+      std::ostream *m_stream;
+#endif
+
+      int TestInitialization();
+      int TestAddSub();
+      int TestMul();
+      
+      void AddTest(testfun_type pFun);
+
+      int Eval(const Matrix<double> &m1, const Matrix<double> &m2)
+      {
+        m_nTests++;
+        int nFail = 0;
+        try
+        {
+          if (m1.GetDim()!=m2.GetDim())
+            throw MatrixError("invalid Matrix dimentsion");
+
+          if (m1.GetRows()!=m2.GetRows())
+            throw MatrixError("invalid Matrix rows");
+
+          if (m1.GetCols()!=m2.GetCols())
+            throw MatrixError("invalid Matrix rows");
+
+          for (int i=0; i<m1.GetRows(); ++i)
+          {
+            for (int j=0; j<m1.GetCols(); ++j)
+            {
+              if (m1.At(i,j)!=m2.At(i,j))
+                throw MatrixError("invalid Matrix value");
+            }
+          }
+
+          nFail = 0;
+        }
+        catch(...)
+        {
+          *m_stream << "\nincorrect result:\n" << m1.ToString() << "\nexpected:\n" << m2.ToString() << "\n";
+          nFail = 1;
+        }
+
+        return nFail;
+      }
+  };
+}
+
+#endif
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/resource.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/resource.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,3 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by app.rc
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/stdafx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/stdafx.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,7 @@
+// stdafx.cpp : source file that includes just the standard includes
+// value_test.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/stdafx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/stdafx.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,8 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// TODO: reference additional headers your program requires here
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/suSortPred.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/suSortPred.h	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,58 @@
+/*
+               __________                                 ____  ___
+    _____  __ _\______   \_____ _______  ______ __________\   \/  /
+   /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     / 
+  |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \ 
+  |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
+        \/                     \/           \/     \/           \_/
+
+  muParserX - A C++ math parser library with array and string support
+  Copyright 2010 Ingo Berg
+
+  This program 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.
+
+  This program 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 this program.  If not, see http://www.gnu.org/licenses.
+*/
+#ifndef SU_PRED_H
+#define SU_PRED_H
+
+#include <functional>
+
+
+/** \brief Namespace containing utility functions and classes for string processing. */
+namespace su
+{
+  namespace pred
+  {
+    /** \brief Sort two strings based on their length.
+    */
+    template<class TString>
+	  struct SortByLength
+      :public std::binary_function<TString, TString, bool>
+	  {	
+	    bool operator()(const TString& a_sLeft, const TString& a_sRight) const
+		  {	
+        if (a_sLeft.length() == a_sRight.length())
+        {
+          return a_sLeft < a_sRight;
+        }
+        else
+        {
+          return a_sLeft.length() < a_sRight.length();
+        }
+		  }
+	  };
+  } // namespace pred
+} // end of namespace
+
+
+#endif
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.cpp	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,54 @@
+// value_test.cpp : main project file.
+
+#include "stdafx.h"
+#include <string>
+
+#include "mpDefines.h"
+#include "mpTypes.h"
+#include "mpValue.h"
+
+//--- MathUtils -----------------------------------------------------------------------------------
+#include "muMatrix.h"
+#include "muMatrixTest.h"
+
+
+MUP_NAMESPACE_START
+  //-----------------------------------------------------------------------------------------------
+  const char_type *g_sCmdCode[] = { _T("BRCK. OPEN     "),
+                                    _T("BRCK. CLOSE    "),
+                                    _T("IDX OPEN       "),
+                                    _T("IDX CLOSE      "),
+                                    _T("ARG_SEP        "),
+                                    _T("IF             "),
+                                    _T("ELSE           "),
+                                    _T("ENDIF          "),
+                                    _T("JMP            "),
+                                    _T("VAR            "),
+                                    _T("VAL            "),
+                                    _T("FUNC           "),
+                                    _T("OPRT_BIN       "),
+                                    _T("OPRT_IFX       "),
+                                    _T("OPRT_PFX       "),
+                                    _T("END            "),
+                                    _T("SCRIPT_GOTO    "),
+                                    _T("SCRIPT_LABEL   "),
+                                    _T("SCRIPT_FOR     "),
+                                    _T("SCRIPT_IF      "),
+                                    _T("SCRIPT_ELSE    "),
+                                    _T("SCRIPT_ELSEIF  "),
+                                    _T("SCRIPT_ENDIF   "),
+                                    _T("SCRIPT_NEWLINE "),
+                                    _T("SCRIPT_FUNCTION"),
+                                    _T("UNKNOWN        ") };
+MUP_NAMESPACE_END
+
+using namespace mup;
+using namespace mu;
+
+int main(int /* argc */, char ** /*argv*/)
+{
+  MatrixTest mt;
+  mt.Run();
+
+  return 0;
+}
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.sln
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.sln	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "value_test", "value_test.vcxproj", "{F2291F6C-D078-44F7-B0A5-AD200C348D23}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Debug|Win32.Build.0 = Debug|Win32
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Release|Win32.ActiveCfg = Release|Win32
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.sln.old
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.sln.old	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "value_test", "value_test.vcproj", "{F2291F6C-D078-44F7-B0A5-AD200C348D23}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Debug|Win32.Build.0 = Debug|Win32
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Release|Win32.ActiveCfg = Release|Win32
+		{F2291F6C-D078-44F7-B0A5-AD200C348D23}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.suo.old
Binary file muparserx/value_test/value_test.suo.old has changed
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.vcproj
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.vcproj	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="value_test"
+	ProjectGUID="{F2291F6C-D078-44F7-B0A5-AD200C348D23}"
+	RootNamespace="value_test"
+	Keyword="ManagedCProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			ManagedExtensions="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(NoInherit)"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				AssemblyDebug="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			ManagedExtensions="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(NoInherit)"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+		<AssemblyReference
+			RelativePath="System.dll"
+			AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+			MinFrameworkVersion="131072"
+		/>
+		<AssemblyReference
+			RelativePath="System.Data.dll"
+			AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
+			MinFrameworkVersion="131072"
+		/>
+		<AssemblyReference
+			RelativePath="System.XML.dll"
+			AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+			MinFrameworkVersion="131072"
+		/>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\mpError.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpError.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIToken.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIToken.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValReader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValue.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpIValue.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpTypes.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValue.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValue.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpValueCache.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpVariable.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpVariable.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\value_test.cpp"
+				>
+			</File>
+			<Filter
+				Name="muMatrix"
+				>
+				<File
+					RelativePath=".\muMatrix.h"
+					>
+				</File>
+				<File
+					RelativePath="..\parser\muMatrixError.h"
+					>
+				</File>
+				<File
+					RelativePath=".\muMatrixTest.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\muMatrixTest.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\app.ico"
+				>
+			</File>
+			<File
+				RelativePath=".\app.rc"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.vcproj.NB1.user.user
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.vcproj.NB1.user.user	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory=""
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="NB1"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory=""
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="NB1"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment=""
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.vcxproj
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.vcxproj	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{F2291F6C-D078-44F7-B0A5-AD200C348D23}</ProjectGuid>
+    <RootNamespace>value_test</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>true</CLRSupport>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>NotSet</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </Reference>
+    <Reference Include="System.Data">
+      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </Reference>
+    <Reference Include="System.Xml">
+      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="mpError.cpp" />
+    <ClCompile Include="mpIToken.cpp" />
+    <ClCompile Include="mpIValue.cpp" />
+    <ClCompile Include="mpValue.cpp" />
+    <ClCompile Include="mpValueCache.cpp" />
+    <ClCompile Include="mpVariable.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="value_test.cpp" />
+    <ClCompile Include="muMatrixTest.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="mpError.h" />
+    <ClInclude Include="mpIToken.h" />
+    <ClInclude Include="mpIValReader.h" />
+    <ClInclude Include="mpIValue.h" />
+    <ClInclude Include="mpTypes.h" />
+    <ClInclude Include="mpValue.h" />
+    <ClInclude Include="mpVariable.h" />
+    <ClInclude Include="muMatrix.h" />
+    <ClInclude Include="..\parser\muMatrixError.h" />
+    <ClInclude Include="muMatrixTest.h" />
+    <ClInclude Include="resource.h" />
+    <ClInclude Include="stdafx.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.ico" />
+    <None Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="app.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.vcxproj.filters
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.vcxproj.filters	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Source Files\muMatrix">
+      <UniqueIdentifier>{d30e11b2-7b04-4b81-a70b-642cb076db3f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="mpError.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mpIToken.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mpIValue.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mpValue.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mpValueCache.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mpVariable.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="value_test.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="muMatrixTest.cpp">
+      <Filter>Source Files\muMatrix</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="mpError.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mpIToken.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mpIValReader.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mpIValue.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mpTypes.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mpValue.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="mpVariable.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="muMatrix.h">
+      <Filter>Source Files\muMatrix</Filter>
+    </ClInclude>
+    <ClInclude Include="..\parser\muMatrixError.h">
+      <Filter>Source Files\muMatrix</Filter>
+    </ClInclude>
+    <ClInclude Include="muMatrixTest.h">
+      <Filter>Source Files\muMatrix</Filter>
+    </ClInclude>
+    <ClInclude Include="resource.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="stdafx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.ico">
+      <Filter>Resource Files</Filter>
+    </None>
+    <None Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="app.rc">
+      <Filter>Resource Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/value_test/value_test.vcxproj.user
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/value_test/value_test.vcxproj.user	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+</Project>
\ No newline at end of file
diff -r 458e51062300 -r 5a4d909d9533 muparserx/vs8/muparserX.sln
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/vs8/muparserX.sln	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "muparserx", "muparserx.vcproj", "{E202E8A6-284D-4AD9-A465-B11267571619}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{E202E8A6-284D-4AD9-A465-B11267571619}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E202E8A6-284D-4AD9-A465-B11267571619}.Debug|Win32.Build.0 = Debug|Win32
+		{E202E8A6-284D-4AD9-A465-B11267571619}.Release|Win32.ActiveCfg = Release|Win32
+		{E202E8A6-284D-4AD9-A465-B11267571619}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff -r 458e51062300 -r 5a4d909d9533 muparserx/vs8/muparserx.vcproj
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/muparserx/vs8/muparserx.vcproj	Tue Nov 08 10:39:59 2011 -0800
@@ -0,0 +1,584 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="muparserx"
+	ProjectGUID="{E202E8A6-284D-4AD9-A465-B11267571619}"
+	RootNamespace="muparser2"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			ManagedExtensions="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../parser"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				SmallerTypeCheck="true"
+				RuntimeLibrary="3"
+				FloatingPointModel="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				AssemblyDebug="1"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="true"
+				FavorSizeOrSpeed="1"
+				OmitFramePointers="true"
+				WholeProgramOptimization="false"
+				AdditionalIncludeDirectories="../parser"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				EnableEnhancedInstructionSet="2"
+				FloatingPointModel="2"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\sample\example.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath="..\sample\timer.cpp"
+				>
+			</File>
+			<Filter
+				Name="muparserx"
+				>
+				<Filter
+					Name="functions"
+					>
+					<File
+						RelativePath="..\parser\mpFuncCmplx.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncCmplx.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncCommon.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncCommon.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncMatrix.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncMatrix.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncNonCmplx.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncNonCmplx.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncStr.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFuncStr.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="operators"
+					>
+					<File
+						RelativePath="..\parser\mpOprtBinAssign.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtBinAssign.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtBinCommon.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtBinCommon.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtCmplx.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtCmplx.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtIndex.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtIndex.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtMatrix.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtMatrix.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtNonCmplx.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpOprtNonCmplx.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="utils"
+					>
+					<File
+						RelativePath="..\parser\suSortPred.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\utGeneric.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="framework"
+					>
+					<File
+						RelativePath="..\parser\mpDefines.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpError.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpError.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpFwdDecl.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpICallback.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpICallback.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIfThenElse.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIfThenElse.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIOprt.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIOprt.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIPackage.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIPackage.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIPrecedence.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIToken.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIToken.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIValReader.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIValReader.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIValue.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpIValue.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpMatrix.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpMatrixError.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpParser.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpParser.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpParserBase.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpParserBase.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpRPN.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpRPN.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpScriptTokens.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpScriptTokens.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpStack.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpTest.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpTest.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpTokenReader.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpTokenReader.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpTypes.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpValReader.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpValReader.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpValue.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpValue.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpValueCache.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpValueCache.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpVariable.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpVariable.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="packages"
+					>
+					<File
+						RelativePath="..\parser\mpPackageCmplx.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageCmplx.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageCommon.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageCommon.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageMatrix.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageMatrix.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageNonCmplx.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageNonCmplx.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageStr.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageStr.h"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageUnit.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\parser\mpPackageUnit.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="doc"
+				>
+				<File
+					RelativePath="..\doc\custom\calc.cpp"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						ExcludedFromBuild="true"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						ExcludedFromBuild="true"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\doc\custom\example.txt"
+					>
+				</File>
+				<File
+					RelativePath="..\doc\custom\features.txt"
+					>
+				</File>
+				<File
+					RelativePath="..\doc\custom\licence.txt"
+					>
+				</File>
+				<File
+					RelativePath="..\doc\custom\Main.txt"
+					>
+				</File>
+			</Filter>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>



More information about the CIG-COMMITS mailing list