Index: /issm/trunk/configure.ac
===================================================================
--- /issm/trunk/configure.ac	(revision 17988)
+++ /issm/trunk/configure.ac	(revision 17989)
@@ -2,5 +2,5 @@
 
 #AUTOCONF
-AC_INIT([Ice Sheet System Model (ISSM)],[4.6],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
+AC_INIT([Ice Sheet System Model (ISSM)],[4.7],[issm@jpl.nasa.gov],[issm],[http://issm.jpl.nasa.gov]) #Initializing configure
 AC_CONFIG_AUX_DIR([./aux-config])         #Put config files in aux-config
 AC_CONFIG_MACRO_DIR([m4])                 #m4 macros are located in m4
Index: /issm/trunk/externalpackages/m1qn3/install.sh
===================================================================
--- /issm/trunk/externalpackages/m1qn3/install.sh	(revision 17989)
+++ /issm/trunk/externalpackages/m1qn3/install.sh	(revision 17989)
@@ -0,0 +1,59 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup 
+rm -rf install src m1qn3-3.3-distrib
+mkdir install
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/m1qn3-3.3-distrib.tgz' 'm1qn3-3.3-distrib.tgz'
+
+#Untar 
+tar -xzf m1qn3-3.3-distrib.tgz
+mv m1qn3-3.3-distrib src
+
+if which ifort >/dev/null; then
+	FC="ifort"
+else
+	FC="gfortran"
+fi
+
+#Compile m1qn3
+cd src/src/
+(
+cat << EOF
+LIB_EXT=a
+FC=$FC
+install: libm1qn3.\$(LIB_EXT)
+	cp libm1qn3.\$(LIB_EXT) ../../install/
+OBJECTS= m1qn3.o
+libm1qn3.\$(LIB_EXT): \$(OBJECTS)
+	ar -r libm1qn3.\$(LIB_EXT) \$(OBJECTS) 
+	ranlib libm1qn3.\$(LIB_EXT) 
+%.o: %.f
+	\$(FC) \$(FFLAGS) -c $< -o \$@
+clean: 
+	rm -rf *.o *.\$(LIB_EXT)
+EOF
+) > Makefile
+make
+
+#compile ddot
+cd ../blas
+(
+cat << EOF
+LIB_EXT=a
+FC=$FC
+install: libddot.\$(LIB_EXT)
+	cp libddot.\$(LIB_EXT) ../../install/
+OBJECTS= ddot.o
+libddot.\$(LIB_EXT): \$(OBJECTS)
+	ar -r libddot.\$(LIB_EXT) \$(OBJECTS) 
+	ranlib libddot.\$(LIB_EXT) 
+%.o: %.f
+	\$(FC) \$(FFLAGS) -c $< -o \$@
+clean: 
+	rm -rf *.o *.\$(LIB_EXT)
+EOF
+) > Makefile
+make
Index: /issm/trunk/externalpackages/petsc/install-3.4-hpc.sh
===================================================================
--- /issm/trunk/externalpackages/petsc/install-3.4-hpc.sh	(revision 17989)
+++ /issm/trunk/externalpackages/petsc/install-3.4-hpc.sh	(revision 17989)
@@ -0,0 +1,39 @@
+#!/bin/bash
+set -eu
+
+#Some cleanup
+rm -rf install petsc-3.4.3 src
+mkdir install src
+
+#Download from ISSM server
+$ISSM_DIR/scripts/DownloadExternalPackage.py 'http://issm.jpl.nasa.gov/files/externalpackages/petsc-lite-3.4.3.tar.gz' 'petsc-3.4.3.tar.gz'
+
+#Untar and move petsc to install directory
+tar -zxvf  petsc-3.4.3.tar.gz
+mv petsc-3.4.3/* src/
+rm -rf petsc-3.4.3
+
+#configure
+cd src
+./config/configure.py \
+ --prefix="$ISSM_DIR/externalpackages/petsc/install" \
+ --PETSC_DIR="$ISSM_DIR/externalpackages/petsc/src" \
+ --with-debugging=0 \
+ --with-shared-libraries=1 \
+ --known-mpi-shared-libraries=1 \
+ --with-mpi=1 \
+ --with-mpi-dir=/data/apps/mpi/openmpi-1.6.0/gcc-4.7.2// \
+ --download-scalapack=yes \
+ --download-blacs=yes \
+ --download-blas=yes \
+ --download-f-blas-lapack=yes \
+ --download-mumps=yes \
+ --download-metis=yes \
+ --download-parmetis=yes \
+ --COPTFLAGS="-O3" \
+ --FOPTFLAGS="-O3" \
+ --CXXOPTFLAGS="-O3"
+
+#Compile petsc and install it
+make
+make install
Index: sm/trunk/externalpackages/valgrind/README
===================================================================
--- /issm/trunk/externalpackages/valgrind/README	(revision 17988)
+++ 	(revision )
@@ -1,5 +1,0 @@
-How to use valgrind to debug memory leaks. 
-Install valgrind (jut type valgrind.sh). 
-Compile the parallel code using -g -O0 as optoins (edit src/c/Makefile if necessary).
-Then set md.mem_debug=1, and run in parallel. Voila!
-The errlog will contain all the info spit out by valgrind.
Index: /issm/trunk/externalpackages/valgrind/issm.supp
===================================================================
--- /issm/trunk/externalpackages/valgrind/issm.supp	(revision 17988)
+++ /issm/trunk/externalpackages/valgrind/issm.supp	(revision 17989)
@@ -180,3 +180,34 @@
    fun:__dmumps_comm_buffer_MOD_dmumps_62
 }
+{
+	<mumps11>
+	  Memcheck:User
+	  fun:check_mem_is_defined_untyped
+	  fun:PMPI_Isend
+	  fun:libparmetis__gkMPI_Isend
+	  fun:libparmetis__CommInterfaceData
+	  fun:libparmetis__CompactGraph
+	  fun:libparmetis__MultilevelOrder
+	  fun:ParMETIS_V32_NodeND
+	  fun:ParMETIS_V3_NodeND
+	  fun:mumps_parmetis_
+}
+{
+	<mumps12>
+	  Memcheck:User
+	  fun:check_mem_is_defined_untyped
+	  fun:PMPI_Bcast
+	  fun:MPI_BCAST
+	  fun:__dmumps_parallel_analysis_MOD_dmumps_718
+	  fun:__dmumps_parallel_analysis_MOD_dmumps_717
+	  fun:__dmumps_parallel_analysis_MOD_dmumps_715
+}
+{
+	<mumps13>
+	  Memcheck:Leak
+	  fun:malloc
+	  fun:__dmumps_parallel_analysis_MOD_dmumps_775
+	  fun:__dmumps_parallel_analysis_MOD_dmumps_720
+	  fun:__dmumps_parallel_analysis_MOD_dmumps_715
+}
 #}}}
Index: /issm/trunk/externalpackages/vim/addons/vim/syntax/c.vim
===================================================================
--- /issm/trunk/externalpackages/vim/addons/vim/syntax/c.vim	(revision 17988)
+++ /issm/trunk/externalpackages/vim/addons/vim/syntax/c.vim	(revision 17989)
@@ -412,5 +412,4 @@
 syn keyword cType BoolInput
 syn keyword cType BoolParam
-syn keyword cType classes
 syn keyword cType Constraint
 syn keyword cType Constraints
@@ -418,6 +417,6 @@
 syn keyword cType Contours
 syn keyword cType ControlInput
+syn keyword cType DataSetParam
 syn keyword cType DatasetInput
-syn keyword cType DataSetParam
 syn keyword cType Definition
 syn keyword cType DependentObject
@@ -432,6 +431,6 @@
 syn keyword cType ElementHook
 syn keyword cType ElementMatrix
+syn keyword cType ElementVector
 syn keyword cType Elements
-syn keyword cType ElementVector
 syn keyword cType ExponentialVariogram
 syn keyword cType ExternalResult
@@ -440,10 +439,9 @@
 syn keyword cType Friction
 syn keyword cType Gauss
-syn keyword cType GaussianVariogram
-syn keyword cType gaussobjects
 syn keyword cType GaussPenta
 syn keyword cType GaussSeg
 syn keyword cType GaussTetra
 syn keyword cType GaussTria
+syn keyword cType GaussianVariogram
 syn keyword cType GenericExternalResult
 syn keyword cType GenericOption
@@ -459,5 +457,4 @@
 syn keyword cType IntVecParam
 syn keyword cType IoModel
-syn keyword cType krigingobjects
 syn keyword cType Load
 syn keyword cType Loads
@@ -467,5 +464,4 @@
 syn keyword cType Matice
 syn keyword cType Matpar
-syn keyword cType matrixobjects
 syn keyword cType MatrixParam
 syn keyword cType Misfit
@@ -476,6 +472,6 @@
 syn keyword cType Observations
 syn keyword cType Option
+syn keyword cType OptionUtilities
 syn keyword cType Options
-syn keyword cType OptionUtilities
 syn keyword cType Param
 syn keyword cType Parameters
@@ -489,10 +485,10 @@
 syn keyword cType Quadtree
 syn keyword cType Results
+syn keyword cType RiftStruct
 syn keyword cType Riftfront
-syn keyword cType RiftStruct
 syn keyword cType Seg
 syn keyword cType SegInput
+syn keyword cType SegRef
 syn keyword cType Segment
-syn keyword cType SegRef
 syn keyword cType SpcDynamic
 syn keyword cType SpcStatic
@@ -514,7 +510,12 @@
 syn keyword cType Vertex
 syn keyword cType Vertices
+syn keyword cType classes
+syn keyword cType gaussobjects
+syn keyword cType krigingobjects
+syn keyword cType matrixobjects
 syn keyword cType AdjointBalancethicknessAnalysis
 syn keyword cType AdjointHorizAnalysis
 syn keyword cType Analysis
+syn keyword cType Balancethickness2Analysis
 syn keyword cType BalancethicknessAnalysis
 syn keyword cType BalancethicknessSoftAnalysis
@@ -626,9 +627,4 @@
 syn keyword cConstant HydrologyModelEnum
 syn keyword cConstant HydrologyshreveEnum
-syn keyword cConstant HydrologyshreveCREnum
-syn keyword cConstant HydrologyshreveKnEnum
-syn keyword cConstant HydrologyshreveNEnum
-syn keyword cConstant HydrologyshrevePEnum
-syn keyword cConstant HydrologyshreveQEnum
 syn keyword cConstant HydrologyshreveSpcwatercolumnEnum
 syn keyword cConstant HydrologyshreveStabilizationEnum
@@ -637,4 +633,5 @@
 syn keyword cConstant SedimentHeadOldEnum
 syn keyword cConstant SedimentHeadResidualEnum
+syn keyword cConstant EffectivePressureEnum
 syn keyword cConstant EplHeadEnum
 syn keyword cConstant EplHeadOldEnum
@@ -655,4 +652,5 @@
 syn keyword cConstant HydrologydcEplPorosityEnum
 syn keyword cConstant HydrologydcEplInitialThicknessEnum
+syn keyword cConstant HydrologydcEplMaxThicknessEnum
 syn keyword cConstant HydrologydcEplThicknessEnum
 syn keyword cConstant HydrologydcEplThicknessOldEnum
@@ -677,10 +675,20 @@
 syn keyword cConstant InversionGradientScalingEnum
 syn keyword cConstant InversionIscontrolEnum
-syn keyword cConstant InversionTaoEnum
+syn keyword cConstant InversionTypeEnum
 syn keyword cConstant InversionIncompleteAdjointEnum
 syn keyword cConstant InversionMaxParametersEnum
 syn keyword cConstant InversionMaxiterPerStepEnum
+syn keyword cConstant InversionMaxiterEnum
+syn keyword cConstant InversionMaxstepsEnum
+syn keyword cConstant InversionFatolEnum
+syn keyword cConstant InversionFgtolEnum
+syn keyword cConstant InversionGatolEnum
+syn keyword cConstant InversionGgtolEnum
+syn keyword cConstant InversionGttolEnum
+syn keyword cConstant InversionAlgorithmEnum
 syn keyword cConstant InversionMinParametersEnum
 syn keyword cConstant InversionNstepsEnum
+syn keyword cConstant InversionDxminEnum
+syn keyword cConstant InversionEpsrelEnum
 syn keyword cConstant InversionNumControlParametersEnum
 syn keyword cConstant InversionNumCostFunctionsEnum
@@ -701,4 +709,5 @@
 syn keyword cConstant MaterialsRheologyLawEnum
 syn keyword cConstant MaterialsRheologyNEnum
+syn keyword cConstant DamageIsdamageEnum
 syn keyword cConstant DamageDEnum
 syn keyword cConstant DamageFEnum
@@ -710,4 +719,5 @@
 syn keyword cConstant DamageC3Enum
 syn keyword cConstant DamageC4Enum
+syn keyword cConstant DamageElementinterpEnum
 syn keyword cConstant DamageHealingEnum
 syn keyword cConstant DamageStressThresholdEnum
@@ -734,6 +744,4 @@
 syn keyword cConstant MaterialsMantleDensityEnum
 syn keyword cConstant MeshAverageVertexConnectivityEnum
-syn keyword cConstant MeshElementonbaseEnum
-syn keyword cConstant MeshElementonsurfaceEnum
 syn keyword cConstant MeshElements2dEnum
 syn keyword cConstant MeshElementsEnum
@@ -747,4 +755,5 @@
 syn keyword cConstant MeshVertexonbaseEnum
 syn keyword cConstant MeshVertexonsurfaceEnum
+syn keyword cConstant MeshVertexonboundaryEnum
 syn keyword cConstant MeshXEnum
 syn keyword cConstant MeshYEnum
@@ -818,6 +827,16 @@
 syn keyword cConstant TransientIsgiaEnum
 syn keyword cConstant TransientIsdamageevolutionEnum
+syn keyword cConstant TransientIshydrologyEnum
 syn keyword cConstant TransientNumRequestedOutputsEnum
 syn keyword cConstant TransientRequestedOutputsEnum
+syn keyword cConstant PotentialEnum
+syn keyword cConstant BalancethicknessSpcpotentialEnum
+syn keyword cConstant BalancethicknessApparentMassbalanceEnum
+syn keyword cConstant Balancethickness2MisfitEnum
+syn keyword cConstant BalancethicknessNuxEnum
+syn keyword cConstant BalancethicknessNuyEnum
+syn keyword cConstant BalancethicknessVxObsEnum
+syn keyword cConstant BalancethicknessVyObsEnum
+syn keyword cConstant BalancethicknessThicknessObsEnum
 syn keyword cConstant SurfaceforcingsEnum
 syn keyword cConstant SMBEnum
@@ -851,4 +870,6 @@
 syn keyword cConstant BalancethicknessAnalysisEnum
 syn keyword cConstant BalancethicknessSolutionEnum
+syn keyword cConstant Balancethickness2AnalysisEnum
+syn keyword cConstant Balancethickness2SolutionEnum
 syn keyword cConstant BalancethicknessSoftAnalysisEnum
 syn keyword cConstant BalancethicknessSoftSolutionEnum
@@ -939,4 +960,5 @@
 syn keyword cConstant TransientParamEnum
 syn keyword cConstant MaticeEnum
+syn keyword cConstant MatdamageiceEnum
 syn keyword cConstant MatparEnum
 syn keyword cConstant NodeEnum
@@ -1053,4 +1075,5 @@
 syn keyword cConstant HydrologyWaterVxEnum
 syn keyword cConstant HydrologyWaterVyEnum
+syn keyword cConstant SigmaNNEnum
 syn keyword cConstant StressTensorEnum
 syn keyword cConstant StressTensorxxEnum
Index: /issm/trunk/jenkins/linux64_murdo_ad
===================================================================
--- /issm/trunk/jenkins/linux64_murdo_ad	(revision 17988)
+++ /issm/trunk/jenkins/linux64_murdo_ad	(revision 17989)
@@ -16,4 +16,5 @@
 				--without-kriging \
 				--without-kml \
+				--without-Gia \
 				--with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
 				--with-adolc-dir=$ISSM_DIR/externalpackages/adolc/install \
Index: /issm/trunk/jenkins/linux64_murdo_ampi
===================================================================
--- /issm/trunk/jenkins/linux64_murdo_ampi	(revision 17988)
+++ /issm/trunk/jenkins/linux64_murdo_ampi	(revision 17989)
@@ -16,4 +16,5 @@
 				  --without-kriging \
 				  --without-kml \
+				  --without-Gia \
 				  --with-gsl-dir=$ISSM_DIR/externalpackages/gsl/install \
 				  --with-adolc-dir=$ISSM_DIR/externalpackages/adolc/install \
Index: /issm/trunk/jenkins/windows
===================================================================
--- /issm/trunk/jenkins/windows	(revision 17988)
+++ /issm/trunk/jenkins/windows	(revision 17989)
@@ -15,4 +15,5 @@
 ISSM_CONFIG='--prefix=$ISSM_DIR \
    --disable-static \
+	--without-Gia \
 	--with-vendor=intel-win7-64  \
 	--with-matlab-dir=""$ISSM_DIR/externalpackages/matlab/install"" \
@@ -100,5 +101,5 @@
 
 #In Windows, we don't yet have MUMPS, can't do full stokes, so exclude all FS runs. Also exclude all runs with Dakota. And exclude higher order runs that have penalties.
-MATLAB_NROPTIONS="'exclude',[104, 124, 204, 211, 215, 220, 221, 285, 290, 308, 322, 404, 421, 422, 503, 507, 510, 511, 701, 702, 703, 218, 234, 235, 412, 413, 414, 417, 418, 420, 205, 274, 331, 405, 409, 455, 612, 514, 435]"
+MATLAB_NROPTIONS="'exclude',[104, 124, 204, 211, 215, 220, 221, 285, 290, 308, 322, 404, 421, 422, 503, 507, 510, 511, 701, 702, 703, 218, 234, 235, 412, 413, 414, 417, 418, 420, 205, 274, 331, 405, 409, 455, 612, 514, 435 280]"
 PYTHON_NROPTIONS=""
 
Index: /issm/trunk/m4/analyses.m4
===================================================================
--- /issm/trunk/m4/analyses.m4	(revision 17988)
+++ /issm/trunk/m4/analyses.m4	(revision 17989)
@@ -24,4 +24,18 @@
 AC_MSG_RESULT($HAVE_ADJOINTBALANCETHICKNESS)
 dnl }}}
+dnl with-AdjointBalancethickness2{{{
+AC_ARG_WITH([AdjointBalancethickness2],
+	AS_HELP_STRING([--with-AdjointBalancethickness2 = YES], [compile with AdjointBalancethickness2 capabilities (default is yes)]),
+	[ADJOINTBALANCETHICKNESS2=$withval],[ADJOINTBALANCETHICKNESS2=yes])
+AC_MSG_CHECKING(for AdjointBalancethickness2 capability compilation)
+
+HAVE_ADJOINTBALANCETHICKNESS2=no 
+if test "x$ADJOINTBALANCETHICKNESS2" = "xyes"; then
+	HAVE_ADJOINTBALANCETHICKNESS2=yes
+	AC_DEFINE([_HAVE_ADJOINTBALANCETHICKNESS2_],[1],[with AdjointBalancethickness2capability])
+fi
+AM_CONDITIONAL([ADJOINTBALANCETHICKNESS2], [test x$HAVE_ADJOINTBALANCETHICKNESS2 = xyes])
+AC_MSG_RESULT($HAVE_ADJOINTBALANCETHICKNESS2)
+dnl }}}
 dnl with-AdjointHoriz{{{
 AC_ARG_WITH([AdjointHoriz],
@@ -52,4 +66,18 @@
 AC_MSG_RESULT($HAVE_BALANCETHICKNESS)
 dnl }}}
+dnl with-Balancethickness2{{{
+AC_ARG_WITH([Balancethickness2],
+	AS_HELP_STRING([--with-Balancethickness2 = YES], [compile with Balancethickness2 capabilities (default is yes)]),
+	[BALANCETHICKNESS2=$withval],[BALANCETHICKNESS2=yes])
+AC_MSG_CHECKING(for Balancethickness2 capability compilation)
+
+HAVE_BALANCETHICKNESS2=no 
+if test "x$BALANCETHICKNESS2" = "xyes"; then
+	HAVE_BALANCETHICKNESS2=yes
+	AC_DEFINE([_HAVE_BALANCETHICKNESS2_],[1],[with Balancethickness2capability])
+fi
+AM_CONDITIONAL([BALANCETHICKNESS2], [test x$HAVE_BALANCETHICKNESS2 = xyes])
+AC_MSG_RESULT($HAVE_BALANCETHICKNESS2)
+dnl }}}
 dnl with-BalancethicknessSoft{{{
 AC_ARG_WITH([BalancethicknessSoft],
Index: /issm/trunk/m4/issm_options.m4
===================================================================
--- /issm/trunk/m4/issm_options.m4	(revision 17988)
+++ /issm/trunk/m4/issm_options.m4	(revision 17989)
@@ -940,4 +940,28 @@
 	fi
 	dnl }}}
+	dnl m1qn3{{{
+	AC_ARG_WITH([m1qn3-dir],
+		AS_HELP_STRING([--with-m1qn3-dir=DIR], [m1qn3 root directory.]),
+		[M1QN3_ROOT=$withval],[M1QN3_ROOT="no"]) 
+
+	dnl Check whether m1qn3 is enabled
+	AC_MSG_CHECKING([for m1qn3])
+	if test "x$M1QN3_ROOT" = "xno" ; then
+		HAVE_M1QN3=no
+	else
+		HAVE_M1QN3=yes
+		if ! test -d "$M1QN3_ROOT"; then
+			AC_MSG_ERROR([m1qn3 directory provided ($M1QN3_ROOT) does not exist]);
+		fi
+	fi
+	AC_MSG_RESULT($HAVE_M1QN3)
+	
+	dnl m1qn3 headers and libraries
+	if test "x$HAVE_M1QN3" == "xyes"; then
+	  M1QN3LIB="$M1QN3_ROOT/libm1qn3.a $M1QN3_ROOT//libddot.a"
+	  AC_DEFINE([_HAVE_M1QN3_],[1],[with M1QN3I in ISSM src])
+	  AC_SUBST([M1QN3LIB])
+	fi
+	dnl }}}
 	dnl slepc{{{
 	AC_ARG_WITH([slepc-dir],
Index: /issm/trunk/scripts/GenerateReferences.sh
===================================================================
--- /issm/trunk/scripts/GenerateReferences.sh	(revision 17988)
+++ /issm/trunk/scripts/GenerateReferences.sh	(revision 17989)
@@ -36,3 +36,3 @@
 
 #open output
-open references.rtf
+#open references.rtf
Index: sm/trunk/scripts/Update.sh
===================================================================
--- /issm/trunk/scripts/Update.sh	(revision 17988)
+++ 	(revision )
@@ -1,98 +1,0 @@
-#!/bin/bash
-FILE=$1
-if [ $# -ne 1 ];
-then
-	echo "Usage: ./Update.sh filename "  1>&2
-	exit 1
-fi
-if [ ! -f $FILE ]; then
-	echo "File $FILE does not exist or is empty. Exiting."  1>&2
-	exit 1
-fi
-
-cat $FILE | sed -e "s/md\.name/md.miscellaneous.name/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.spcvx/md.diagnostic.spcvx/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.spcvy/md.diagnostic.spcvy/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.spcvz/md.diagnostic.spcvz/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.spctemperature/md.thermal.spctemperature/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.spcthickness/md.balancethickness.spcthickness/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.bamg/md.private.bamg/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.numberofgrids/md.mesh.numberofvertices/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vx_obs/md.inversion.vx_obs/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vy_obs/md.inversion.vy_obs/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vel_obs/md.inversion.vel_obs/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vx/md.initialization.vx/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vy/md.initialization.vy/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vz/md.initialization.vz/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.vel/md.initialization.vel/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.temperature/md.initialization.temperature/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.pressure/md.initialization.pressure/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.thickness_obs/md.inversion.thickness_obs/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.thickness/md.geometry.thickness/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.bed/md.geometry.bed/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.bathymetry/md.geometry.bathymetry/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.surface_mass_balance/md.surfaceforcings.mass_balance/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.surface=/md.geometry.surface=/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.surface /md.geometry.surface /g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.surface,/md.geometry.surface,/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.surface;/md.geometry.surface;/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.x/md.mesh.x/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.yts/md.constants.yts/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.y/md.mesh.y/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.z/md.mesh.z/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.lat/md.mesh.lat/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.long/md.mesh.long/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.hemisphere/md.mesh.hemisphere/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.numberofnodes/md.mesh.numberofvertices/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.numberofelements/md.mesh.numberofelements/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.drag_coefficient/md.friction.coefficient/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.drag_p/md.friction.p/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.drag_q/md.friction.q/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/setelementstype/setflowequation/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/geography(md/setmask(md/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.rheology_B/md.materials.rheology_B/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.rho_ice/md.materials.rho_ice/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.rho_water/md.materials.rho_water/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.nodeonbed/md.mesh.vertexonbed/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.nodeonboundary/md.mesh.vertexonboundary/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.petscoptions/md.solver/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.dhdt/md.balancethickness.thickening_rate/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.eps_rel/md.diagnostic.reltol/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.eps_res/md.diagnostic.restol/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.eps_abs/md.diagnostic.abstol/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.eps_cm/md.inversion.cost_function_threshold/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.cm_responses/md.inversion.cost_functions/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.nsteps/md.inversion.nsteps/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.weights/md.inversion.cost_functions_coefficients/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.optscal/md.inversion.gradient_scaling/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.cm_jump/md.inversion.step_threshold/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.control_type/md.inversion.control_parameters/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.waitonlock/md.settings.waitonlock/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.cm_min/md.inversion.min_parameters/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.cm_max/md.inversion.max_parameters/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.maxiter/md.inversion.maxiter_per_step/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.control_type/md.inversion.control_parameters/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.control_type/md.inversion.control_parameters/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.min_thermal_constraints/md.thermal.penalty_threshold/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.control_analysis/md.inversion.iscontrol/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/SurfaceAbsVelMisfitEnum/101/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/SurfaceRelVelMisfitEnum/102/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/SurfaceLogVelMisfitEnum/103/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/SurfaceLogVxVyMisfitEnum/104/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/SurfaceAverageVelMisfitEnum/105/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/ThicknessAbsMisfitEnum/201/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/DragCoefficientAbsGradientEnum/501/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/RheologyBbarAbsGradientEnum/502/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/ThicknessAbsGradientEnum/503/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/DragCoefficientEnum/{'FrictionCoefficient'}/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.elementoniceshelf/md.mask.elementonfloatingice/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.nodeoniceshelf/md.mask.vertexonfloatingice/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.elementonicesheet/md.mask.elementongroundedice/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.nodeonicesheet/md.mask.vertexongroundedice/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.elements/md.mesh.elements/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.rheology_n/md.materials.rheology_n/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.gl_migration/md.groundingline.migration/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.hydrostatic_adjustment/md.prognostic.hydrostatic_adjustment/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.rheology_law/md.materials.rheology_law/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.basal_melting_rate/md.basalforcings.melting_rate/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
-cat $FILE | sed -e "s/md\.geothermalflux/md.basalforcings.geothermalflux/g" > $FILE$$.bak && mv $FILE$$.bak $FILE
Index: sm/trunk/scripts/archive.sh
===================================================================
--- /issm/trunk/scripts/archive.sh	(revision 17988)
+++ 	(revision )
@@ -1,22 +1,0 @@
-#!/bin/bash
-#This bash routine  will create a tar file for the ISSM
-#code. Just run the following command: 
-
-#Some local script functions 
-function today_date {
-suffix=`date | awk '{printf("%s-%s-%s",$2,$3,$6);}'` 
-echo $suffix;
-}
-
-#Cleanup code 
-cd $ISSM_DIR
-make clean
-make distclean
-
-#Get rid of externalpackages
-rm -rf externalpackages
-
-#Create tar file, with today's date in the title;
-cd $ISSM_DIR/..
-today=`today_date`
-tar zcvf issm-3.0-$today.tar.gz  `basename $ISSM_DIR`
Index: sm/trunk/scripts/cloc-1.55.pl
===================================================================
--- /issm/trunk/scripts/cloc-1.55.pl	(revision 17988)
+++ 	(revision )
@@ -1,8264 +1,0 @@
-#!/usr/bin/env perl
-# cloc -- Count Lines of Code {{{1
-# Copyright (C) 2006-2011 Northrop Grumman Corporation
-# Author:  Al Danial <al.danial@gmail.com>
-#          First release August 2006
-#
-# Includes code from:
-#   - SLOCCount v2.26 
-#     http://www.dwheeler.com/sloccount/
-#     by David Wheeler.
-#   - Regexp::Common v2.120
-#     http://search.cpan.org/~abigail/Regexp-Common-2.120/lib/Regexp/Common.pm
-#     by Damian Conway and Abigail.
-#   - Win32::Autoglob 
-#     http://search.cpan.org/~sburke/Win32-Autoglob-1.01/Autoglob.pm
-#     by Sean M. Burke.
-#   - Algorithm::Diff
-#     http://search.cpan.org/~tyemq/Algorithm-Diff-1.1902/lib/Algorithm/Diff.pm
-#     by Tye McQueen.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 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 General Public License for more details:
-# http://www.gnu.org/licenses/gpl.txt
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-# 1}}}
-my $VERSION = sprintf("%.2f", 1.55);
-my $URL     = "http://cloc.sourceforge.net";
-require 5.006;
-# use modules                                  {{{1
-use warnings;
-use strict;
-use Getopt::Long;
-use File::Basename;
-use File::Temp qw { tempfile tempdir };
-use File::Find;
-use File::Path;
-use File::Spec;
-use IO::File;
-use POSIX "strftime";
-
-# Digest::MD5 isn't in the standard distribution. Use it only if installed.
-my $HAVE_Digest_MD5 = 0;
-eval "use Digest::MD5;";
-if (defined $Digest::MD5::VERSION) {
-    $HAVE_Digest_MD5 = 1;
-} else {
-    warn "Digest::MD5 not installed; will skip file uniqueness checks.\n";
-}
-
-my $HAVE_Rexexp_Common;
-# Regexp::Common isn't in the standard distribution.  It will
-# be installed in a temp directory if necessary.
-BEGIN {
-    if (eval "use Regexp::Common;") {
-        $HAVE_Rexexp_Common = 1;
-    } else {
-        $HAVE_Rexexp_Common = 0;
-    }
-}
-
-my $HAVE_Algorith_Diff = 0;
-# Algorithm::Diff isn't in the standard distribution.  It will
-# be installed in a temp directory if necessary.
-eval "use Algorithm::Diff qw ( sdiff ) ";
-if (defined $Algorithm::Diff::VERSION) {
-    $HAVE_Algorith_Diff = 1;
-} else {
-    Install_Algorithm_Diff();
-}
-# print "2 HAVE_Algorith_Diff = $HAVE_Algorith_Diff\n";
-# test_alg_diff($ARGV[$#ARGV - 1], $ARGV[$#ARGV]); die;
-
-# Uncomment next two lines when building Windows executable with perl2exe
-# or if running on a system that already has Regexp::Common.
-#use Regexp::Common;
-#$HAVE_Rexexp_Common = 1;
-
-#perl2exe_include "Regexp/Common/whitespace.pm"
-#perl2exe_include "Regexp/Common/URI.pm"
-#perl2exe_include "Regexp/Common/URI/fax.pm"
-#perl2exe_include "Regexp/Common/URI/file.pm"
-#perl2exe_include "Regexp/Common/URI/ftp.pm"
-#perl2exe_include "Regexp/Common/URI/gopher.pm"
-#perl2exe_include "Regexp/Common/URI/http.pm"
-#perl2exe_include "Regexp/Common/URI/pop.pm"
-#perl2exe_include "Regexp/Common/URI/prospero.pm"
-#perl2exe_include "Regexp/Common/URI/news.pm"
-#perl2exe_include "Regexp/Common/URI/tel.pm"
-#perl2exe_include "Regexp/Common/URI/telnet.pm"
-#perl2exe_include "Regexp/Common/URI/tv.pm"
-#perl2exe_include "Regexp/Common/URI/wais.pm"
-#perl2exe_include "Regexp/Common/CC.pm"
-#perl2exe_include "Regexp/Common/SEN.pm"
-#perl2exe_include "Regexp/Common/number.pm"
-#perl2exe_include "Regexp/Common/delimited.pm"
-#perl2exe_include "Regexp/Common/profanity.pm"
-#perl2exe_include "Regexp/Common/net.pm"
-#perl2exe_include "Regexp/Common/zip.pm"
-#perl2exe_include "Regexp/Common/comment.pm"
-#perl2exe_include "Regexp/Common/balanced.pm"
-#perl2exe_include "Regexp/Common/lingua.pm"
-#perl2exe_include "Regexp/Common/list.pm"
-#perl2exe_include "File/Glob.pm"
-
-use Text::Tabs qw { expand };
-use Cwd qw { cwd };
-# 1}}}
-# Usage information, options processing.       {{{1
-my $ON_WINDOWS = 0;
-   $ON_WINDOWS = 1 if ($^O =~ /^MSWin/) or ($^O eq "Windows_NT");
-if ($ON_WINDOWS and $ENV{'SHELL'}) {
-    if ($ENV{'SHELL'} =~ m{^/}) {
-        $ON_WINDOWS = 1;  # make Cygwin look like Unix
-    } else {
-        $ON_WINDOWS = 0;  # MKS defines $SHELL but still acts like Windows
-    }
-}
-
-my $NN     = chr(27) . "[0m";  # normal
-   $NN     = "" if $ON_WINDOWS;
-my $BB     = chr(27) . "[1m";  # bold
-   $BB     = "" if $ON_WINDOWS;
-my $script = basename $0;
-my $usage  = "
-Usage: $script [options] <file(s)/dir(s)> | <set 1> <set 2> | <report files>
-
- Count, or compute differences of, physical lines of source code in the 
- given files (may be archives such as compressed tarballs or zip files) 
- and/or recursively below the given directories.
-
- ${BB}Input Options${NN}
-   --extract-with=<cmd>      This option is only needed if cloc is unable
-                             to figure out how to extract the contents of
-                             the input file(s) by itself.
-                             Use <cmd> to extract binary archive files (e.g.:
-                             .tar.gz, .zip, .Z).  Use the literal '>FILE<' as 
-                             a stand-in for the actual file(s) to be
-                             extracted.  For example, to count lines of code
-                             in the input files 
-                                gcc-4.2.tar.gz  perl-5.8.8.tar.gz  
-                             on Unix use  
-                               --extract-with='gzip -dc >FILE< | tar xf -'
-                             or, if you have GNU tar,
-                               --extract-with='tar zxf >FILE<' 
-                             and on Windows use: 
-                               --extract-with=\"\\\"c:\\Program Files\\WinZip\\WinZip32.exe\\\" -e -o >FILE< .\"
-                             (if WinZip is installed there).
-   --list-file=<file>        Take the list of file and/or directory names to 
-                             process from <file> which has one file/directory 
-                             name per line.  See also --exclude-list-file.
-   --unicode                 Check binary files to see if they contain Unicode
-                             expanded ASCII text.  This causes performance to
-                             drop noticably.
-
- ${BB}Processing Options${NN}
-   --autoconf                Count .in files (as processed by GNU autoconf) of 
-                             recognized languages.
-   --by-file                 Report results for every source file encountered.
-   --by-file-by-lang         Report results for every source file encountered
-                             in addition to reporting by language.
-   --diff <set1> <set2>      Compute differences in code and comments between
-                             source file(s) of <set1> and <set2>.  The inputs
-                             may be pairs of files, directories, or archives.
-                             Use --diff-alignment to generate a list showing
-                             which file pairs where compared.  See also
-                             --ignore-case, --ignore-whitespace.
-   --follow-links            [Unix only] Follow symbolic links to directories
-                             (sym links to files are always followed).
-   --force-lang=<lang>[,<ext>]
-                             Process all files that have a <ext> extension 
-                             with the counter for language <lang>.  For 
-                             example, to count all .f files with the 
-                             Fortran 90 counter (which expects files to 
-                             end with .f90) instead of the default Fortran 77 
-                             counter, use
-                               --force-lang=\"Fortran 90\",f
-                             If <ext> is omitted, every file will be counted
-                             with the <lang> counter.  This option can be 
-                             specified multiple times (but that is only
-                             useful when <ext> is given each time).  
-                             See also --script-lang, --lang-no-ext.
-   --ignore-whitespace       Ignore horizontal white space when comparing files
-                             with --diff.  See also --ignore-case.
-   --ignore-case             Ignore changes in case; consider upper- and lower-
-                             case letters equivalent when comparing files with
-                             --diff.  See also --ignore-whitespace.
-   --lang-no-ext=<lang>      Count files without extensions using the <lang> 
-                             counter.  This option overrides internal logic 
-                             for files without extensions (where such files 
-                             are checked against known scripting languages
-                             by examining the first line for #!).  See also 
-                             --force-lang, --script-lang.
-   --read-binary-files       Process binary files in addition to text files.
-                             This is usually a bad idea and should only be
-                             attempted with text files that have embedded 
-                             binary data.
-   --read-lang-def=<file>    Load from <file> the language processing filters.
-                             (see also --write-lang-def) then use these filters
-                             instead of the built-in filters.
-   --script-lang=<lang>,<s>  Process all files that invoke <s> as a #!
-                             scripting language with the counter for language
-                             <lang>.  For example, files that begin with
-                                #!/usr/local/bin/perl5.8.8
-                             will be counted with the Perl counter by using
-                                --script-lang=Perl,perl5.8.8
-                             The language name is case insensitive but the
-                             name of the script language executable, <s>,
-                             must have the right case.  This option can be 
-                             specified multiple times.  See also --force-lang,
-                             --lang-no-ext.
-   --sdir=<dir>              Use <dir> as the scratch directory instead of
-                             letting File::Temp chose the location.  Files
-                             written to this location are not removed at
-                             the end of the run (as they are with File::Temp).
-   --skip-uniqueness         Skip the file uniqueness check.  This will give
-                             a performance boost at the expense of counting
-                             files with identical contents multiple times
-                             (if such duplicates exist).
-   --strip-comments=<ext>    For each file processed, write to the current
-                             directory a version of the file which has blank
-                             lines and comments removed.  The name of each
-                             stripped file is the original file name with 
-                             .<ext> appended to it.  It is written to the
-                             current directory unless --original-dir is on.
-   --original-dir            [Only effective in combination with 
-                             --strip-comments]  Write the stripped files 
-                             to the same directory as the original files.
-   --sum-reports             Input arguments are report files previously
-                             created with the --report-file option.  Makes
-                             a cumulative set of results containing the
-                             sum of data from the individual report files.
-
- ${BB}Filter Options${NN}
-   --exclude-dir=<D1>[,D2,]  Exclude the given comma separated directories
-                             D1, D2, D3, et cetera, from being scanned.  For
-                             example  --exclude-dir=.cache,test  will skip
-                             all files that have /.cache/ or /test/ as part
-                             of their path.
-                             Directories named .cvs and .svn are always
-                             excluded.
-   --exclude-ext=<ext1>[,<ext2>[...]]
-                             Do not count files having the given file name 
-                             extensions.
-   --exclude-lang=<L1>[,L2,] Exclude the given comma separated languages
-                             L1, L2, L3, et cetera, from being counted.
-   --exclude-list-file=<file>  Ignore files and/or directories whose names 
-                             appear in <file>.  <file> should have one entry 
-                             per line.  Relative path names will be resolved 
-                             starting from the directory where cloc is 
-                             invoked.  See also --list-file.
-   --match-f=<regex>         Only count files whose basenames match the Perl 
-                             regex.  For example
-                               --match-f=^[Ww]idget
-                             only counts files that start with Widget or widget.
-   --not-match-f=<regex>     Count all files except those whose basenames
-                             match the Perl regex.
-   --match-d=<regex>         Only count files in directories matching the Perl 
-                             regex.  For example
-                               --match-d=/src/
-                             only counts files in directories containing
-                             /src/
-   --not-match-d=<regex>     Count all files except those in directories
-                             matching the Perl regex.
-   --skip-win-hidden         On Windows, ignore hidden files.
-
- ${BB}Debug Options${NN}
-   --categorized=<file>      Save names of categorized files to <file>.
-   --counted=<file>          Save names of processed source files to <file>.
-   --diff-alignment=<file>   Write to <file> a list of files and file pairs 
-                             showing which files were added, removed, and/or
-                             compared during a run with --diff.  This switch
-                             forces the --diff mode on.
-   --help                    Print this usage information and exit.
-   --found=<file>            Save names of every file found to <file>.
-   --ignored=<file>          Save names of ignored files and the reason they
-                             were ignored to <file>.
-   --print-filter-stages     Print to STDOUT processed source code before and 
-                             after each filter is applied.
-   --show-ext[=<ext>]        Print information about all known (or just the
-                             given) file extensions and exit.
-   --show-lang[=<lang>]      Print information about all known (or just the
-                             given) languages and exit.
-   -v[=<n>]                  Verbose switch (optional numeric value).
-   --version                 Print the version of this program and exit.
-
-   --write-lang-def=<file>   Writes to <file> the language processing filters
-                             then exits.  Useful as a first step to creating
-                             custom language definitions (see --read-lang-def).
-
- ${BB}Output Options${NN}
-   --3                       Print third-generation language output.
-                             (This option can cause report summation to fail
-                             if some reports were produced with this option
-                             while others were produced without it.)
-   --progress-rate=<n>       Show progress update after every <n> files are
-                             processed (default <n>=100).  Set <n> to 0 to
-                             suppress progress output (useful when redirecting
-                             output to STDOUT).
-   --quiet                   Suppress all information messages except for
-                             the final report.
-   --report-file=<file>      Write the results to <file> instead of STDOUT.
-   --out=<file>              Synonym for --report-file=<file>.
-   --csv                     Write the results as comma separated values.
-   --sql=<file>              Write results as SQL create and insert statements
-                             which can be read by a database program such as
-                             SQLite.  If <file> is 1, output is sent to STDOUT.
-   --sql-project=<name>      Use <name> as the project identifier for the 
-                             current run.  Only valid with the --sql option.
-   --sql-append              Append SQL insert statements to the file specified
-                             by --sql and do not generate table creation 
-                             statements.  Only valid with the --sql option.
-   --sum-one                 For plain text reports, show the SUM: output line 
-                             even if only one input file is processed.
-   --xml                     Write the results in XML.
-   --xsl=<file>              Reference <file> as an XSL stylesheet within
-                             the XML output.  If <file> is 1 (numeric one), 
-                             writes a default stylesheet, cloc.xsl (or 
-                             cloc-diff.xsl if --diff is also given).  
-                             This switch forces --xml on.
-   --yaml                    Write the results in YAML.
-
-";
-#  Help information for options not yet implemented:
-#  --inline                  Process comments that appear at the end
-#                            of lines containing code.
-#  --html                    Create HTML files of each input file showing
-#                            comment and code lines in different colors.
-
-$| = 1;  # flush STDOUT
-my $start_time = time();
-my (
-    $opt_categorized          ,
-    $opt_found                ,
-    @opt_force_lang           ,
-    $opt_lang_no_ext          ,
-    @opt_script_lang          ,
-    $opt_diff                 ,
-    $opt_diff_alignment       ,
-    $opt_html                 ,
-    $opt_ignored              ,
-    $opt_counted              ,
-    $opt_show_ext             ,
-    $opt_show_lang            ,
-    $opt_progress_rate        ,
-    $opt_print_filter_stages  ,
-    $opt_v                    ,
-    $opt_version              ,
-    $opt_exclude_lang         ,
-    $opt_exclude_list_file    ,
-    $opt_exclude_dir          ,
-    $opt_read_lang_def        ,
-    $opt_write_lang_def       ,
-    $opt_strip_comments       ,
-    $opt_original_dir         ,
-    $opt_quiet                ,
-    $opt_report_file          ,
-    $opt_sdir                 ,
-    $opt_sum_reports          ,
-    $opt_unicode              ,
-    $opt_no3                  ,   # accept it but don't use it
-    $opt_3                    ,
-    $opt_extract_with         ,
-    $opt_by_file              ,
-    $opt_by_file_by_lang      ,
-    $opt_xml                  ,
-    $opt_xsl                  ,
-    $opt_yaml                 ,
-    $opt_csv                  ,
-	$opt_match_f              ,
-	$opt_not_match_f          ,
-	$opt_match_d              ,
-	$opt_not_match_d          ,
-	$opt_skip_uniqueness      ,
-	$opt_list_file            ,
-	$opt_help                 ,
-	$opt_skip_win_hidden      ,
-	$opt_read_binary_files    ,
-	$opt_sql                  ,
-	$opt_sql_append           ,
-	$opt_sql_project          ,
-	$opt_inline               ,
-    $opt_exclude_ext          ,
-    $opt_ignore_whitespace    ,
-    $opt_ignore_case          ,
-    $opt_follow_links         ,
-    $opt_autoconf             ,
-    $opt_sum_one              ,
-   );
-my $getopt_success = GetOptions(
-   "by_file|by-file"                         => \$opt_by_file             ,
-   "by_file_by_lang|by-file-by-lang"         => \$opt_by_file_by_lang     ,
-   "categorized=s"                           => \$opt_categorized         ,
-   "counted=s"                               => \$opt_counted             ,
-   "exclude_lang|exclude-lang=s"             => \$opt_exclude_lang        ,
-   "exclude_dir|exclude-dir=s"               => \$opt_exclude_dir         ,
-   "exclude_list_file|exclude-list-file=s"   => \$opt_exclude_list_file   ,
-   "extract_with|extract-with=s"             => \$opt_extract_with        , 
-   "found=s"                                 => \$opt_found               ,
-   "diff"                                    => \$opt_diff                ,
-   "diff-alignment|diff_alignment=s"         => \$opt_diff_alignment      ,
-   "html"                                    => \$opt_html                ,
-   "ignored=s"                               => \$opt_ignored             ,
-   "quiet"                                   => \$opt_quiet               ,
-   "read_lang_def|read-lang-def=s"           => \$opt_read_lang_def       ,
-   "show_ext|show-ext:s"                     => \$opt_show_ext            ,
-   "show_lang|show-lang:s"                   => \$opt_show_lang           ,
-   "progress_rate|progress-rate=i"           => \$opt_progress_rate       ,
-   "print_filter_stages|print-filter-stages" => \$opt_print_filter_stages ,
-   "report_file|report-file=s"               => \$opt_report_file         ,
-   "out=s"                                   => \$opt_report_file         ,
-   "script_lang|script-lang=s"               => \@opt_script_lang         ,
-   "sdir=s"                                  => \$opt_sdir                ,
-   "skip_uniqueness|skip-uniqueness"         => \$opt_skip_uniqueness     ,
-   "strip_comments|strip-comments=s"         => \$opt_strip_comments      ,
-   "original_dir|original-dir"               => \$opt_original_dir        ,
-   "sum_reports|sum-reports"                 => \$opt_sum_reports         ,
-   "unicode"                                 => \$opt_unicode             ,
-   "no3"                                     => \$opt_no3                 ,  # ignored
-   "3"                                       => \$opt_3                   ,
-   "v:i"                                     => \$opt_v                   ,
-   "version"                                 => \$opt_version             ,
-   "write_lang_def|write-lang-def=s"         => \$opt_write_lang_def      ,
-   "xml"                                     => \$opt_xml                 ,
-   "xsl=s"                                   => \$opt_xsl                 ,
-   "force_lang|force-lang=s"                 => \@opt_force_lang          ,
-   "lang_no_ext|lang-no-ext=s"               => \$opt_lang_no_ext         ,
-   "yaml"                                    => \$opt_yaml                ,
-   "csv"                                     => \$opt_csv                 ,
-   "match_f|match-f=s"                       => \$opt_match_f             ,
-   "not_match_f|not-match-f=s"               => \$opt_not_match_f         ,
-   "match_d|match-d=s"                       => \$opt_match_d             ,
-   "not_match_d|not-match-d=s"               => \$opt_not_match_d         ,
-   "list_file|list-file=s"                   => \$opt_list_file           ,
-   "help"                                    => \$opt_help                ,
-   "skip_win_hidden|skip-win-hidden"         => \$opt_skip_win_hidden     ,
-   "read_binary_files|read-binary-files"     => \$opt_read_binary_files   ,
-   "sql=s"                                   => \$opt_sql                 ,
-   "sql_project|sql-project=s"               => \$opt_sql_project         ,
-   "sql_append|sql-append"                   => \$opt_sql_append          ,
-   "inline"                                  => \$opt_inline              ,
-   "exclude_ext|exclude-ext=s"               => \$opt_exclude_ext         ,
-   "ignore_whitespace|ignore-whitespace"     => \$opt_ignore_whitespace   ,
-   "ignore_case|ignore-case"                 => \$opt_ignore_case         ,
-   "follow_links|follow-links"               => \$opt_follow_links        ,
-   "autoconf"                                => \$opt_autoconf            ,
-   "sum_one|sum-one"                         => \$opt_sum_one             ,
-  );
-$opt_by_file  = 1 if defined  $opt_by_file_by_lang;
-my $CLOC_XSL = "cloc.xsl"; # created with --xsl
-   $CLOC_XSL = "cloc-diff.xsl" if $opt_diff;
-die "\n" unless $getopt_success;
-die $usage if $opt_help;
-my %Exclude_Language = ();
-   %Exclude_Language = map { $_ => 1 } split(/,/, $opt_exclude_lang) 
-        if $opt_exclude_lang;
-my %Exclude_Dir      = ();
-   %Exclude_Dir      = map { $_ => 1 } split(/,/, $opt_exclude_dir ) 
-        if $opt_exclude_dir ;
-# Forcibly exclude .svn, .cvs, .hg directories.  The contents of these
-# directories often conflict with files of interest.
-$opt_exclude_dir       = 1;
-$Exclude_Dir{".svn"}   = 1;
-$Exclude_Dir{".cvs"}   = 1;
-$Exclude_Dir{".hg"}    = 1;
-$opt_diff              = 1 if $opt_diff_alignment;
-$opt_exclude_ext       = "" unless $opt_exclude_ext;
-$opt_ignore_whitespace = 0  unless $opt_ignore_whitespace;
-$opt_ignore_case       = 0  unless $opt_ignore_case;       
-$opt_lang_no_ext       = 0  unless $opt_lang_no_ext;
-$opt_follow_links      = 0  unless $opt_follow_links;
-
-# Options defaults:
-$opt_progress_rate = 100 unless defined $opt_progress_rate;
-if (!defined $opt_v) {
-    $opt_v  = 0;
-} elsif (!$opt_v) {
-    $opt_v  = 1;
-}
-if (defined $opt_xsl) {
-    $opt_xsl = $CLOC_XSL if $opt_xsl eq "1";
-    $opt_xml = 1;
-}
-my $skip_generate_report = 0;
-$opt_sql = 0 unless defined $opt_sql;
-if ($opt_sql eq "1") { # stream SQL output to STDOUT
-    $opt_quiet            = 1;
-    $skip_generate_report = 1;
-    $opt_by_file          = 1;
-    $opt_sum_reports      = 0;
-    $opt_progress_rate    = 0;
-} elsif ($opt_sql)  { # write SQL output to a file
-    $opt_by_file          = 1;
-    $skip_generate_report = 1;
-    $opt_sum_reports      = 0;
-}
-die $usage unless defined $opt_version         or
-                  defined $opt_show_lang       or
-                  defined $opt_show_ext        or
-                  defined $opt_write_lang_def  or
-                  defined $opt_list_file       or
-                  defined $opt_xsl             or
-                  scalar @ARGV >= 1;
-die "--diff requires at least two arguments\n" 
-    if $opt_diff and scalar @ARGV < 2;
-if ($opt_version) {
-    printf "$VERSION\n";
-    exit;
-}
-# 1}}}
-# Step 1:  Initialize global constants.        {{{1
-#
-my $nFiles_Found = 0;  # updated in make_file_list
-my (%Language_by_Extension, %Language_by_Script,
-    %Filters_by_Language, %Not_Code_Extension, %Not_Code_Filename,
-    %Language_by_File, %Scale_Factor, %Known_Binary_Archives,
-    %EOL_Continuation_re,
-   );
-my $ALREADY_SHOWED_HEADER = 0;
-my $ALREADY_SHOWED_XML_SECTION = 0;
-my %Error_Codes = ( 'Unable to read'                => -1,
-                    'Neither file nor directory'    => -2, 
-                    'Diff error (quoted comments?)' => -3, 
-                  );
-if ($opt_read_lang_def) {
-    read_lang_def(
-        $opt_read_lang_def     , #        Sample values:
-        \%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77' 
-        \%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'
-        \%Language_by_File     , # Language_by_File{makefile}  = 'make'
-        \%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] = 
-                                 #      [ 'remove_matches' , '^\s*#'  ]
-        \%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1
-        \%Not_Code_Filename    , # Not_Code_Filename{README}   = 1
-        \%Scale_Factor         , # Scale_Factor{Perl}          = 4.0
-        \%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\$'
-        );
-} else {
-    set_constants(               #
-        \%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77' 
-        \%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'
-        \%Language_by_File     , # Language_by_File{makefile}  = 'make'
-        \%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] = 
-                                 #      [ 'remove_matches' , '^\s*#'  ]
-        \%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1
-        \%Not_Code_Filename    , # Not_Code_Filename{README}   = 1
-        \%Scale_Factor         , # Scale_Factor{Perl}          = 4.0
-        \%Known_Binary_Archives, # Known_Binary_Archives{.tar} = 1
-        \%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\$'
-        );
-}
-if ($opt_lang_no_ext and !defined $Filters_by_Language{$opt_lang_no_ext}) {
-    die_unknown_lang($opt_lang_no_ext, "--lang-no-ext")
-}
-
-# Process command line provided extention-to-language mapping overrides.
-# Make a hash of known languages in lower case for easier matching.
-my %Recognized_Language_lc = (); # key = language name in lc, value = true name
-foreach my $language (keys %Filters_by_Language) {
-    my $lang_lc = lc $language;
-    $Recognized_Language_lc{$lang_lc} = $language;
-}
-my %Forced_Extension = (); # file name extensions which user wants to count
-my $All_One_Language = 0;  # set to !0 if --force-lang's <ext> is missing
-foreach my $pair (@opt_force_lang) {
-    my ($lang, $extension) = split(',', $pair);
-    my $lang_lc = lc $lang;
-    if (defined $extension) {
-        $Forced_Extension{$extension} = $lang;
-
-        die_unknown_lang($lang, "--force-lang")
-            unless $Recognized_Language_lc{$lang_lc}; 
-
-        $Language_by_Extension{$extension} = $Recognized_Language_lc{$lang_lc};
-    } else {
-        # the scary case--count everything as this language
-        $All_One_Language = $Recognized_Language_lc{$lang_lc};
-    }
-}
-
-foreach my $pair (@opt_script_lang) {
-    my ($lang, $script_name) = split(',', $pair);
-    my $lang_lc = lc $lang;
-    if (!defined $script_name) {
-        die "The --script-lang option requires a comma separated pair of ".
-            "strings.\n";
-    }
-
-    die_unknown_lang($lang, "--script-lang")
-        unless $Recognized_Language_lc{$lang_lc}; 
-
-    $Language_by_Script{$script_name} = $Recognized_Language_lc{$lang_lc};
-}
-
-# If user provided file extensions to ignore, add these to
-# the exclusion list.
-foreach my $ext (map { $_ => 1 } split(/,/, $opt_exclude_ext ) ) {
-    $ext = lc $ext if $ON_WINDOWS;
-    $Not_Code_Extension{$ext} = 1;
-}
-
-# If SQL output is requested, keep track of directory names generated by 
-# File::Temp::tempdir and used to temporarily hold the results of compressed
-# archives.  Contents of the SQL table 't' will be much cleaner if these
-# meaningless directory names are stripped from the front of files pulled
-# from the archives.
-my %TEMP_DIR = ();
-
-# invert %Language_by_Script hash to get an easy-to-look-up list of known
-# scripting languages
-my %Script_Language = map { $_ => 1 } values %Language_by_Script ;
-# 1}}}
-# Step 2:  Early exits for display, summation. {{{1
-#
-print_extension_info($opt_show_ext ) if defined $opt_show_ext ;
-print_language_info( $opt_show_lang) if defined $opt_show_lang;
-exit if (defined $opt_show_ext) or (defined $opt_show_lang);
-
-#print "Before glob have [", join(",", @ARGV), "]\n";
-@ARGV = windows_glob(@ARGV) if $ON_WINDOWS;
-#print "after  glob have [", join(",", @ARGV), "]\n";
-
-if ($opt_sum_reports and $opt_diff) {
-    my @results = ();
-    if ($opt_list_file) { # read inputs from the list file
-        my @list = read_list_file($opt_list_file);
-        @results = combine_diffs(\@list);
-    } else { # get inputs from the command line
-        @results = combine_diffs(\@ARGV);
-    }
-    if ($opt_report_file) {
-        write_file($opt_report_file, @results);
-    } else {
-        print "\n", join("\n", @results), "\n";
-    }
-    exit;
-}
-if ($opt_sum_reports) {
-    my %Results = ();
-    foreach my $type( "by language", "by report file" ) {
-        my $found_lang = undef; 
-        if ($opt_list_file) { # read inputs from the list file
-            my @list = read_list_file($opt_list_file);
-            $found_lang = combine_results(\@list, 
-                                           $type, 
-                                          \%{$Results{ $type }}, 
-                                          \%Filters_by_Language );
-        } else { # get inputs from the command line
-            $found_lang = combine_results(\@ARGV, 
-                                           $type, 
-                                          \%{$Results{ $type }}, 
-                                          \%Filters_by_Language );
-        }
-        next unless %Results;
-        my $end_time = time();
-        my @results  = generate_report($VERSION, $end_time - $start_time,
-                                       $type,
-                                      \%{$Results{ $type }}, \%Scale_Factor);
-        if ($opt_report_file) {
-            my $ext  = ".lang";
-               $ext  = ".file" unless $type eq "by language";
-            next if !$found_lang and  $ext  eq ".lang";
-            write_file($opt_report_file . $ext, @results);
-        } else {
-            print "\n", join("\n", @results), "\n";
-        }
-    }
-    exit;
-}
-if ($opt_write_lang_def) {
-    write_lang_def($opt_write_lang_def   ,
-                  \%Language_by_Extension,
-                  \%Language_by_Script   ,
-                  \%Language_by_File     ,
-                  \%Filters_by_Language  ,
-                  \%Not_Code_Extension   ,
-                  \%Not_Code_Filename    ,
-                  \%Scale_Factor         ,
-                  \%EOL_Continuation_re  ,
-                  );
-    exit;
-}
-# 1}}}
-# Step 3:  Create a list of files to consider. {{{1
-#  a) If inputs are binary archives, first cd to a temp
-#     directory, expand the archive with the user-given
-#     extraction tool, then add the temp directory to
-#     the list of dirs to process.
-#  b) Create a list of every file that might contain source
-#     code.  Ignore binary files, zero-sized files, and
-#     any file in a directory the user says to exclude.
-#  c) Determine the language for each file in the list.
-#
-my @binary_archive = ();
-my $cwd            = cwd();
-if ($opt_extract_with) {
-#print "cwd main = [$cwd]\n";
-    my @extract_location = ();
-    foreach my $bin_file (@ARGV) {
-        my $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
-        $TEMP_DIR{ $extract_dir } = 1 if $opt_sql;
-        print "mkdir $extract_dir\n" if $opt_v;
-        print "cd    $extract_dir\n" if $opt_v;
-        chdir $extract_dir;
-        my $bin_file_full_path = "";
-        if (File::Spec->file_name_is_absolute( $bin_file )) {
-            $bin_file_full_path = $bin_file;
-#print "bin_file_full_path (was ful) = [$bin_file_full_path]\n";
-        } else {
-            $bin_file_full_path = File::Spec->catfile( $cwd, $bin_file );
-#print "bin_file_full_path (was rel) = [$bin_file_full_path]\n";
-        }
-        my     $extract_cmd = uncompress_archive_cmd($bin_file_full_path);
-        print  $extract_cmd, "\n" if $opt_v;
-        system $extract_cmd;
-        push @extract_location, $extract_dir;
-        chdir $cwd;
-    }
-    # It is possible that the binary archive itself contains additional
-    # files compressed the same way (true for Java .ear files).  Go
-    # through all the files that were extracted, see if they are binary
-    # archives and try to extract them.  Lather, rinse, repeat.
-    my $binary_archives_exist = 1;
-    my $count_binary_archives = 0;
-    my $previous_count        = 0;
-    while ($binary_archives_exist) {
-        @binary_archive = ();
-        foreach my $dir (@extract_location) {
-            find(\&archive_files, $dir);  # populates global @binary_archive
-        }
-        foreach my $archive (@binary_archive) {
-            my     $extract_dir = tempdir( CLEANUP => 1 ); # 1 = delete on exit
-            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql;
-            print "mkdir $extract_dir\n" if $opt_v;
-            print "cd    $extract_dir\n" if $opt_v;
-            chdir  $extract_dir;
-
-            my     $extract_cmd = uncompress_archive_cmd($archive);
-            print  $extract_cmd, "\n" if $opt_v;
-            system $extract_cmd;
-            push @extract_location, $extract_dir;
-            unlink $archive;  # otherwise will be extracting it forever 
-        }
-        $count_binary_archives = scalar @binary_archive;
-        if ($count_binary_archives == $previous_count) {
-            $binary_archives_exist = 0;
-        }
-        $previous_count = $count_binary_archives;
-    }
-    chdir $cwd;
-
-    @ARGV = @extract_location;
-} else {
-    # see if any of the inputs need to be auto-uncompressed &/or expanded
-    my @updated_ARGS = ();
-    foreach my $Arg (@ARGV) {
-        if (is_dir($Arg)) {
-            push @updated_ARGS, $Arg;
-            next;
-        }
-        my $full_path = "";
-        if (File::Spec->file_name_is_absolute( $Arg )) {
-            $full_path = $Arg;
-        } else {
-            $full_path = File::Spec->catfile( $cwd, $Arg );
-        }
-#print "full_path = [$full_path]\n";
-        my $extract_cmd = uncompress_archive_cmd($full_path);
-        if ($extract_cmd) {
-            my     $extract_dir = tempdir( CLEANUP => 1 ); # 1 = delete on exit
-            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql;
-            print "mkdir $extract_dir\n" if $opt_v;
-            print "cd    $extract_dir\n" if $opt_v;
-            chdir  $extract_dir;
-            print  $extract_cmd, "\n" if $opt_v;
-            system $extract_cmd;
-            push @updated_ARGS, $extract_dir;
-            chdir $cwd;
-        } else {
-            # this is a conventional, uncompressed, unarchived file
-            # or a directory; keep as-is
-            push @updated_ARGS, $Arg;
-        }
-    }
-    @ARGV = @updated_ARGS;
-}
-# 1}}}
-my @Errors    = ();
-my @file_list = ();  # global variable updated in files()
-my %Ignored   = ();  # files that are not counted (language not recognized or
-                     # problems reading the file)
-my @Lines_Out = ();
-if ($opt_diff) {
-# Step 4:  Separate code from non-code files. {{{1
-my @fh            = ();
-my @files_for_set = ();
-# make file lists for each separate argument
-if ($opt_exclude_list_file) {
-    process_exclude_list_file($opt_exclude_list_file, 
-                             \%Exclude_Dir,
-                             \%Ignored);
-}
-for (my $i = 0; $i < scalar @ARGV; $i++) {
-    push @fh, 
-         make_file_list([ $ARGV[$i] ], \%Error_Codes, \@Errors, \%Ignored);
-    @{$files_for_set[$i]} = @file_list;
-    @file_list = ();
-}
-# 1}}}
-# Step 5:  Remove duplicate files.             {{{1
-#
-my %Language           = ();
-my %unique_source_file = ();
-my $n_set = 0;
-foreach my $FH (@fh) {  # loop over each pair of file sets
-    ++$n_set;
-    remove_duplicate_files($FH, 
-                               \%{$Language{$FH}}               , 
-                               \%{$unique_source_file{$FH}}     , 
-                          \%Error_Codes                         , 
-                               \@Errors                         , 
-                               \%Ignored                        );
-    printf "%2d: %8d unique file%s.                          \r", 
-        $n_set,
-        plural_form(scalar keys %unique_source_file) 
-        unless $opt_quiet;
-}
-# 1}}}
-# Step 6:  Count code, comments, blank lines.  {{{1
-#
-my %Results_by_Language = ();
-my %Results_by_File     = ();
-my %Delta_by_Language   = ();
-my %Delta_by_File       = ();
-my $nFiles_added        = 0;
-my $nFiles_removed      = 0;
-my $nFiles_modified     = 0;
-my $nFiles_same         = 0;
-
-foreach (my $F = 0; $F < scalar @fh - 1; $F++) { 
-    # loop over file sets; do diff between set $F to $F+1
-
-    my $nCounted = 0;
-
-    my @file_pairs    = ();
-    my @files_added   = ();
-    my @files_removed = ();
-
-    align_by_pairs(\%{$unique_source_file{$fh[$F  ]}}    , # in
-                   \%{$unique_source_file{$fh[$F+1]}}    , # in
-                   \@files_added                         , # out
-                   \@files_removed                       , # out
-                   \@file_pairs                          , # out
-                   );
-    if (!@file_pairs) {
-        # Special case where all files were either added or deleted.
-        # In this case, one of these arrays will be empty: 
-        #   @files_added, @files_removed
-        # so loop over both to cover both cases.
-        my $status = @files_added ? 'added' : 'removed';
-        my $offset = @files_added ? 1       : 0        ;
-        foreach my $file (@files_added, @files_removed) {
-            my $Lang = $Language{$fh[$F+$offset]}{$file};
-            my ($all_line_count,
-                $blank_count   ,
-                $comment_count ,
-               ) = call_counter($file, $Lang, \@Errors);
-            my $code_count = $all_line_count-$blank_count-$comment_count;
-            if ($opt_by_file) {
-                $Delta_by_File{$file}{'code'   }{$status} += $code_count   ;
-                $Delta_by_File{$file}{'blank'  }{$status} += $blank_count  ;
-                $Delta_by_File{$file}{'comment'}{$status} += $comment_count;
-                $Delta_by_File{$file}{'lang'   }{$status}  = $Lang         ;
-                $Delta_by_File{$file}{'nFiles' }{$status} += 1             ;
-            }
-            $Delta_by_Language{$Lang}{'code'   }{$status} += $code_count   ;
-            $Delta_by_Language{$Lang}{'blank'  }{$status} += $blank_count  ;
-            $Delta_by_Language{$Lang}{'comment'}{$status} += $comment_count;
-        }
-    }
-   #use Data::Dumper::Simple;
-   #use Data::Dumper;
-   #print Dumper(\@files_added, \@files_removed, \@file_pairs);
-    my @alignment = (); # only  used if --diff-alignment
-#print "after align_by_pairs:\n";
-
-#print "added:\n";
-    push @alignment, sprintf "Files added: %d\n", scalar @files_added
-        if $opt_diff_alignment;
-    foreach my $f (@files_added) {
-#printf "%10s -> %s\n", $f, $Language{$fh[$F+1]}{$f};
-        # Don't proceed unless the file (both L and R versions)
-        # is in a known language.
-        next if $Language{$fh[$F+1]}{$f} eq "(unknown)";
-        next if $Exclude_Language{$Language{$fh[$F+1]}{$f}};
-        push @alignment, sprintf "  + %s ; %s\n", $f, $Language{$fh[$F+1]}{$f}
-            if $opt_diff_alignment;
-        ++$Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'nFiles'}{'added'};
-        # Additionally, add contents of file $f to 
-        #        Delta_by_File{$f}{comment/blank/code}{'added'}
-        #        Delta_by_Language{$lang}{comment/blank/code}{'added'}
-        my ($all_line_count,
-            $blank_count   ,
-            $comment_count ,
-           ) = call_counter($f, $Language{$fh[$F+1]}{$f}, \@Errors);
-        $Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'comment'}{'added'} +=
-            $comment_count;
-        $Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'blank'}{'added'}   +=
-            $blank_count;
-        $Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'code'}{'added'}    +=
-            $all_line_count - $blank_count - $comment_count;
-        $Delta_by_File{ $f }{'comment'}{'added'} = $comment_count;
-        $Delta_by_File{ $f }{'blank'}{'added'}   = $blank_count;
-        $Delta_by_File{ $f }{'code'}{'added'}    = 
-            $all_line_count - $blank_count - $comment_count;
-    }
-    push @alignment, "\n";
-
-#print "removed:\n";
-    push @alignment, sprintf "Files removed: %d\n", scalar @files_removed
-        if $opt_diff_alignment;
-    foreach my $f (@files_removed) {
-        # Don't proceed unless the file (both L and R versions)
-        # is in a known language.
-        next if $Language{$fh[$F  ]}{$f} eq "(unknown)";
-        next if $Exclude_Language{$Language{$fh[$F  ]}{$f}};
-        ++$Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'nFiles'}{'removed'};
-        push @alignment, sprintf "  - %s ; %s\n", $f, $Language{$fh[$F]}{$f}
-            if $opt_diff_alignment;
-#printf "%10s -> %s\n", $f, $Language{$fh[$F  ]}{$f};
-        # Additionally, add contents of file $f to 
-        #        Delta_by_File{$f}{comment/blank/code}{'removed'}
-        #        Delta_by_Language{$lang}{comment/blank/code}{'removed'}
-        my ($all_line_count,
-            $blank_count   ,
-            $comment_count ,
-           ) = call_counter($f, $Language{$fh[$F  ]}{$f}, \@Errors);
-        $Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'comment'}{'removed'} +=
-            $comment_count;
-        $Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'blank'}{'removed'}   +=
-            $blank_count;
-        $Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'code'}{'removed'}    +=
-            $all_line_count - $blank_count - $comment_count;
-        $Delta_by_File{ $f }{'comment'}{'removed'} = $comment_count;
-        $Delta_by_File{ $f }{'blank'}{'removed'}   = $blank_count;
-        $Delta_by_File{ $f }{'code'}{'removed'}    = 
-            $all_line_count - $blank_count - $comment_count;
-    }
-    push @alignment, "\n";
-
-    push @alignment, sprintf "File pairs compared: %d\n", scalar @file_pairs
-        if $opt_diff_alignment;
-#print "Language=\n", Dumper(\%Language);
-    foreach my $pair (@file_pairs) {
-        my $file_L = $pair->[0];
-        my $file_R = $pair->[1];
-        my $Lang_L = $Language{$fh[$F  ]}{$file_L};
-        my $Lang_R = $Language{$fh[$F+1]}{$file_R};
-#print "main step 6 file_L=$file_L    file_R=$file_R\n";
-        ++$nCounted;
-        printf "Counting:  %d\r", $nCounted 
-            unless (!$opt_progress_rate or ($nCounted % $opt_progress_rate));
-        next if $Ignored{$file_L};
-
-        # filter out excluded or unrecognized languages
-        if ($Exclude_Language{$Lang_L} or $Exclude_Language{$Lang_R}) {
-            $Ignored{$file_L} = "--exclude-lang=$Lang_L}";
-            $Ignored{$file_R} = "--exclude-lang=$Lang_R}";
-            next;
-        }
-        if (!defined @{$Filters_by_Language{$Lang_L} } or
-            !defined @{$Filters_by_Language{$Lang_R} }
-           ) {
-            if (($Lang_L eq "(unknown)") or ($Lang_R eq "(unknown)")) {
-                $Ignored{$fh[$F  ]}{$file_L} = "language unknown (#1)";
-                $Ignored{$fh[$F+1]}{$file_R} = "language unknown (#1)";
-            } else {
-                $Ignored{$fh[$F  ]}{$file_L} = "missing Filters_by_Language{$Lang_L}";
-                $Ignored{$fh[$F+1]}{$file_R} = "missing Filters_by_Language{$Lang_R}";
-            }
-            next;
-        }
-
-#print "DIFF($file_L, $file_R)\n";
-        # step 0: compare the two files' contents 
-        chomp ( my @lines_L = read_file($file_L) );
-        chomp ( my @lines_R = read_file($file_R) );
-        my $language_file_L = "";
-        if (defined $Language{$fh[$F]}{$file_L}) {
-            $language_file_L = $Language{$fh[$F]}{$file_L};
-        } else {
-            # files $file_L and $file_R do not contain known language
-            next;
-        }
-        my $contents_are_same = 1;
-        if (scalar @lines_L == scalar @lines_R) {
-            # same size, must compare line-by-line
-            for (my $i = 0; $i < scalar @lines_L; $i++) {
-                if ($lines_L[$i] ne $lines_R[$i]) {
-                    $contents_are_same = 0;
-                    last;
-                }
-            }
-            if ($contents_are_same) {
-                ++$Delta_by_Language{$language_file_L}{'nFiles'}{'same'};
-            } else {
-                ++$Delta_by_Language{$language_file_L}{'nFiles'}{'modified'};
-            }
-        } else {
-            $contents_are_same = 0;
-            # different sizes, contents have changed
-            ++$Delta_by_Language{$language_file_L}{'nFiles'}{'modified'};
-        }
-        if ($opt_diff_alignment) {
-            my $str =  "$file_L | $file_R ; $language_file_L";
-            if ($contents_are_same) {
-                push @alignment, "  == $str";
-            } else {
-                push @alignment, "  != $str";
-            }
-        }
-
-        # step 1: identify comments in both files
-#print "Diff blank removal L language= $Lang_L";
-#print " scalar(lines_L)=", scalar @lines_L, "\n";
-        my @original_minus_blanks_L 
-                    = rm_blanks(  \@lines_L, $Lang_L, \%EOL_Continuation_re);
-#print "1: scalar(original_minus_blanks_L)=", scalar @original_minus_blanks_L, "\n";
-        @lines_L    = @original_minus_blanks_L;
-#print "2: scalar(lines_L)=", scalar @lines_L, "\n";
-        @lines_L    = add_newlines(\@lines_L); # compensate for rm_comments()
-        @lines_L    = rm_comments( \@lines_L, $Lang_L, $file_L,
-                                   \%EOL_Continuation_re);
-#print "3: scalar(lines_L)=", scalar @lines_L, "\n";
-
-#print "Diff blank removal R language= $Lang_R\n";
-        my @original_minus_blanks_R 
-                    = rm_blanks(  \@lines_R, $Lang_R, \%EOL_Continuation_re);
-        @lines_R    = @original_minus_blanks_R;
-        @lines_R    = add_newlines(\@lines_R); # taken away by rm_comments()
-        @lines_R    = rm_comments( \@lines_R, $Lang_R, $file_R,
-                                   \%EOL_Continuation_re);
-
-        my (@diff_LL, @diff_LR, );
-        array_diff( $file_L                  ,   # in
-                   \@original_minus_blanks_L ,   # in
-                   \@lines_L                 ,   # in
-                   "comment"                 ,   # in
-                   \@diff_LL, \@diff_LR      ,   # out
-                   \@Errors);                    # in/out
-
-        my (@diff_RL, @diff_RR, );
-        array_diff( $file_R                  ,   # in
-                   \@original_minus_blanks_R ,   # in
-                   \@lines_R                 ,   # in
-                   "comment"                 ,   # in
-                   \@diff_RL, \@diff_RR      ,   # out
-                   \@Errors);                    # in/out
-        # each line of each file is now classified as
-        # code or comment
-
-#use Data::Dumper; 
-#print Dumper("diff_LL", \@diff_LL, "diff_LR", \@diff_LR, );
-#print Dumper("diff_RL", \@diff_RL, "diff_RR", \@diff_RR, );
-#die;
-        # step 2: separate code from comments for L and R files
-        my @code_L = ();
-        my @code_R = ();
-        my @comm_L = ();
-        my @comm_R = ();
-        foreach my $line_info (@diff_LL) {
-            if      ($line_info->{'type'} eq "code"   ) {
-                push @code_L, $line_info->{char};
-            } elsif ($line_info->{'type'} eq "comment") {
-                push @comm_L, $line_info->{char};
-            } else {
-                die "Diff unexpected line type ",
-                    $line_info->{'type'}, "for $file_L line ",
-                    $line_info->{'lnum'};
-            }
-        }
-        foreach my $line_info (@diff_RL) {
-            if      ($line_info->{type} eq "code"   ) {
-                push @code_R, $line_info->{'char'};
-            } elsif ($line_info->{type} eq "comment") {
-                push @comm_R, $line_info->{'char'};
-            } else {
-                die "Diff unexpected line type ",
-                    $line_info->{'type'}, "for $file_R line ",
-                    $line_info->{'lnum'};
-            }
-        }
-
-        if ($opt_ignore_whitespace) {
-            # strip all whitespace from each line of source code
-            # and comments then use these stripped arrays in diffs
-            foreach (@code_L) { s/\s+//g }
-            foreach (@code_R) { s/\s+//g }
-            foreach (@comm_L) { s/\s+//g }
-            foreach (@comm_R) { s/\s+//g }
-        }
-        if ($opt_ignore_case) {
-            # change all text to lowercase in diffs
-            foreach (@code_L) { $_ = lc }
-            foreach (@code_R) { $_ = lc }
-            foreach (@comm_L) { $_ = lc }
-            foreach (@comm_R) { $_ = lc }
-        }
-        # step 3: compute code diffs
-        array_diff("$file_L v. $file_R"   ,   # in
-                   \@code_L               ,   # in
-                   \@code_R               ,   # in
-                   "revision"             ,   # in
-                   \@diff_LL, \@diff_LR   ,   # out
-                   \@Errors);                 # in/out
-#print Dumper("diff_LL", \@diff_LL, "diff_LR", \@diff_LR, );
-#print Dumper("diff_LR", \@diff_LR);
-        foreach my $line_info (@diff_LR) {
-            my $status = $line_info->{'desc'}; # same|added|removed|modified
-            ++$Delta_by_Language{$Lang_L}{'code'}{$status};
-            if ($opt_by_file) {
-                ++$Delta_by_File{$file_L}{'code'}{$status};
-            }
-        }
-#use Data::Dumper;
-#print Dumper("code diffs:", \@diff_LL, \@diff_LR);
-
-        # step 4: compute comment diffs
-        array_diff("$file_L v. $file_R"   ,   # in
-                   \@comm_L               ,   # in
-                   \@comm_R               ,   # in
-                   "revision"             ,   # in
-                   \@diff_LL, \@diff_LR   ,   # out
-                   \@Errors);                 # in/out
-#print Dumper("comment diff_LR", \@diff_LR);
-        foreach my $line_info (@diff_LR) {
-            my $status = $line_info->{'desc'}; # same|added|removed|modified
-            ++$Delta_by_Language{$Lang_L}{'comment'}{$status};
-            if ($opt_by_file) {
-                ++$Delta_by_File{$file_L}{'comment'}{$status};
-            }
-        }
-#print Dumper("comment diffs:", \@diff_LL, \@diff_LR);
-#die; here=  need to save original line number in diff result for html display
-
-        # step 5: compute difference in blank lines (kind of pointless)
-        my ($all_line_count_L,
-            $blank_count_L   ,
-            $comment_count_L ,
-           ) = call_counter($file_L, $Lang_L, \@Errors);
-
-        my ($all_line_count_R,
-            $blank_count_R   ,
-            $comment_count_R ,
-           ) = call_counter($file_R, $Lang_R, \@Errors);
-
-        if ($blank_count_L <  $blank_count_R) {
-            my $D = $blank_count_R - $blank_count_L;
-            $Delta_by_Language{$Lang_L}{'blank'}{'added'}   += $D;
-        } else {
-            my $D = $blank_count_L - $blank_count_R;
-            $Delta_by_Language{$Lang_L}{'blank'}{'removed'} += $D;
-        }
-        if ($opt_by_file) {
-            if ($blank_count_L <  $blank_count_R) {
-                my $D = $blank_count_R - $blank_count_L;
-                $Delta_by_File{$file_L}{'blank'}{'added'}   += $D;
-            } else {
-                my $D = $blank_count_L - $blank_count_R;
-                $Delta_by_File{$file_L}{'blank'}{'removed'} += $D;
-            }
-        }
-
-        my $code_count_L = $all_line_count_L-$blank_count_L-$comment_count_L;
-        if ($opt_by_file) {
-            $Results_by_File{$file_L}{'code'   } = $code_count_L    ;
-            $Results_by_File{$file_L}{'blank'  } = $blank_count_L   ;
-            $Results_by_File{$file_L}{'comment'} = $comment_count_L ;
-            $Results_by_File{$file_L}{'lang'   } = $Lang_L          ;
-            $Results_by_File{$file_L}{'nFiles' } = 1                ;
-        } else {
-            $Results_by_File{$file_L} = 1;  # just keep track of counted files
-        }
-   
-        $Results_by_Language{$Lang_L}{'nFiles'}++;
-        $Results_by_Language{$Lang_L}{'code'}    += $code_count_L   ;
-        $Results_by_Language{$Lang_L}{'blank'}   += $blank_count_L  ;
-        $Results_by_Language{$Lang_L}{'comment'} += $comment_count_L;
-    }
-    write_file($opt_diff_alignment, @alignment) if $opt_diff_alignment;
-
-}
-#use Data::Dumper;
-#print Dumper("Delta_by_Language:"  , \%Delta_by_Language);
-#print Dumper("Results_by_Language:", \%Results_by_Language);
-#print Dumper("Delta_by_File:"      , \%Delta_by_File);
-#print Dumper("Results_by_File:"    , \%Results_by_File);
-#die;
-my @ignored_reasons = map { "$_: $Ignored{$_}" } sort keys %Ignored;
-write_file($opt_ignored, @ignored_reasons   ) if $opt_ignored;
-write_file($opt_counted, sort keys %Results_by_File) if $opt_counted;
-# 1}}}
-# Step 7:  Assemble results.                      {{{1
-#
-my $end_time = time();
-printf "%8d file%s ignored.                           \n", 
-    plural_form(scalar keys %Ignored) unless $opt_quiet;
-print_errors(\%Error_Codes, \@Errors) if @Errors;
-if (!%Delta_by_Language) {
-    print "Nothing to count.\n";
-    exit;
-}
-
-if ($opt_by_file) {
-    @Lines_Out = diff_report($VERSION, time() - $start_time,
-                            "by file",
-                            \%Delta_by_File, \%Scale_Factor);
-} else {
-    @Lines_Out = diff_report($VERSION, time() - $start_time,
-                            "by language",
-                            \%Delta_by_Language, \%Scale_Factor);
-}
-
-# 1}}}
-} else {
-# Step 4:  Separate code from non-code files. {{{1
-my $fh = 0;
-if ($opt_list_file) {
-    my @list = read_list_file($opt_list_file);
-    $fh = make_file_list(\@list, \%Error_Codes, \@Errors, \%Ignored);
-} else {
-    $fh = make_file_list(\@ARGV, \%Error_Codes, \@Errors, \%Ignored);
-    #     make_file_list populates global variable @file_list via call to 
-    #     File::Find's find() which in turn calls files()
-}
-if ($opt_exclude_list_file) {
-    process_exclude_list_file($opt_exclude_list_file, 
-                             \%Exclude_Dir,
-                             \%Ignored);
-}
-if ($opt_skip_win_hidden and $ON_WINDOWS) {
-    my @file_list_minus_hidded = ();
-    # eval code to run on Unix without 'missing Win32::File module' error.
-    my $win32_file_invocation = '
-        use Win32::File;
-        foreach my $F (@file_list) {
-            my $attr = undef;
-            Win32::File::GetAttributes($F, $attr);
-            if ($attr & HIDDEN) {
-                $Ignored{$F} = "Windows hidden file";
-                print "Ignoring $F since it is a Windows hidden file\n" 
-                    if $opt_v > 1;
-            } else {
-                push @file_list_minus_hidded, $F;
-            }
-        }';
-    eval $win32_file_invocation;
-    @file_list = @file_list_minus_hidded;
-}
-#printf "%8d file%s excluded.                     \n", 
-#   plural_form(scalar keys %Ignored) 
-#   unless $opt_quiet;
-# die print ": ", join("\n: ", @file_list), "\n";
-# 1}}}
-# Step 5:  Remove duplicate files.             {{{1
-#
-my %Language           = ();
-my %unique_source_file = ();
-remove_duplicate_files($fh                          ,   # in 
-                           \%Language               ,   # out
-                           \%unique_source_file     ,   # out
-                      \%Error_Codes                 ,   # in
-                           \@Errors                 ,   # out
-                           \%Ignored                );  # out
-printf "%8d unique file%s.                              \n", 
-    plural_form(scalar keys %unique_source_file) 
-    unless $opt_quiet;
-# 1}}}
-# Step 6:  Count code, comments, blank lines.  {{{1
-#
-
-my %Results_by_Language = ();
-my %Results_by_File     = ();
-my $nCounted = 0;
-foreach my $file (sort keys %unique_source_file) {
-    ++$nCounted;
-    printf "Counting:  %d\r", $nCounted 
-        unless (!$opt_progress_rate or ($nCounted % $opt_progress_rate));
-    next if $Ignored{$file};
-    if ($Exclude_Language{$Language{$file}}) {
-        $Ignored{$file} = "--exclude-lang=$Language{$file}";
-        next;
-    }
-    if (!defined @{$Filters_by_Language{$Language{$file}} }) {
-        if ($Language{$file} eq "(unknown)") {
-            $Ignored{$file} = "language unknown (#1)";
-        } else {
-            $Ignored{$file} = "missing Filters_by_Language{$Language{$file}}";
-        }
-        next;
-    }
-
-    my ($all_line_count,
-        $blank_count   ,
-        $comment_count ,
-       ) = call_counter($file, $Language{$file}, \@Errors);
-    my $code_count = $all_line_count - $blank_count - $comment_count;
-    if ($opt_by_file) {
-        $Results_by_File{$file}{'code'   } = $code_count     ;
-        $Results_by_File{$file}{'blank'  } = $blank_count    ;
-        $Results_by_File{$file}{'comment'} = $comment_count  ;
-        $Results_by_File{$file}{'lang'   } = $Language{$file};
-        $Results_by_File{$file}{'nFiles' } = 1;
-    } else {
-        $Results_by_File{$file} = 1;  # just keep track of counted files
-    }
-
-    $Results_by_Language{$Language{$file}}{'nFiles'}++;
-    $Results_by_Language{$Language{$file}}{'code'}    += $code_count   ;
-    $Results_by_Language{$Language{$file}}{'blank'}   += $blank_count  ;
-    $Results_by_Language{$Language{$file}}{'comment'} += $comment_count;
-}
-my @ignored_reasons = map { "$_: $Ignored{$_}" } sort keys %Ignored;
-write_file($opt_ignored, @ignored_reasons   ) if $opt_ignored;
-write_file($opt_counted, sort keys %Results_by_File) if $opt_counted;
-# 1}}}
-# Step 7:  Assemble results.                      {{{1
-#
-my $end_time = time();
-printf "%8d file%s ignored.\n", plural_form(scalar keys %Ignored) 
-    unless $opt_quiet;
-print_errors(\%Error_Codes, \@Errors) if @Errors;
-exit unless %Results_by_Language;
-
-generate_sql($end_time - $start_time,
-            \%Results_by_File, \%Scale_Factor) if $opt_sql;
-
-exit if $skip_generate_report;
-if      ($opt_by_file_by_lang) {
-    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
-                                      "by file",
-                                      \%Results_by_File,    \%Scale_Factor);
-    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
-                                      "by language",
-                                      \%Results_by_Language, \%Scale_Factor);
-} elsif ($opt_by_file) {
-    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
-                                      "by file",
-                                      \%Results_by_File,    \%Scale_Factor);
-} else {
-    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
-                                      "by language",
-                                      \%Results_by_Language, \%Scale_Factor);
-}
-# 1}}}
-}
-if ($opt_report_file) { write_file($opt_report_file, @Lines_Out); } 
-else                  { print "\n", join("\n", @Lines_Out), "\n"; }
-
-sub process_exclude_list_file {              # {{{1
-    my ($list_file      , # in
-        $rh_exclude_dir , # out
-        $rh_ignored     , # out
-       ) = @_;
-    print "-> process_exclude_list_file($list_file)\n" if $opt_v > 2;
-    # reject a specific set of files and/or directories
-    my @reject_list   = read_list_file($list_file);
-    my @file_reject_list = ();
-    foreach my $F_or_D (@reject_list) {
-        if (is_dir($F_or_D)) {
-            $rh_exclude_dir->{$F_or_D} = 1;
-        } elsif (is_file($F_or_D)) {
-            push @file_reject_list, $F_or_D;
-        }
-    }
-
-    # Normalize file names for better comparison.
-    my %normalized_input   = normalize_file_names(@file_list);
-    my %normalized_reject  = normalize_file_names(@file_reject_list);
-    my %normalized_exclude = normalize_file_names(keys %{$rh_exclude_dir});
-    foreach my $F (keys %normalized_input) {
-        if ($normalized_reject{$F} or is_excluded($F, \%normalized_exclude)) {
-            my $orig_F = $normalized_input{$F};
-            $rh_ignored->{$orig_F} = "listed in exclusion file $opt_exclude_list_file";
-            print "Ignoring $orig_F because it appears in $opt_exclude_list_file\n" 
-                if $opt_v > 1;
-        }
-    }
-    print "<- process_exclude_list_file\n" if $opt_v > 2;
-} # 1}}}
-sub combine_results {                        # {{{1
-    # returns 1 if the inputs are categorized by language
-    #         0 if no identifiable language was found
-    my ($ra_report_files, # in
-        $report_type    , # in  "by language" or "by report file"
-        $rhh_count      , # out count{TYPE}{nFiles|code|blank|comment|scaled}
-        $rhaa_Filters_by_Language , # in
-       ) = @_;
-
-    print "-> combine_results(report_type=$report_type)\n" if $opt_v > 2;
-    my $found_language = 0;
-
-    foreach my $file (@{$ra_report_files}) {
-        my $IN = new IO::File $file, "r";
-        if (!defined $IN) {
-            warn "Unable to read $file; ignoring.\n";
-            next;
-        }
-        while (<$IN>) {
-            next if /^(http|Language|SUM|-----)/;
-            if (!$opt_by_file  and
-                m{^(.*?)\s+         # language
-                   (\d+)\s+         # files
-                   (\d+)\s+         # blank
-                   (\d+)\s+         # comments
-                   (\d+)\s+         # code
-                   (                #    next four entries missing with -nno3
-                   x\s+             # x
-                   \d+\.\d+\s+      # scale
-                   =\s+             # =
-                   (\d+\.\d+)\s*    # scaled code
-                   )?
-                   $}x) {
-                if ($report_type eq "by language") {
-                    next unless defined @{$rhaa_Filters_by_Language->{$1}};
-                    # above test necessary to avoid trying to sum reports
-                    # of reports (which have no language breakdown).
-                    $found_language = 1;
-                    $rhh_count->{$1   }{'nFiles' } += $2;
-                    $rhh_count->{$1   }{'blank'  } += $3;
-                    $rhh_count->{$1   }{'comment'} += $4;
-                    $rhh_count->{$1   }{'code'   } += $5;
-                    $rhh_count->{$1   }{'scaled' } += $7 if $opt_3;
-                } else {
-                    $rhh_count->{$file}{'nFiles' } += $2;
-                    $rhh_count->{$file}{'blank'  } += $3;
-                    $rhh_count->{$file}{'comment'} += $4;
-                    $rhh_count->{$file}{'code'   } += $5;
-                    $rhh_count->{$file}{'scaled' } += $7 if $opt_3;
-                }
-            } elsif ($opt_by_file  and
-                m{^(.*?)\s+         # language
-                   (\d+)\s+         # blank
-                   (\d+)\s+         # comments
-                   (\d+)\s+         # code
-                   (                #    next four entries missing with -nno3
-                   x\s+             # x
-                   \d+\.\d+\s+      # scale
-                   =\s+             # =
-                   (\d+\.\d+)\s*    # scaled code
-                   )?
-                   $}x) {
-                if ($report_type eq "by language") {
-                    next unless %{$rhaa_Filters_by_Language->{$1}};
-                    # above test necessary to avoid trying to sum reports
-                    # of reports (which have no language breakdown).
-                    $found_language = 1;
-                    $rhh_count->{$1   }{'nFiles' } +=  1;
-                    $rhh_count->{$1   }{'blank'  } += $2;
-                    $rhh_count->{$1   }{'comment'} += $3;
-                    $rhh_count->{$1   }{'code'   } += $4;
-                    $rhh_count->{$1   }{'scaled' } += $6 if $opt_3;
-                } else {
-                    $rhh_count->{$file}{'nFiles' } +=  1;
-                    $rhh_count->{$file}{'blank'  } += $2;
-                    $rhh_count->{$file}{'comment'} += $3;
-                    $rhh_count->{$file}{'code'   } += $4;
-                    $rhh_count->{$file}{'scaled' } += $6 if $opt_3;
-                }
-            }
-        }
-    }
-    print "<- combine_results\n" if $opt_v > 2;
-    return $found_language;
-
-} # 1}}}
-sub diff_report     {                        # {{{1
-    # returns an array of lines containing the results
-    print "-> diff_report\n" if $opt_v > 2;
-
-    if ($opt_xml or $opt_yaml) {
-        print "<- diff_report\n" if $opt_v > 2;
-        return diff_xml_yaml_report(@_) 
-    } elsif ($opt_csv) {
-        print "<- diff_report\n" if $opt_v > 2;
-        return diff_csv_report(@_) 
-    }
-
-    my ($version    , # in
-        $elapsed_sec, # in
-        $report_type, # in  "by language" | "by report file" | "by file"
-        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}
-        $rh_scale   , # in
-       ) = @_;
-
-#print "diff_report: ", Dumper($rhhh_count), "\n";
-    my @results       = ();
-
-    my $languages     = ();
-    my %sum           = (); # sum{nFiles|blank|comment|code}{same|modified|added|removed}
-    my $max_len       = 0;
-    foreach my $language (keys %{$rhhh_count}) {
-        foreach my $V (qw(nFiles blank comment code)) {
-            foreach my $S (qw(added same modified removed)) {
-                $rhhh_count->{$language}{$V}{$S} = 0 unless
-                    defined $rhhh_count->{$language}{$V}{$S};
-                $sum{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};
-            }
-        }
-        $max_len      = length($language) if length($language) > $max_len;
-    }
-    my $column_1_offset = 0;
-       $column_1_offset = $max_len - 17 if $max_len > 17;
-    $elapsed_sec = 0.5 unless $elapsed_sec;
-
-    my $spacing_0 = 23;
-    my $spacing_1 = 13;
-    my $spacing_2 =  9;
-    my $spacing_3 = 17;
-    if (!$opt_3) {
-        $spacing_1 = 19;
-        $spacing_2 = 14;
-        $spacing_3 = 28;
-    }
-    $spacing_0 += $column_1_offset;
-    $spacing_1 += $column_1_offset;
-    $spacing_3 += $column_1_offset;
-    my %Format = (
-        '1' => { 'xml' => 'name="%s" ',
-                 'txt' => "\%-${spacing_0}s ",
-               },
-        '2' => { 'xml' => 'name="%s" ',
-                 'txt' => "\%-${spacing_3}s ",
-               },
-        '3' => { 'xml' => 'files_count="%d" ',
-                 'txt' => '%5d ',
-               },
-        '4' => { 'xml' => 'blank="%d" comment="%d" code="%d" ',
-                 'txt' => "\%${spacing_2}d \%${spacing_2}d \%${spacing_2}d",
-               },
-        '5' => { 'xml' => 'factor="%.2f" scaled="%.2f" ',
-                 'txt' => ' x %6.2f = %14.2f',
-               },
-    );
-    my $Style = "txt";
-       $Style = "xml" if $opt_xml ;
-       $Style = "xml" if $opt_yaml;  # not a typo; just set to anything but txt
-       $Style = "xml" if $opt_csv ;  # not a typo; just set to anything but txt
-
-    my $hyphen_line = sprintf "%s", '-' x (79 + $column_1_offset);
-       $hyphen_line = sprintf "%s", '-' x (68 + $column_1_offset) 
-            if (!$opt_3) and (68 + $column_1_offset) > 79;
-    my $data_line  = "";
-    my $first_column;
-    my $BY_LANGUAGE = 0;
-    my $BY_FILE     = 0;
-    if      ($report_type eq "by language") {
-        $first_column = "Language";
-        $BY_LANGUAGE  = 1;
-    } elsif ($report_type eq "by file")     {
-        $first_column = "File";
-        $BY_FILE      = 1;
-    } else {
-        $first_column = "Report File";
-    }
-
-    my $header_line  = sprintf "%s v %4.2f", $URL, $version;
-    my $sum_files    = 1;
-    my $sum_lines    = 1;
-       $header_line .= sprintf("  T=%.1f s (%.1f files/s, %.1f lines/s)",
-                        $elapsed_sec           ,
-                        $sum_files/$elapsed_sec,
-                        $sum_lines/$elapsed_sec) unless $opt_sum_reports;
-    if ($Style eq "txt") {
-        push @results, output_header($header_line, $hyphen_line, $BY_FILE);
-    } elsif ($Style eq "csv") {
-        die "csv";
-    }
-
-    # column headers
-    if (!$opt_3 and $BY_FILE) {
-        my $spacing_n = $spacing_1 - 11;
-        $data_line  = sprintf "%-${spacing_n}s" , $first_column;
-    } else {
-        $data_line  = sprintf "%-${spacing_1}s ", $first_column;
-    }
-    if ($BY_FILE) {
-        $data_line .= sprintf "%${spacing_2}s"   , ""     ;
-    } else {
-        $data_line .= sprintf "%${spacing_2}s "  , "files";
-    }
-    $data_line .= sprintf "%${spacing_2}s %${spacing_2}s %${spacing_2}s",
-        "blank"         ,
-        "comment"       ,
-        "code";
-
-    if ($Style eq "txt") {
-        push @results, $data_line;
-        push @results, $hyphen_line;
-    }
-
-    foreach my $lang_or_file (sort {
-                                 $rhhh_count->{$b}{'code'} <=>
-                                 $rhhh_count->{$a}{'code'}
-                               }
-                          keys %{$rhhh_count}) {
-
-        push @results, "$lang_or_file";
-        foreach my $S (qw(same modified added removed)) {
-            my $indent = $spacing_1 - 2;
-            my $line .= sprintf " %-${indent}s", $S;
-            if ($BY_FILE) {
-                $line .= sprintf "   ";
-            } else {
-                $line .= sprintf "  %${spacing_2}s", $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
-            }
-            $line .= sprintf " %${spacing_2}s %${spacing_2}s %${spacing_2}s",
-                $rhhh_count->{$lang_or_file}{'blank'}{$S}   ,
-                $rhhh_count->{$lang_or_file}{'comment'}{$S} ,
-                $rhhh_count->{$lang_or_file}{'code'}{$S}    ;
-            push @results, $line;
-        }
-    }
-    push @results, "-" x 79;
-    push @results, "SUM:";
-    foreach my $S (qw(same modified added removed)) {
-        my $indent = $spacing_1 - 2;
-        my $line .= sprintf " %-${indent}s", $S;
-            if ($BY_FILE) {
-                $line .= sprintf "   ";
-            } else {
-                $line .= sprintf "  %${spacing_2}s", $sum{'nFiles'}{$S};
-            }
-        $line .= sprintf " %${spacing_2}s %${spacing_2}s %${spacing_2}s",
-            $sum{'blank'}{$S}   ,
-            $sum{'comment'}{$S} ,
-            $sum{'code'}{$S}    ;
-        push @results, $line;
-    }
-    push @results, "-" x 79;
-    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;
-    print "<- diff_report\n" if $opt_v > 2;
-
-    return @results;
-} # 1}}}
-sub xml_or_yaml_header {                     # {{{1
-    my ($URL, $version, $elapsed_sec, $sum_files, $sum_lines) = @_;
-    my $header      = "";
-    my $file_rate   = $sum_files/$elapsed_sec;
-    my $line_rate   = $sum_lines/$elapsed_sec;
-    my $type        = ""; 
-       $type        = "diff_" if $opt_diff;
-    my $report_file = "";
-       $report_file = "  <report_file>$opt_report_file</report_file>"
-       if $opt_report_file;
-    if ($opt_xml) {
-        $header = "<?xml version=\"1.0\"?>";
-        $header .= "\n<?xml-stylesheet type=\"text/xsl\" href=\"" . $opt_xsl . "\"?>" if $opt_xsl;
-        $header .= "<${type}results>
-<header>
-  <cloc_url>$URL</cloc_url>
-  <cloc_version>$version</cloc_version>
-  <elapsed_seconds>$elapsed_sec</elapsed_seconds>
-  <n_files>$sum_files</n_files>
-  <n_lines>$sum_lines</n_lines>
-  <files_per_second>$file_rate</files_per_second>
-  <lines_per_second>$line_rate</lines_per_second>";
-        $header .= "\n$report_file"
-            if $opt_report_file;
-        $header .= "\n</header>";
-    } elsif ($opt_yaml) {
-        $header = "---\n# $URL
-header :
-  cloc_url           : http://cloc.sourceforge.net
-  cloc_version       : $version
-  elapsed_seconds    : $elapsed_sec
-  n_files            : $sum_files
-  n_lines            : $sum_lines
-  files_per_second   : $file_rate
-  lines_per_second   : $line_rate";
-        $header .= "\n  report_file        : $opt_report_file"
-            if $opt_report_file;
-    }
-    return $header;
-} # 1}}}
-sub diff_xml_yaml_report {                   # {{{1
-    # returns an array of lines containing the results
-    my ($version    , # in
-        $elapsed_sec, # in
-        $report_type, # in  "by language" | "by report file" | "by file"
-        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}
-        $rh_scale   , # in
-       ) = @_;
-    print "-> diff_xml_yaml_report\n" if $opt_v > 2;
-
-#print "diff_report: ", Dumper($rhhh_count), "\n";
-    my @results       = ();
-    
-    my $languages     = ();
-    my %sum           = (); # sum{nFiles|blank|comment|code}{same|modified|added|removed}
-
-    my $sum_files = 0;
-    my $sum_lines = 0;
-    foreach my $language (keys %{$rhhh_count}) {
-        foreach my $V (qw(nFiles blank comment code)) {
-            foreach my $S (qw(added same modified removed)) {
-                $rhhh_count->{$language}{$V}{$S} = 0 unless
-                    defined $rhhh_count->{$language}{$V}{$S};
-                $sum{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};
-                if ($V eq "nFiles") {
-                    $sum_files += $rhhh_count->{$language}{$V}{$S};
-                } else {
-                    $sum_lines += $rhhh_count->{$language}{$V}{$S};
-                }
-            }
-        }
-    }
-    $elapsed_sec = 0.5 unless $elapsed_sec;
-
-    my $data_line   = "";
-    my $BY_LANGUAGE = 0;
-    my $BY_FILE     = 0;
-    if      ($report_type eq "by language") {
-        $BY_LANGUAGE  = 1;
-    } elsif ($report_type eq "by file")     {
-        $BY_FILE      = 1;
-    }
-
-    if (!$ALREADY_SHOWED_HEADER) {
-        push @results,
-              xml_or_yaml_header($URL, $version, $elapsed_sec, 
-                                 $sum_files, $sum_lines);
-        $ALREADY_SHOWED_HEADER = 1;
-    }
-
-    foreach my $S (qw(same modified added removed)) {
-        if ($opt_xml) {
-            push @results, "  <$S>";
-        } elsif ($opt_yaml) {
-            push @results, "$S :";
-        }
-        foreach my $lang_or_file (sort {
-                                     $rhhh_count->{$b}{'code'} <=>
-                                     $rhhh_count->{$a}{'code'}
-                                   }
-                              keys %{$rhhh_count}) {
-            my $L = "";
-            if ($opt_xml) {
-                if ($BY_FILE) {
-                    $L .= sprintf "    <file name=\"%s\" files_count=\"1\" ", 
-                            $lang_or_file;
-                } else {
-                    $L .= sprintf "    <language name=\"%s\" files_count=\"%d\" ",
-                            $lang_or_file ,
-                            $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
-                }
-                foreach my $T (qw(blank comment code)) {
-                    $L .= sprintf "%s=\"%d\" ", 
-                            $T, $rhhh_count->{$lang_or_file}{$T}{$S};
-                }
-                push @results, $L . "/>";
-            } elsif ($opt_yaml) {
-                if ($BY_FILE) {
-                    push @results, sprintf "  - file : %s", $lang_or_file;
-                    push @results, sprintf "    files_count : 1", 
-                } else {
-                    push @results, sprintf "  - language : %s", $lang_or_file;
-                    push @results, sprintf "    files_count : %d", 
-                            $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
-                }
-                foreach my $T (qw(blank comment code)) {
-                    push @results, sprintf "    %s : %d", 
-                            $T, $rhhh_count->{$lang_or_file}{$T}{$S};
-                }
-            }
-        }
-
-        if ($opt_xml) {
-            my $L = sprintf "    <total sum_files=\"%d\" ", $sum{'nFiles'}{$S};
-            foreach my $V (qw(blank comment code)) {
-                $L .= sprintf "%s=\"%d\" ", $V, $sum{$V}{$S};
-            }
-            push @results, $L . "/>";
-            push @results, "  </$S>";
-        } elsif ($opt_yaml) {
-            push @results, sprintf "%s_total :\n    sum_files : %d", 
-                                $S, $sum{'nFiles'}{$S};
-            foreach my $V (qw(blank comment code)) {
-                push @results, sprintf "    %s : %d", $V, $sum{$V}{$S};
-            }
-        }
-    }
-
-    if ($opt_xml) {
-        push @results, "</diff_results>";
-    }
-    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;
-    print "<- diff_xml_yaml_report\n" if $opt_v > 2;
-    return @results;
-} # 1}}}
-sub diff_csv_report {                        # {{{1
-    # returns an array of lines containing the results
-    my ($version    , # in
-        $elapsed_sec, # in
-        $report_type, # in  "by language" | "by report file" | "by file"
-        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}
-        $rh_scale   , # in  unused
-       ) = @_;
-    print "-> diff_csv_report\n" if $opt_v > 2;
-
-#use Data::Dumper;
-#print "diff_csv_report: ", Dumper($rhhh_count), "\n";
-#die;
-    my @results       = ();
-    my $languages     = ();
-
-    my $data_line   = "";
-    my $BY_LANGUAGE = 0;
-    my $BY_FILE     = 0;
-    if      ($report_type eq "by language") {
-        $BY_LANGUAGE  = 1;
-    } elsif ($report_type eq "by file")     {
-        $BY_FILE      = 1;
-    }
-
-    $elapsed_sec = 0.5 unless $elapsed_sec;
-
-    my $line = "Language, ";
-       $line = "File, " if $BY_FILE;
-    foreach my $item (qw(files blank comment code)) {
-        next if $BY_FILE and $item eq 'files';
-        foreach my $symbol qw( == != + - ) {
-            $line .= "$symbol $item, ";
-        }
-    }
-    $line .= "\"$URL v $version T=$elapsed_sec s\"";
-    push @results, $line;
-
-    foreach my $lang_or_file (sort {
-                                 $rhhh_count->{$b}{'code'} <=>
-                                 $rhhh_count->{$a}{'code'}
-                               }
-                          keys %{$rhhh_count}) {
-        $line = "$lang_or_file, ";
-        foreach my $item (qw(nFiles blank comment code)) {
-            next if $BY_FILE and $item eq 'nFiles';
-            foreach my $symbol (qw(same modified added removed)) {
-                if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {
-                    $line .= "$rhhh_count->{$lang_or_file}{$item}{$symbol}, ";
-                } else {
-                    $line .= "0, ";
-                }
-            }
-        }
-        push @results, $line;
-    }
-
-    print "<- diff_csv_report\n" if $opt_v > 2;
-    return @results;
-} # 1}}}
-sub generate_sql    {                        # {{{1
-    my ($elapsed_sec, # in
-        $rhh_count  , # in  count{TYPE}{lang|code|blank|comment|scaled}
-        $rh_scale   , # in
-       ) = @_;
-    print "-> generate_sql\n" if $opt_v > 2;
-
-    $opt_sql_project = cwd() unless defined $opt_sql_project;
-    $opt_sql_project =~ s{/}{\\}g if $ON_WINDOWS;
-
-    my $schema = "
-create table metadata (          -- $URL v $VERSION
-                timestamp text,    
-                Project   text,    
-                elapsed_s real);   
-create table t        (
-                Project   text   ,  
-                Language  text   ,  
-                File      text   ,  
-                nBlank    integer,  
-                nComment  integer,  
-                nCode     integer,  
-                nScaled   real   ); 
-";
-    $opt_sql = "-" if $opt_sql eq "1";
-
-    my $open_mode = ">";
-       $open_mode = ">>" if $opt_sql_append;
-
-    my $fh = new IO::File; # $opt_sql, "w";
-    if (!$fh->open("${open_mode}${opt_sql}")) {
-        die "Unable to write to $opt_sql  $!\n";
-    }
-    print $fh $schema unless defined $opt_sql_append;
-
-    print $fh "begin transaction;\n";
-    printf $fh "insert into metadata values('%s', '%s', %f);\n",
-                strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
-                $opt_sql_project, $elapsed_sec;
-
-    my $nIns = 0;
-    foreach my $file (keys %{$rhh_count}) {
-        my $language = $rhh_count->{$file}{'lang'};
-        my $clean_filename = $file;
-        # If necessary (that is, if the input contained an
-        # archive file [.tar.gz, etc]), strip the temporary
-        # directory name which was used to expand the archive
-        # from the file name.
-        foreach my $temp_d (keys %TEMP_DIR) {
-            if ($ON_WINDOWS) {
-            # \ -> / necessary to allow the next if test's
-            # m{} to work in the presence of spaces in file names
-                $temp_d         =~ s{\\}{/}g;
-                $clean_filename =~ s{\\}{/}g;
-            }
-            if ($clean_filename =~ m{^$temp_d/}) {
-                $clean_filename =~ s{^$temp_d/}{};
-                last;
-            }
-        }
-        $clean_filename =~ s{/}{\\}g if $ON_WINDOWS; # then go back from / to \
-        printf $fh "insert into t values('%s', '%s', '%s', %d, %d, %d, %f);\n",
-                    $opt_sql_project           ,
-                    $language                  ,
-                    $clean_filename            ,
-                    $rhh_count->{$file}{'blank'},
-                    $rhh_count->{$file}{'comment'},
-                    $rhh_count->{$file}{'code'}   ,
-                    $rhh_count->{$file}{'code'}*$rh_scale->{$language};
-        ++$nIns;
-        if (!($nIns % 10_000)) {
-            print $fh "commit;\n";
-            print $fh "begin transaction;\n";
-        }
-    }
-    print $fh "commit;\n";
-
-    $fh->close unless $opt_sql eq "-"; # don't try to close STDOUT
-    print "<- generate_sql\n" if $opt_v > 2;
-
-    # sample query:
-    #
-    #   select project, language, 
-    #          sum(nCode)     as Code, 
-    #          sum(nComment)  as Comments, 
-    #          sum(nBlank)    as Blank,  
-    #          sum(nCode)+sum(nComment)+sum(nBlank) as All_Lines,
-    #          100.0*sum(nComment)/(sum(nCode)+sum(nComment)) as Comment_Pct
-    #          from t group by Project, Language order by Project, Code desc;
-    #
-} # 1}}}
-sub output_header   {                        # {{{1
-    my ($header_line, 
-        $hyphen_line,
-        $BY_FILE    ,)    = @_;
-    print "-> output_header\n" if $opt_v > 2;
-    my @R = ();
-    if      ($opt_xml) {
-        if (!$ALREADY_SHOWED_XML_SECTION) {
-            push @R, "<?xml version=\"1.0\"?>";
-            push @R, '<?xml-stylesheet type="text/xsl" href="' .
-                            $opt_xsl . '"?>' if $opt_xsl;
-            push @R, "<results>";
-            push @R, "<header>$header_line</header>";
-            $ALREADY_SHOWED_XML_SECTION = 1;
-        }
-        if ($BY_FILE) {
-            push @R, "<files>";
-        } else {
-            push @R, "<languages>";
-        }
-    } elsif ($opt_yaml) {
-        push @R, "---\n# $header_line";
-    } elsif ($opt_csv) {
-        # append the header to the end of the column headers
-        # to keep the output a bit cleaner from a spreadsheet
-        # perspective
-    } else {
-        if ($ALREADY_SHOWED_HEADER) {
-            push @R, "";
-        } else {
-            push @R, $header_line;
-            $ALREADY_SHOWED_HEADER = 1;
-        }
-        push @R, $hyphen_line;
-    }
-    print "<- output_header\n" if $opt_v > 2;
-    return @R;
-} # 1}}}
-sub generate_report {                        # {{{1
-    # returns an array of lines containing the results
-    my ($version    , # in
-        $elapsed_sec, # in
-        $report_type, # in  "by language" | "by report file" | "by file"
-        $rhh_count  , # in  count{TYPE}{nFiles|code|blank|comment|scaled}
-        $rh_scale   , # in
-       ) = @_;
-
-    print "-> generate_report\n" if $opt_v > 2;
-    my @results       = ();
-    
-    my $languages     = ();
-
-    my $sum_files     = 0;
-    my $sum_code      = 0;
-    my $sum_blank     = 0;
-    my $sum_comment   = 0;
-    my $max_len       = 0;
-    foreach my $language (keys %{$rhh_count}) {
-        $sum_files   += $rhh_count->{$language}{'nFiles'} ;
-        $sum_blank   += $rhh_count->{$language}{'blank'}  ;
-        $sum_comment += $rhh_count->{$language}{'comment'};
-        $sum_code    += $rhh_count->{$language}{'code'}   ;
-        $max_len      = length($language) if length($language) > $max_len;
-    }
-    my $column_1_offset = 0;
-       $column_1_offset = $max_len - 17 if $max_len > 17;
-    my $sum_lines = $sum_blank + $sum_comment + $sum_code;
-    $elapsed_sec = 0.5 unless $elapsed_sec;
-
-    my $spacing_0 = 23;
-    my $spacing_1 = 13;
-    my $spacing_2 =  9;
-    my $spacing_3 = 17;
-    if (!$opt_3) {
-        $spacing_1 = 19;
-        $spacing_2 = 14;
-        $spacing_3 = 28;
-    }
-    $spacing_0 += $column_1_offset;
-    $spacing_1 += $column_1_offset;
-    $spacing_3 += $column_1_offset;
-    my %Format = (
-        '1' => { 'xml' => 'name="%s" ',
-                 'txt' => "\%-${spacing_0}s ",
-               },
-        '2' => { 'xml' => 'name="%s" ',
-                 'txt' => "\%-${spacing_3}s ",
-               },
-        '3' => { 'xml' => 'files_count="%d" ',
-                 'txt' => '%5d ',
-               },
-        '4' => { 'xml' => 'blank="%d" comment="%d" code="%d" ',
-                 'txt' => "\%${spacing_2}d \%${spacing_2}d \%${spacing_2}d",
-               },
-        '5' => { 'xml' => 'factor="%.2f" scaled="%.2f" ',
-                 'txt' => ' x %6.2f = %14.2f',
-               },
-    );
-    my $Style = "txt";
-       $Style = "xml" if $opt_xml ;
-       $Style = "xml" if $opt_yaml;  # not a typo; just set to anything but txt
-       $Style = "xml" if $opt_csv ;  # not a typo; just set to anything but txt
-
-    my $hyphen_line = sprintf "%s", '-' x (79 + $column_1_offset);
-       $hyphen_line = sprintf "%s", '-' x (68 + $column_1_offset) 
-            if (!$opt_3) and (68 + $column_1_offset) > 79;
-    my $data_line  = "";
-    my $first_column;
-    my $BY_LANGUAGE = 0;
-    my $BY_FILE     = 0;
-    if      ($report_type eq "by language") {
-        $first_column = "Language";
-        $BY_LANGUAGE  = 1;
-    } elsif ($report_type eq "by file")     {
-        $first_column = "File";
-        $BY_FILE      = 1;
-    } else {
-        $first_column = "Report File";
-    }
-
-    my $header_line  = sprintf "%s v %4.2f", $URL, $version;
-       $header_line .= sprintf("  T=%.1f s (%.1f files/s, %.1f lines/s)",
-                        $elapsed_sec           ,
-                        $sum_files/$elapsed_sec,
-                        $sum_lines/$elapsed_sec) unless $opt_sum_reports;
-    if ($opt_xml or $opt_yaml) {
-        if (!$ALREADY_SHOWED_HEADER) {
-            push @results, xml_or_yaml_header($URL, $version, $elapsed_sec, 
-                                              $sum_files, $sum_lines);
-            $ALREADY_SHOWED_HEADER = 1;
-        }
-        if ($BY_FILE) {
-            push @results, "<files>";
-        } else {
-            push @results, "<languages>";
-        }
-    } else {
-        push @results, output_header($header_line, $hyphen_line, $BY_FILE);
-    }
-
-    if ($Style eq "txt") {
-        # column headers
-        if (!$opt_3 and $BY_FILE) {
-            my $spacing_n = $spacing_1 - 11;
-            $data_line  = sprintf "%-${spacing_n}s ", $first_column;
-        } else {
-            $data_line  = sprintf "%-${spacing_1}s ", $first_column;
-        }
-        if ($BY_FILE) {
-            $data_line .= sprintf "%${spacing_2}s "  , " "    ;
-        } else {
-            $data_line .= sprintf "%${spacing_2}s "  , "files";
-        }
-        $data_line .= sprintf "%${spacing_2}s %${spacing_2}s %${spacing_2}s",
-            "blank"         ,
-            "comment"       ,
-            "code";
-        $data_line .= sprintf " %8s   %14s",
-            "scale"         ,
-            "3rd gen. equiv"
-              if $opt_3;
-        push @results, $data_line;
-        push @results, $hyphen_line;
-    }
-    if ($opt_csv) {
-        my $header2;
-        if ($BY_FILE) {
-            $header2 = "language,filename";
-        } else {
-            $header2 = "files,language";
-        }
-        $header2 .= ",blank,comment,code";
-        $header2 .= ",scale,3rd gen. equiv" if $opt_3;
-        $header2 .= ',"' . $header_line . '"';
-        push @results, $header2;
-    }
-
-    my $sum_scaled = 0;
-    foreach my $lang_or_file (sort {
-                                 $rhh_count->{$b}{'code'} <=>
-                                 $rhh_count->{$a}{'code'}
-                               }
-                          keys %{$rhh_count}) {
-        my ($factor, $scaled);
-        if ($BY_LANGUAGE or $BY_FILE) {
-            $factor = 1;
-            if ($BY_LANGUAGE) {
-                if (defined $rh_scale->{$lang_or_file}) {
-                    $factor = $rh_scale->{$lang_or_file};
-                } else {
-                    warn "No scale factor for $lang_or_file; using 1.00";
-                }
-            } else { # by individual code file
-                $factor = $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};
-            }
-            $scaled = $factor*$rhh_count->{$lang_or_file}{'code'};
-        } else {
-            if (!defined $rhh_count->{$lang_or_file}{'scaled'}) {
-                $opt_3 = 0;
-                # If we're summing together files previously generated
-                # with --no3 then rhh_count->{$lang_or_file}{'scaled'}
-                # this variable will be undefined.  That should only
-                # happen when summing together by file however.
-            } elsif ($BY_LANGUAGE) {
-                warn "Missing scaled language info for $lang_or_file\n";
-            }
-            if ($opt_3) {
-                $scaled =         $rhh_count->{$lang_or_file}{'scaled'};
-                $factor = $scaled/$rhh_count->{$lang_or_file}{'code'};
-            }
-        }
-
-        if ($BY_FILE) {
-            $data_line  = sprintf $Format{'1'}{$Style}, $lang_or_file;
-        } else {
-            $data_line  = sprintf $Format{'2'}{$Style}, $lang_or_file;
-        }
-        $data_line .= sprintf $Format{3}{$Style}  , 
-                        $rhh_count->{$lang_or_file}{'nFiles'} unless $BY_FILE;
-        $data_line .= sprintf $Format{4}{$Style}  , 
-            $rhh_count->{$lang_or_file}{'blank'}  ,
-            $rhh_count->{$lang_or_file}{'comment'},
-            $rhh_count->{$lang_or_file}{'code'}   ;
-        $data_line .= sprintf $Format{5}{$Style}  ,
-            $factor                               ,
-            $scaled if $opt_3;
-        $sum_scaled  += $scaled if $opt_3;
-
-        if ($opt_xml) {
-            if (defined $rhh_count->{$lang_or_file}{'lang'}) {
-                my $lang = $rhh_count->{$lang_or_file}{'lang'};
-                if (!defined $languages->{$lang}) {
-                    $languages->{$lang} = $lang;
-                }
-                $data_line.=' language="' . $lang . '" ';
-            }
-            if ($BY_FILE) {
-                push @results, "  <file " . $data_line . "/>";
-            } else {
-                push @results, "  <language " . $data_line . "/>";
-            }
-        } elsif ($opt_yaml) {
-            push @results,$lang_or_file . ":";
-            push @results,"  nFiles: "  .$rhh_count->{$lang_or_file}{'nFiles'} 
-                unless $BY_FILE;
-            push @results,"  blank: "   .$rhh_count->{$lang_or_file}{'blank'}  ;
-            push @results,"  comment: " .$rhh_count->{$lang_or_file}{'comment'};
-            push @results,"  code: "    .$rhh_count->{$lang_or_file}{'code'}   ;
-            push @results,"  language: ".$rhh_count->{$lang_or_file}{'lang'} 
-                if $BY_FILE;
-            if ($opt_3) {
-                push @results, "  scaled: " . $scaled;
-                push @results, "  factor: " . $factor;
-            }
-        } elsif ($opt_csv) {
-            my $extra_3 = "";
-               $extra_3 = ",$factor,$scaled" if $opt_3;
-            my $str;
-            if ($BY_FILE) {
-                $str = $rhh_count->{$lang_or_file}{'lang'}   . ",";
-            } else {
-                $str = $rhh_count->{$lang_or_file}{'nFiles'} . ",";
-            }
-            $str .= $lang_or_file                         . "," .
-                    $rhh_count->{$lang_or_file}{'blank'}  . "," .
-                    $rhh_count->{$lang_or_file}{'comment'}. "," .
-                    $rhh_count->{$lang_or_file}{'code'}         .
-                    $extra_3;
-            push @results, $str;
-        } else {
-            push @results, $data_line;
-        }
-    }
-
-    my $avg_scale = 1;  # weighted average of scale factors
-       $avg_scale = sprintf("%.2f", $sum_scaled / $sum_code) 
-            if $sum_code and $opt_3;
-
-    if ($opt_xml) {
-        $data_line = "";
-        if (!$BY_FILE) {
-            $data_line .= sprintf "sum_files=\"%d\" ", $sum_files;
-        }
-        $data_line .= sprintf $Format{'4'}{$Style},
-            $sum_blank   ,
-            $sum_comment ,
-            $sum_code    ;
-        $data_line .= sprintf $Format{'5'}{$Style},
-            $avg_scale   ,
-            $sum_scaled  if $opt_3;
-        push @results, "  <total " . $data_line . "/>";
-
-        if ($BY_FILE) {
-            push @results, "</files>";
-        } else {
-            foreach my $language (keys %{$languages}) {
-                push @results, '  <language name="' . $language . '"/>';
-            }
-            push @results, "</languages>";
-        }
-
-        if (!$opt_by_file_by_lang or $ALREADY_SHOWED_XML_SECTION) {
-    	    push @results, "</results>";
-        } else {
-            $ALREADY_SHOWED_XML_SECTION = 1;
-        }
-    } elsif ($opt_yaml) {
-        push @results, "SUM:";
-        push @results, "  blank: "  . $sum_blank  ;
-        push @results, "  code: "   . $sum_code   ;
-        push @results, "  comment: ". $sum_comment;
-        push @results, "  nFiles: " . $sum_files  ;
-        if ($opt_3) {
-            push @results, "  scaled: " . $sum_scaled;
-            push @results, "  factor: " . $avg_scale ;
-        }
-    } elsif ($opt_csv) {
-        # do nothing
-    } else {
-
-        if ($BY_FILE) {
-            $data_line  = sprintf "%-${spacing_0}s ", "SUM:"  ;
-        } else {
-            $data_line  = sprintf "%-${spacing_1}s ", "SUM:"  ;
-            $data_line .= sprintf "%${spacing_2}d ", $sum_files;
-        }
-        $data_line .= sprintf $Format{'4'}{$Style},
-            $sum_blank   ,
-            $sum_comment ,
-            $sum_code    ;
-        $data_line .= sprintf $Format{'5'}{$Style},
-            $avg_scale   ,
-            $sum_scaled if $opt_3;
-        push @results, $hyphen_line if $sum_files > 1 or $opt_sum_one;
-        push @results, $data_line   if $sum_files > 1 or $opt_sum_one;
-        push @results, $hyphen_line;
-    }
-    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;
-    print "<- generate_report\n" if $opt_v > 2;
-    return @results;
-} # 1}}}
-sub print_errors {                           # {{{1
-    my ($rh_Error_Codes, # in
-        $raa_errors    , # in
-       ) = @_;
-
-    print "-> print_errors\n" if $opt_v > 2;
-    my %error_string = reverse(%{$rh_Error_Codes});
-    my $nErrors      = scalar @{$raa_errors};
-    warn sprintf "\n%d error%s:\n", plural_form(scalar @Errors);
-    for (my $i = 0; $i < $nErrors; $i++) {
-        warn sprintf "%s:  %s\n", 
-                     $error_string{ $raa_errors->[$i][0] },
-                     $raa_errors->[$i][1] ;
-    }
-    print "<- print_errors\n" if $opt_v > 2;
-
-} # 1}}}
-sub write_lang_def {                         # {{{1
-    my ($file                     ,
-        $rh_Language_by_Extension , # in
-        $rh_Language_by_Script    , # in
-        $rh_Language_by_File      , # in
-        $rhaa_Filters_by_Language , # in
-        $rh_Not_Code_Extension    , # in
-        $rh_Not_Code_Filename     , # in
-        $rh_Scale_Factor          , # in
-        $rh_EOL_Continuation_re   , # in
-       ) = @_;
-
-    print "-> write_lang_def($file)\n" if $opt_v > 2;
-    my $OUT = new IO::File $file, "w";
-    die "Unable to write to $file\n" unless defined $OUT;
-
-    foreach my $language (sort keys %{$rhaa_Filters_by_Language}) {
-        next if $language eq "MATLAB/Objective C/MUMPS" or
-                $language eq "PHP/Pascal";
-        printf $OUT "%s\n", $language;
-        foreach my $filter (@{$rhaa_Filters_by_Language->{$language}}) {
-            printf $OUT "    filter %s", $filter->[0];
-            printf $OUT " %s", $filter->[1] if defined $filter->[1];
-            print  $OUT "\n";
-        }
-        foreach my $ext (sort keys %{$rh_Language_by_Extension}) {
-            if ($language eq $rh_Language_by_Extension->{$ext}) {
-                printf $OUT "    extension %s\n", $ext;
-            }
-        }
-        foreach my $filename (sort keys %{$rh_Language_by_File}) {
-            if ($language eq $rh_Language_by_File->{$filename}) {
-                printf $OUT "    filename %s\n", $filename;
-            }
-        }
-        foreach my $script_exe (sort keys %{$rh_Language_by_Script}) {
-            if ($language eq $rh_Language_by_Script->{$script_exe}) {
-                printf $OUT "    script_exe %s\n", $script_exe;
-            }
-        }
-        printf $OUT "    3rd_gen_scale %.2f\n", $rh_Scale_Factor->{$language};
-        if (defined $rh_EOL_Continuation_re->{$language}) {
-            printf $OUT "    end_of_line_continuation %s\n", 
-                $rh_EOL_Continuation_re->{$language};
-        }
-    }
-
-    $OUT->close;
-    print "<- write_lang_def\n" if $opt_v > 2;
-} # 1}}}
-sub read_lang_def {                          # {{{1
-    my ($file                     ,
-        $rh_Language_by_Extension , # out
-        $rh_Language_by_Script    , # out
-        $rh_Language_by_File      , # out
-        $rhaa_Filters_by_Language , # out
-        $rh_Not_Code_Extension    , # out
-        $rh_Not_Code_Filename     , # out
-        $rh_Scale_Factor          , # out
-        $rh_EOL_Continuation_re   , # out
-        $rh_EOL_abc,
-       ) = @_;
-
-
-    print "-> read_lang_def($file)\n" if $opt_v > 2;
-    my $IN = new IO::File $file, "r";
-    die "Unable to read $file.\n" unless defined $IN;
-
-    my $language = "";
-    while (<$IN>) {
-        next if /^\s*#/ or /^\s*$/;
-
-        if (/^(\w+.*?)\s*$/) {
-            $language = $1;
-            next;
-        }
-        die "Missing computer language name, line $. of $file\n"
-            unless $language;
-
-        if      (/^    filter\s+(\w+)\s*$/) {
-            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]
-
-        } elsif (/^    filter\s+(\w+)\s+(.*?)\s*$/) {
-            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]
-
-        } elsif (/^    extension\s+(\S+)\s*$/) {
-            if (defined $rh_Language_by_Extension->{$1}) {
-                die "File extension collision:  $1 ",
-                    "maps to languages '$rh_Language_by_Extension->{$1}' ",
-                    "and '$language'\n" ,
-                    "Edit $file and remove $1 from one of these two ",
-                    "language definitions.\n";
-            }
-            $rh_Language_by_Extension->{$1} = $language;
-
-        } elsif (/^    filename\s+(\S+)\s*$/) {
-            $rh_Language_by_File->{$1} = $language;
-
-        } elsif (/^    script_exe\s+(\S+)\s*$/) {
-            $rh_Language_by_Script->{$1} = $language;
-
-        } elsif (/^    3rd_gen_scale\s+(\S+)\s*$/) {
-            $rh_Scale_Factor->{$language} = $1;
-
-        } elsif (/^    end_of_line_continuation\s+(\S+)\s*$/) {
-            $rh_EOL_Continuation_re->{$language} = $1;
-
-        } else {
-            die "Unexpected data line $. of $file:\n$_\n";
-        }
-
-    }
-    $IN->close;
-    print "<- read_lang_def\n" if $opt_v > 2;
-} # 1}}}
-sub print_extension_info {                   # {{{1
-    my ($extension,) = @_;
-    if ($extension) {  # show information on this extension
-        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
-            # Language_by_Extension{f}    = 'Fortran 77' 
-            printf "%-12s -> %s\n", $ext, $Language_by_Extension{$ext}
-                if $ext =~ m{$extension}i;
-        }
-    } else {           # show information on all  extensions
-        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
-            # Language_by_Extension{f}    = 'Fortran 77' 
-            printf "%-12s -> %s\n", $ext, $Language_by_Extension{$ext};
-        }
-    }
-} # 1}}}
-sub print_language_info {                    # {{{1
-    my ($language,) = @_;
-    my %extensions = (); # the subset matched by the given $language value
-    if ($language) {  # show information on this language
-        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
-            # Language_by_Extension{f}    = 'Fortran 77' 
-            push @{$extensions{$Language_by_Extension{$ext}} }, $ext
-                if $Language_by_Extension{$ext} =~ m{$language}i;
-        }
-    } else {          # show information on all  languages
-        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
-            # Language_by_Extension{f}    = 'Fortran 77' 
-            push @{$extensions{$Language_by_Extension{$ext}} }, $ext
-        }
-    }
-
-    # add exceptions (one file extension mapping to multiple languages)
-    if (!$language or 
-        $language =~ /^(Objective C|MATLAB|MUMPS)$/i) {
-        push @{$extensions{'Objective C'}}, "m";
-        push @{$extensions{'MATLAB'}}     , "m";
-        push @{$extensions{'MUMPS'}}      , "m";
-        delete $extensions{'MATLAB/Objective C/MUMPS'};
-    }
-
-    if (%extensions) {
-        foreach my $lang (sort {lc $a cmp lc $b } keys %extensions) {
-            printf "%-26s (%s)\n", $lang, join(", ", @{$extensions{$lang}});
-        }
-    }
-} # 1}}}
-sub make_file_list {                         # {{{1
-    my ($ra_arg_list,  # in   file and/or directory names to examine
-        $rh_Err     ,  # in   hash of error codes
-        $raa_errors ,  # out  errors encountered
-        $rh_ignored ,  # out  files not recognized as computer languages
-        ) = @_;
-    print "-> make_file_list(@{$ra_arg_list})\n" if $opt_v > 2;
-
-    my ($fh, $filename);
-    if ($opt_categorized) {
-        $filename = $opt_categorized;
-        $fh = new IO::File $filename, "+>";  # open for read/write
-        die "Unable to write to $filename:  $!\n" unless defined $fh;
-    } elsif ($opt_sdir) {
-        # write to the user-defined scratch directory
-        $filename = $opt_sdir . '/cloc_file_list.txt';
-        $fh = new IO::File $filename, "+>";  # open for read/write
-        die "Unable to write to $filename:  $!\n" unless defined $fh;
-    } else {
-        # let File::Temp create a suitable temporary file
-        ($fh, $filename) = tempfile(UNLINK => 1);  # delete file on exit
-        print "Using temp file list [$filename]\n" if $opt_v;
-    }
-
-    my @dir_list = ();
-    foreach my $file_or_dir (@{$ra_arg_list}) {
-#print "make_file_list file_or_dir=$file_or_dir\n";
-        my $size_in_bytes = 0;
-        if (!-r $file_or_dir) {
-            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file_or_dir];
-            next;
-        }
-        if (is_file($file_or_dir)) {
-            if (!(-s $file_or_dir)) {   # 0 sized file, named pipe, socket 
-                $rh_ignored->{$file_or_dir} = 'zero sized file';
-                next;
-            } elsif (-B $file_or_dir and !$opt_read_binary_files) { 
-                # avoid binary files unless user insists on reading them
-                if ($opt_unicode) {
-                    # only ignore if not a Unicode file w/trivial 
-                    # ASCII transliteration
-                    if (!unicode_file($file_or_dir)) {
-                        $rh_ignored->{$file_or_dir} = 'binary file';
-                        next;
-                    }
-                } else {
-                    $rh_ignored->{$file_or_dir} = 'binary file';
-                    next;
-                }
-            }
-            push @file_list, "$file_or_dir";
-        } elsif (is_dir($file_or_dir)) {
-            push @dir_list, $file_or_dir;
-        } else {
-            push @{$raa_errors}, [$rh_Err->{'Neither file nor directory'} , $file_or_dir];
-            $rh_ignored->{$file_or_dir} = 'not file, not directory';
-        }
-    }
-    foreach my $dir (@dir_list) {
-#print "make_file_list dir=$dir\n";
-        # populates global variable @file_list
-        find({wanted => \&files, follow => $opt_follow_links }, $dir);  
-    }
-    $nFiles_Found = scalar @file_list;
-    printf "%8d text file%s.\n", plural_form($nFiles_Found) unless $opt_quiet;
-    write_file($opt_found, sort @file_list) if $opt_found;
-
-    my $nFiles_Categorized = 0;
-    foreach my $file (@file_list) {
-        printf "classifying $file\n" if $opt_v > 2;
-
-        my $basename = basename $file;
-        if ($Not_Code_Filename{$basename}) {
-            $rh_ignored->{$file} = "listed in " . '$' .
-                "Not_Code_Filename{$basename}";
-            next;
-        } elsif ($basename =~ m{~$}) {
-            $rh_ignored->{$file} = "temporary editor file";
-            next;
-        }
-
-        my $size_in_bytes = (stat $file)[7];
-        my $language      = "";
-        if ($All_One_Language) {
-            # user over-rode auto-language detection by using
-            # --force-lang with just a language name (no extension)
-            $language      = $All_One_Language;
-        } else {
-            $language      = classify_file($file      ,
-                                           $rh_Err    ,
-                                           $raa_errors,
-                                           $rh_ignored);
-        }
-die  "make_file_list($file) undef size" unless defined $size_in_bytes;
-die  "make_file_list($file) undef lang" unless defined $language;
-        printf $fh "%d,%s,%s\n", $size_in_bytes, $language, $file;
-        ++$nFiles_Categorized;
-        #printf "classified %d files\n", $nFiles_Categorized 
-        #    unless (!$opt_progress_rate or 
-        #            ($nFiles_Categorized % $opt_progress_rate));
-    }
-    printf "classified %d files\r", $nFiles_Categorized 
-        if !$opt_quiet and $nFiles_Categorized > 1;
-
-    print "<- make_file_list()\n" if $opt_v > 2;
-
-    return $fh;   # handle to the file containing the list of files to process
-}  # 1}}}
-sub remove_duplicate_files {                 # {{{1
-    my ($fh                   , # in 
-        $rh_Language          , # out
-        $rh_unique_source_file, # out
-        $rh_Err               , # in
-        $raa_errors           , # out  errors encountered
-        $rh_ignored           , # out
-        ) = @_;
-
-    # Check for duplicate files by comparing file sizes.
-    # Where files are equally sized, compare their MD5 checksums.
-    print "-> remove_duplicate_files\n" if $opt_v > 2;
-
-    my $n = 0;
-    my %files_by_size = (); # files_by_size{ # bytes } = [ list of files ]
-    seek($fh, 0, 0); # rewind to beginning of the temp file
-    while (<$fh>) {
-        ++$n;
-        my ($size_in_bytes, $language, $file) = split(/,/, $_, 3);
-        chomp($file);
-        $rh_Language->{$file} = $language;
-        push @{$files_by_size{$size_in_bytes}}, $file;
-        if ($opt_skip_uniqueness) {
-            $rh_unique_source_file->{$file} = 1;
-        }
-    }
-    return if $opt_skip_uniqueness;
-    if ($opt_progress_rate and ($n > $opt_progress_rate)) {
-        printf "Duplicate file check %d files (%d known unique)\r", 
-            $n, scalar keys %files_by_size;
-    }
-    $n = 0;
-    foreach my $bytes (sort {$a <=> $b} keys %files_by_size) {
-        ++$n;
-        printf "Unique: %8d files                                          \r",
-            $n unless (!$opt_progress_rate or ($n % $opt_progress_rate));
-        if (scalar @{$files_by_size{$bytes}} == 1) {
-            # only one file is this big; must be unique
-            $rh_unique_source_file->{$files_by_size{$bytes}[0]} = 1;
-            next;
-        } else {
-#print "equally sized files: ",join(", ", @{$files_by_size{$bytes}}), "\n";
-            foreach my $F (different_files(\@{$files_by_size{$bytes}},
-                                            $rh_Err     ,
-                                            $raa_errors ,
-                                            $rh_ignored ) ) {
-                $rh_unique_source_file->{$F} = 1;
-            }
-        }
-    }
-    print "<- remove_duplicate_files\n" if $opt_v > 2;
-} # 1}}}
-sub files {                                  # {{{1
-    # invoked by File::Find's find()   Populates global variable @file_list
-    if ($opt_exclude_dir or $opt_exclude_list_file) {
-        my $return = 0;
-        foreach my $skip_dir (keys %Exclude_Dir) {
-            # File::Find::dir used to always start with / but
-            # newer versions (1.13) no longer do; have to correct for this
-            my $dir = $File::Find::dir;
-               $dir = "./$dir" unless $dir =~ m{^/};
-            if ($dir =~ m{/\Q$skip_dir\E(/|$)} ) {
-                $Ignored{$File::Find::name} = "--exclude-dir=$skip_dir";
-                $return = 1;
-                last;
-            }
-        }
-        return if $return;
-    }
-    my $Dir = cwd(); # not $File::Find::dir which just gives relative path
-	if ($opt_match_f    ) {	return unless /$opt_match_f/;     }
-    if ($opt_not_match_f) {	return if     /$opt_not_match_f/; }
-	if ($opt_match_d    ) {	return unless $Dir =~ m{$opt_match_d}     }
-    if ($opt_not_match_d) {	return if     $Dir =~ m{$opt_not_match_d} }
-
-    my $nBytes = -s     $_ ;
-    if (!$nBytes and $opt_v > 5) {
-        printf "files(%s)  zero size\n", $File::Find::name;
-    }
-    return unless $nBytes  ; # attempting other tests w/pipe or socket will hang
-    my $is_dir = is_dir($_);
-    my $is_bin = -B     $_ ;
-    printf "files(%s)  size=%d is_dir=%d  -B=%d\n",
-        $File::Find::name, $nBytes, $is_dir, $is_bin if $opt_v > 5;
-    $is_bin = 0 if $opt_unicode and unicode_file($_);
-    $is_bin = 0 if $opt_read_binary_files;
-    return if $is_dir or $is_bin;
-    ++$nFiles_Found;
-    printf "%8d files\r", $nFiles_Found 
-        unless (!$opt_progress_rate or ($nFiles_Found % $opt_progress_rate));
-    push @file_list, $File::Find::name;
-} # 1}}}
-sub archive_files {                          # {{{1
-    # invoked by File::Find's find()  Populates global variable @binary_archive
-    foreach my $ext (keys %Known_Binary_Archives) {
-        push @binary_archive, $File::Find::name 
-            if $File::Find::name =~ m{$ext$};
-    }
-} # 1}}}
-sub is_file {                                # {{{1
-    # portable method to test if item is a file
-    # (-f doesn't work in ActiveState Perl on Windows)
-    my $item = shift @_;
-
-    if ($ON_WINDOWS) {
-        my $mode = (stat $item)[2];
-           $mode = 0 unless $mode;
-        if ($mode & 0100000) { return 1; } 
-        else                 { return 0; }
-    } else {
-        return (-f $item);  # works on Unix, Linux, CygWin, z/OS
-    }
-} # 1}}}
-sub is_dir {                                 # {{{1
-    # portable method to test if item is a directory
-    # (-d doesn't work in ActiveState Perl on Windows)
-    my $item = shift @_;
-
-    if ($ON_WINDOWS) {
-        my $mode = (stat $item)[2];
-           $mode = 0 unless $mode;
-        if ($mode & 0040000) { return 1; } 
-        else                 { return 0; }
-    } else {
-        return (-d $item);  # works on Unix, Linux, CygWin, z/OS
-    }
-} # 1}}}
-sub is_excluded {                            # {{{1
-    my ($file       , # in
-        $excluded   , # in   hash of excluded directories
-       ) = @_;
-    my($filename, $filepath, $suffix) = fileparse($file);
-    foreach my $path (sort keys %{$excluded}) {
-        return 1 if ($filepath =~ m{^$path/}i);
-    }
-} # 1}}}
-sub classify_file {                          # {{{1
-    my ($full_file   , # in
-        $rh_Err      , # in   hash of error codes
-        $raa_errors  , # out
-        $rh_ignored  , # out
-       ) = @_;
-
-    print "-> classify_file($full_file)\n" if $opt_v > 2;
-    my $language = "(unknown)";
-
-    my $look_at_first_line = 0;
-    my $file = basename $full_file; 
-    if ($opt_autoconf and $file =~ /\.in$/) {
-       $file =~ s/\.in$//;
-    }
-    return $language if $Not_Code_Filename{$file}; # (unknown)
-    return $language if $file =~ m{~$}; # a temp edit file (unknown)
-    if (defined $Language_by_File{$file}) {
-        return $Language_by_File{$file};
-    }
-
-    if ($file =~ /\.(\w+)$/) { # has an extension
-      print "$full_file extension=[$1]\n" if $opt_v > 2;
-      my $extension = $1;
-         # Windows file names are case insensitive so map 
-         # all extensions to lowercase there.
-         $extension = lc $extension if $ON_WINDOWS;  
-      my @extension_list = ( $extension );
-      if ($file =~ /\.(\w+\.\w+)$/) { # has a double extension
-          my $extension = $1;
-          $extension = lc $extension if $ON_WINDOWS;  
-          unshift @extension_list, $extension;  # examine double ext first
-      }
-      foreach my $extension (@extension_list) {
-        if ($Not_Code_Extension{$extension} and 
-           !$Forced_Extension{$extension}) {
-           # If .1 (for example) is an extention that would ordinarily be
-           # ignored but the user has insisted this be counted with the
-           # --force-lang option, then go ahead and count it.
-            $rh_ignored->{$full_file} = 
-                'listed in $Not_Code_Extension{' . $extension . '}';
-            return $language;
-        }
-        if (defined $Language_by_Extension{$extension}) {
-            if ($Language_by_Extension{$extension} eq
-                'MATLAB/Objective C/MUMPS') {
-                my $lang_M_or_O = "";
-                matlab_or_objective_C($full_file , 
-                                      $rh_Err    ,
-                                      $raa_errors,
-                                     \$lang_M_or_O);
-                if ($lang_M_or_O) {
-                    return $lang_M_or_O;
-                } else { # an error happened in matlab_or_objective_C()
-                    $rh_ignored->{$full_file} = 
-                        'failure in matlab_or_objective_C()';
-                    return $language; # (unknown)
-                }
-            } elsif ($Language_by_Extension{$extension} eq 'PHP/Pascal') {
-                if (really_is_php($full_file)) {
-                    return 'PHP';
-                } elsif (really_is_incpascal($full_file)) {
-                    return 'Pascal';
-                } else {
-                    return $language; # (unknown)
-                }
-            } elsif ($Language_by_Extension{$extension} eq 'Smarty') {
-                # Smarty extension .tpl is generic; make sure the
-                # file at least roughly resembles PHP
-                if (really_is_php($full_file)) {
-                    return 'Smarty';
-                } else {
-                    return $language; # (unknown)
-                }
-            } else {
-                return $Language_by_Extension{$extension};
-            }
-        } else { # has an unmapped file extension
-            $look_at_first_line = 1;
-        }
-      }
-    } elsif (defined $Language_by_File{lc $file}) {
-        return $Language_by_File{lc $file};
-    } elsif ($opt_lang_no_ext and 
-             defined $Filters_by_Language{$opt_lang_no_ext}) {
-        return $opt_lang_no_ext;
-    } else {  # no file extension
-        $look_at_first_line = 1;
-    }
-
-    if ($look_at_first_line) {
-        # maybe it is a shell/Perl/Python/Ruby/etc script that
-        # starts with pound bang:
-        #   #!/usr/bin/perl
-        #   #!/usr/bin/env perl
-        my $script_language = peek_at_first_line($full_file , 
-                                                 $rh_Err    , 
-                                                 $raa_errors);
-        if (!$script_language) {
-            $rh_ignored->{$full_file} = "language unknown (#2)";
-            # returns (unknown)
-        }
-        if (defined $Language_by_Script{$script_language}) {
-            if (defined $Filters_by_Language{
-                            $Language_by_Script{$script_language}}) {
-                $language = $Language_by_Script{$script_language};
-            } else {
-                $rh_ignored->{$full_file} = 
-                    "undefined:  Filters_by_Language{" . 
-                    $Language_by_Script{$script_language} .
-                    "} for scripting language $script_language";
-                # returns (unknown)
-            }
-        } else {
-            $rh_ignored->{$full_file} = "language unknown (#3)";
-            # returns (unknown)
-        }
-    }
-    print "<- classify_file($full_file)\n" if $opt_v > 2;
-    return $language;
-} # 1}}}
-sub peek_at_first_line {                     # {{{1
-    my ($file        , # in
-        $rh_Err      , # in   hash of error codes
-        $raa_errors  , # out
-       ) = @_;
-
-    print "-> peek_at_first_line($file)\n" if $opt_v > 2;
-
-    my $script_language = "";
-    if (!-r $file) {
-        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
-        return $script_language;
-    }
-    my $IN = new IO::File $file, "r";
-    if (!defined $IN) {
-        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
-        print "<- peek_at_first_line($file)\n" if $opt_v > 2;
-        return $script_language;
-    }
-    chomp(my $first_line = <$IN>);
-    if (defined $first_line) {
-#print "peek_at_first_line of [$file] first_line=[$first_line]\n";
-        if ($first_line =~ /^#\!\s*(\S.*?)$/) {
-#print "peek_at_first_line 1=[$1]\n";
-            my @pound_bang = split(' ', $1);
-#print "peek_at_first_line basename 0=[", basename($pound_bang[0]), "]\n";
-            if (basename($pound_bang[0]) eq "env" and 
-                scalar @pound_bang > 1) {
-                $script_language = $pound_bang[1];
-#print "peek_at_first_line pound_bang A $pound_bang[1]\n";
-            } else {
-                $script_language = basename $pound_bang[0];
-#print "peek_at_first_line pound_bang B $script_language\n";
-            }
-        }
-    }
-    $IN->close;
-    print "<- peek_at_first_line($file)\n" if $opt_v > 2;
-    return $script_language;
-} # 1}}}
-sub different_files {                        # {{{1
-    # See which of the given files are unique by computing each file's MD5
-    # sum.  Return the subset of files which are unique.
-    my ($ra_files    , # in
-        $rh_Err      , # in
-        $raa_errors  , # out
-        $rh_ignored  , # out
-       ) = @_;
-
-    print "-> different_files(@{$ra_files})\n" if $opt_v > 2;
-    my %file_hash = ();  # file_hash{md5 hash} = [ file1, file2, ... ]
-    foreach my $F (@{$ra_files}) {
-        next if is_dir($F);  # needed for Windows
-        my $IN = new IO::File $F, "r";
-        if (!defined $IN) {
-            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F];
-            $rh_ignored->{$F} = 'cannot read';
-        } else {
-            if ($HAVE_Digest_MD5) {
-                binmode $IN;
-                my $MD5 = Digest::MD5->new->addfile($IN)->hexdigest;
-                push @{$file_hash{$MD5}}, $F;
-            } else {
-                # all files treated unique
-                push @{$file_hash{$F}}, $F;
-            }
-            $IN->close;
-        }
-    }
-
-    # Loop over file sets having identical MD5 sums.  Within
-    # each set, pick the file that most resembles known source 
-    # code.
-    my @unique = ();
-    for my $md5 (sort keys %file_hash) {
-        my $i_best = 0;
-        for (my $i = 1; $i < scalar(@{$file_hash{$md5}}); $i++) {
-            my $F = $file_hash{$md5}[$i];
-            my (@nul_a, %nul_h);
-            my $language = classify_file($F, $rh_Err, 
-                                        # don't save these errors; pointless
-                                        \@nul_a, \%nul_h);
-            $i_best = $i if $language ne "(unknown)";
-        }
-        push @unique, $file_hash{$md5}[$i_best];
-    }
-    print "<- different_files(@unique)\n" if $opt_v > 2;
-    return @unique;
-} # 1}}}
-sub call_counter {                           # {{{1
-    my ($file     , # in
-        $language , # in
-        $ra_Errors, # out
-       ) = @_;
-
-    # Logic:  pass the file through the following filters:
-    #         1. remove blank lines
-    #         2. remove comments using each filter defined for this language
-    #            (example:  SQL has two, remove_starts_with(--) and 
-    #             remove_c_comments() )
-    #         3. compute comment lines as 
-    #               total lines - blank lines - lines left over after all
-    #                   comment filters have been applied
-
-    print "-> call_counter($file, $language)\n" if $opt_v > 2;
-#print "call_counter:  ", Dumper(@routines), "\n";
-
-    my @lines = ();
-    my $ascii = "";
-    if (-B $file and $opt_unicode) {
-        # was binary so must be unicode
-
-        $/ = undef;
-        my $IN = new IO::File $file, "r";
-        my $bin_text = <$IN>;
-        $IN->close;
-        $/ = "\n";
-
-        $ascii = unicode_to_ascii( $bin_text );
-        @lines = split("\n", $ascii );
-        foreach (@lines) { $_ = "$_\n"; }
-
-    } else {
-        # regular text file
-        @lines = read_file($file);
-        $ascii = join('', @lines);
-    }
-
-    my @original_lines = @lines;
-    my $total_lines    = scalar @lines;
-
-    print_lines($file, "Original file:", \@lines) if $opt_print_filter_stages;
-    @lines = rm_blanks(\@lines, $language, \%EOL_Continuation_re); # remove blank lines
-    my $blank_lines = $total_lines - scalar @lines;
-    print_lines($file, "Blank lines removed:", \@lines) 
-        if $opt_print_filter_stages;
-
-    @lines = rm_comments(\@lines, $language, $file,
-                               \%EOL_Continuation_re);
-
-    my $comment_lines = $total_lines - $blank_lines - scalar  @lines;
-    if ($opt_strip_comments) {
-        my $stripped_file = "";
-        if ($opt_original_dir) {
-            $stripped_file =          $file . ".$opt_strip_comments";
-        } else {
-            $stripped_file = basename $file . ".$opt_strip_comments";
-        }
-        write_file($stripped_file, @lines);
-    }
-    if ($opt_html and !$opt_diff) {
-        chomp(@original_lines);  # includes blank lines, comments
-        chomp(@lines);           # no blank lines, no comments
-
-        my (@diff_L, @diff_R, %count);
-
-        # remove blank lines to get better quality diffs; count
-        # blank lines separately
-        my @original_lines_minus_white = ();
-        # however must keep track of how many blank lines were removed and
-        # where they were removed so that the HTML display can include it
-        my %blank_line  = ();
-        my $insert_line = 0;
-        foreach (@original_lines) {
-            if (/^\s*$/) {
-               ++$count{blank}{same};
-               ++$blank_line{ $insert_line };
-            } else {
-                ++$insert_line;
-                push @original_lines_minus_white, $_;
-            }
-        }
-
-        array_diff( $file                       ,   # in
-                   \@original_lines_minus_white ,   # in
-                   \@lines                      ,   # in
-                   "comment"                    ,   # in
-                   \@diff_L, \@diff_R,          ,   # out
-                    $ra_Errors);                    # in/out
-        write_comments_to_html($file, \@diff_L, \@diff_R, \%blank_line);
-#print Dumper("count", \%count);
-    }
-
-    print "<- call_counter($total_lines, $blank_lines, $comment_lines)\n" 
-        if $opt_v > 2;
-    return ($total_lines, $blank_lines, $comment_lines);
-} # 1}}}
-sub windows_glob {                           # {{{1
-    # Windows doesn't expand wildcards.  Use code from Sean M. Burke's 
-    # Win32::Autoglob module to do this.
-    return map {;
-        ( defined($_) and m/[\*\?]/ ) ? sort(glob($_)) : $_
-          } @_; 
-} # 1}}}
-sub write_file {                             # {{{1
-    my ($file  , # in
-        @lines , # in
-       ) = @_;
-
-#print "write_file 1 [$file]\n";
-    # Do ~ expansion (by Tim LaBerge, fixes bug 2787984)
-    my $preglob_filename = $file;
-#print "write_file 2 [$preglob_filename]\n";
-    if ($ON_WINDOWS) {
-        $file = (windows_glob($file))[0];
-    } else {
-        $file = glob($file);  # sometimes returns null string
-    }
-#print "write_file 3 [$file]\n";
-    $file = $preglob_filename unless $file;
-#print "write_file 4 [$file]\n";
-
-    print "-> write_file($file)\n" if $opt_v > 2;
-
-    # Create the destination directory if it doesn't already exist.
-    my $abs_file_path = File::Spec->rel2abs( $file );
-    my ($volume, $directories, $filename) = File::Spec->splitpath( $abs_file_path );
-    mkpath($volume . $directories, 1, 0777);
-    
-    my $OUT = new IO::File $file, "w";
-    if (defined $OUT) {
-        chomp(@lines);
-        print $OUT join("\n", @lines), "\n";
-        $OUT->close;
-    } else {
-        warn "Unable to write to $file\n";
-    }
-    print "Wrote $file";
-    print ", $CLOC_XSL" if $opt_xsl and $opt_xsl eq $CLOC_XSL;
-    print "\n";
-    
-    print "<- write_file\n" if $opt_v > 2;
-} # 1}}}
-sub read_file  {                             # {{{1
-    my ($file, ) = @_;
-
-    print "-> read_file($file)\n" if $opt_v > 2;
-    my @lines = ();
-    my $IN = new IO::File $file, "r";
-    if (defined $IN) {
-        @lines = <$IN>;
-        $IN->close;
-        # Some files don't end with a new line.  Force this:
-        $lines[$#lines] .= "\n" unless $lines[$#lines] =~ m/\n$/;
-    } else {
-        warn "Unable to read $file\n";
-    }
-    print "<- read_file\n" if $opt_v > 2;
-    return @lines;
-} # 1}}}
-sub rm_blanks {                              # {{{1
-    my ($ra_in    ,
-        $language ,
-        $rh_EOL_continuation_re) = @_;
-    print "-> rm_blanks(language=$language)\n" if $opt_v > 2;
-#print "rm_blanks: language = [$language]\n";
-    my @out = ();
-    if ($language eq "COBOL") {
-        @out = remove_cobol_blanks($ra_in);
-    } else {
-        # removes blank lines
-        if (defined $rh_EOL_continuation_re->{$language}) {
-            @out = remove_matches_2re($ra_in, '^\s*$', 
-                                      $rh_EOL_continuation_re->{$language}); 
-        } else {
-            @out = remove_matches($ra_in, '^\s*$');
-        }
-    }
-    print "<- rm_blanks(language=$language)\n" if $opt_v > 2;
-    return @out;
-} # 1}}}
-sub rm_comments {                            # {{{1
-    my ($ra_lines , # in, must be free of blank lines
-        $language , # in
-        $file     , # in (some language counters, eg Haskell, need 
-                    #     access to the original file)
-        $rh_EOL_continuation_re , # in
-       ) = @_;
-    print "-> rm_comments(file=$file)\n" if $opt_v > 2;
-    my @routines       = @{$Filters_by_Language{$language}};
-    my @lines          = @{$ra_lines};
-    my @original_lines = @{$ra_lines};
-
-    foreach my $call_string (@routines) {
-        my $subroutine = $call_string->[0];
-        if (! defined &{$subroutine}) {
-            warn "rm_comments undefined subroutine $subroutine for $file\n";
-            next;
-        }
-        print "rm_comments file=$file sub=$subroutine\n" if $opt_v > 1;
-        my @args  = @{$call_string};
-        shift @args; # drop the subroutine name
-        if (@args and $args[0] eq '>filename<') {
-            shift   @args;
-            unshift @args, $file;
-        }
-
-        no strict 'refs';
-        @lines = &{$subroutine}(\@lines, @args);   # apply filter...
-
-        print_lines($file, "After $subroutine(@args)", \@lines) 
-            if $opt_print_filter_stages;
-        # then remove blank lines which are created by comment removal
-        if (defined $rh_EOL_continuation_re->{$language}) {
-            @lines = remove_matches_2re(\@lines, '^\s*$',
-                                        $rh_EOL_continuation_re);
-        } else {
-            @lines = remove_matches(\@lines, '^\s*$');
-        }
-        
-        print_lines($file, "post $subroutine(@args) blank cleanup:", \@lines) 
-            if $opt_print_filter_stages;
-    }
-    # Exception for scripting languages:  treat the first #! line as code.
-    # Will need to add it back in if it was removed earlier.
-    if ($Script_Language{$language} and 
-        $original_lines[0] =~ /^#!/ and
-        (scalar(@lines) == 0 or 
-         $lines[0] ne $original_lines[0])) {
-        unshift @lines, $original_lines[0];  # add the first line back
-    }
-    print "<- rm_comments\n" if $opt_v > 2;
-    return @lines;
-} # 1}}}
-sub remove_f77_comments {                    # {{{1
-    my ($ra_lines, ) = @_;
-    print "-> remove_f77_comments\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    foreach (@{$ra_lines}) {
-        next if m{^[*cC]};
-        next if m{^\s*!};
-        push @save_lines, $_;
-    }
-
-    print "<- remove_f77_comments\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_f90_comments {                    # {{{1
-    # derived from SLOCCount
-    my ($ra_lines, ) = @_;
-    print "-> remove_f90_comments\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    foreach (@{$ra_lines}) {
-        # a comment is              m/^\s*!/
-        # an empty line is          m/^\s*$/
-        # a HPF statement is        m/^\s*!hpf\$/i
-        # an Open MP statement is   m/^\s*!omp\$/i
-        if (! m/^(\s*!|\s*$)/ || m/^\s*!(hpf|omp)\$/i) {
-            push @save_lines, $_;
-        }
-    }
-
-    print "<- remove_f90_comments\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_matches {                         # {{{1
-    my ($ra_lines, # in
-        $pattern , # in   Perl regular expression (case insensitive)
-       ) = @_;
-    print "-> remove_matches(pattern=$pattern)\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    foreach (@{$ra_lines}) {
-#chomp; print "remove_matches [$pattern] [$_]\n";
-        next if m{$pattern}i;
-        push @save_lines, $_;
-    }
-
-    print "<- remove_matches\n" if $opt_v > 2;
-#print "remove_matches returning\n   ", join("\n   ", @save_lines), "\n";
-    return @save_lines;
-} # 1}}}
-sub remove_matches_2re {                     # {{{1
-    my ($ra_lines, # in
-        $pattern1, # in Perl regex 1 (case insensitive) to match
-        $pattern2, # in Perl regex 2 (case insensitive) to not match prev line
-       ) = @_;
-    print "-> remove_matches_2re(pattern=$pattern1,$pattern2)\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {
-#print "remove_matches_2re [$pattern1] [$pattern2] [$ra_lines->[$i]]\n";
-        if ($i) {
-#print "remove_matches_2re prev=[$ra_lines->[$i-1]] this=[$ra_lines->[$i]]\n";
-            next if ($ra_lines->[$i]   =~ m{$pattern1}i) and 
-                    ($ra_lines->[$i-1] !~ m{$pattern2}i);
-        } else {
-            # on first line
-            next if $ra_lines->[$i]   =~  m{$pattern1}i;
-        }
-        push @save_lines, $ra_lines->[$i];
-    }
-
-    print "<- remove_matches_2re\n" if $opt_v > 2;
-#print "remove_matches_2re returning\n   ", join("\n   ", @save_lines), "\n";
-    return @save_lines;
-} # 1}}}
-sub remove_inline {                          # {{{1
-    my ($ra_lines, # in
-        $pattern , # in   Perl regular expression (case insensitive)
-       ) = @_;
-    print "-> remove_inline(pattern=$pattern)\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    unless ($opt_inline) {
-        return @{$ra_lines};
-    }
-    my $nLines_affected = 0;
-    foreach (@{$ra_lines}) {
-#chomp; print "remove_inline [$pattern] [$_]\n";
-        if (m{$pattern}i) {
-            ++$nLines_affected;
-            s{$pattern}{}i;
-        }
-        push @save_lines, $_;
-    }
-
-    print "<- remove_inline\n" if $opt_v > 2;
-#print "remove_inline returning\n   ", join("\n   ", @save_lines), "\n";
-    return @save_lines;
-} # 1}}}
-sub remove_above {                           # {{{1
-    my ($ra_lines, $marker, ) = @_;
-    print "-> remove_above(marker=$marker)\n" if $opt_v > 2;
-
-    # Make two passes through the code:
-    # 1. check if the marker exists
-    # 2. remove anything above the marker if it exists,
-    #    do nothing if the marker does not exist
-
-    # Pass 1
-    my $found_marker = 0;
-    for (my $line_number  = 1;
-            $line_number <= scalar @{$ra_lines};
-            $line_number++) {
-        if ($ra_lines->[$line_number-1] =~ m{$marker}) {
-            $found_marker = $line_number;
-            last;
-        }
-    }
-
-    # Pass 2 only if needed
-    my @save_lines = ();
-    if ($found_marker) {
-        my $n = 1;
-        foreach (@{$ra_lines}) {
-            push @save_lines, $_
-                if $n >= $found_marker;
-            ++$n;
-        }
-    } else { # marker wasn't found; save all lines
-        foreach (@{$ra_lines}) {
-            push @save_lines, $_;
-        }
-    }
-
-    print "<- remove_above\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_below {                           # {{{1
-    my ($ra_lines, $marker, ) = @_;
-    print "-> remove_below(marker=$marker)\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    foreach (@{$ra_lines}) {
-        last if m{$marker};
-        push @save_lines, $_;
-    }
-
-    print "<- remove_below\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_below_above {                     # {{{1
-    my ($ra_lines, $marker_below, $marker_above, ) = @_;
-    # delete lines delimited by start and end line markers such
-    # as Perl POD documentation
-    print "-> remove_below_above(markerB=$marker_below, A=$marker_above)\n" 
-        if $opt_v > 2;
-
-    my @save_lines = ();
-    my $between    = 0;
-    foreach (@{$ra_lines}) {
-        if (!$between and m{$marker_below}) {
-            $between    = 1;
-            next;
-        }
-        if ($between and m{$marker_above}) {
-            $between    = 0;
-            next;
-        }
-        next if $between;
-        push @save_lines, $_;
-    }
-
-    print "<- remove_below_above\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_between {                         # {{{1
-    my ($ra_lines, $marker, ) = @_;
-    # $marker must contain one of the balanced pairs understood
-    # by Regexp::Common::balanced, namely
-    # '{}'  '()'  '[]'  or  '<>'
-
-    print "-> remove_between(marker=$marker)\n" if $opt_v > 2;
-    my %acceptable = ('{}'=>1,  '()'=>1,  '[]'=>1,  '<>'=>1, );
-    die "remove_between:  invalid delimiter '$marker'\n",
-        "the delimiter must be one of these four pairs:\n",
-        "{}  ()  []  <>\n" unless
-        $acceptable{$marker};
-
-    Install_Regexp_Common() unless $HAVE_Rexexp_Common;
-
-    my $all_lines = join("", @{$ra_lines});
-
-    no strict 'vars';
-    # otherwise get:
-    #  Global symbol "%RE" requires explicit package name at cloc line xx.
-    if ($all_lines =~ m/$RE{balanced}{-parens => $marker}/) {
-        no warnings; 
-        $all_lines =~ s/$1//g;
-    }
-
-    print "<- remove_between\n" if $opt_v > 2;
-    return split("\n", $all_lines);
-} # 1}}}
-sub remove_cobol_blanks {                    # {{{1
-    # subroutines derived from SLOCCount
-    my ($ra_lines, ) = @_;
-
-    my $free_format = 0;  # Support "free format" source code.
-    my @save_lines  = ();
-  
-    foreach (@{$ra_lines}) {
-        next if m/^\s*$/;
-        my $line = expand($_);  # convert tabs to equivalent spaces
-        $free_format = 1 if $line =~ m/^......\$.*SET.*SOURCEFORMAT.*FREE/i;
-        if ($free_format) {
-            push @save_lines, $_;
-        } else {
-            # Greg Toth:
-            #  (1) Treat lines with any alphanum in cols 1-6 and 
-            #      blanks in cols 7 through 71 as blank line, and
-            #  (2) Treat lines with any alphanum in cols 1-6 and 
-            #      slash (/) in col 7 as blank line (this is a 
-            #      page eject directive). 
-            push @save_lines, $_ unless m/^\d{6}\s*$/             or 
-                                        ($line =~ m/^.{6}\s{66}/) or 
-                                        ($line =~ m/^......\//);
-        }
-    }
-    return @save_lines;
-} # 1}}}
-sub remove_cobol_comments {                  # {{{1
-    # subroutines derived from SLOCCount
-    my ($ra_lines, ) = @_;
-
-    my $free_format = 0;  # Support "free format" source code.
-    my @save_lines  = ();
-  
-    foreach (@{$ra_lines}) {
-        if (m/^......\$.*SET.*SOURCEFORMAT.*FREE/i) {$free_format = 1;}
-        if ($free_format) {
-            push @save_lines, $_ unless m{^\s*\*};
-        } else {
-            push @save_lines, $_ unless m{^......\*} or m{^\*};
-        }
-    }
-    return @save_lines;
-} # 1}}}
-sub remove_jcl_comments {                    # {{{1
-    my ($ra_lines, ) = @_;
-
-    print "-> remove_jcl_comments\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    my $in_comment = 0;
-    foreach (@{$ra_lines}) {
-        next if /^\s*$/;
-        next if m{^\s*//\*};
-        last if m{^\s*//\s*$};
-        push @save_lines, $_;
-    }
-
-    print "<- remove_jcl_comments\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_jsp_comments {                    # {{{1
-    #  JSP comment is   <%--  body of comment   --%>
-    my ($ra_lines, ) = @_;
-
-    print "-> remove_jsp_comments\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    my $in_comment = 0;
-    foreach (@{$ra_lines}) {
-
-        next if /^\s*$/;
-        s/<\%\-\-.*?\-\-\%>//g;  # strip one-line comments
-        next if /^\s*$/;
-        if ($in_comment) {
-            if (/\-\-\%>/) {
-                s/^.*?\-\-\%>//;
-                $in_comment = 0;
-            }
-        }
-        next if /^\s*$/;
-        $in_comment = 1 if /^(.*?)<\%\-\-/;
-        next if defined $1 and $1 =~ /^\s*$/;
-        next if ($in_comment);
-        push @save_lines, $_;
-    }
-
-    print "<- remove_jsp_comments\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub remove_html_comments {                   # {{{1
-    #  HTML comment is   <!--  body of comment   -->
-    #  Need to use my own routine until the HTML comment regex in
-    #  the Regexp::Common module can handle  <!--  --  -->
-    my ($ra_lines, ) = @_;
-
-    print "-> remove_html_comments\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    my $in_comment = 0;
-    foreach (@{$ra_lines}) {
-
-        next if /^\s*$/;
-        s/<!\-\-.*?\-\->//g;  # strip one-line comments
-        next if /^\s*$/;
-        if ($in_comment) {
-            if (/\-\->/) {
-                s/^.*?\-\->//;
-                $in_comment = 0;
-            }
-        }
-        next if /^\s*$/;
-        $in_comment = 1 if /^(.*?)<!\-\-/;
-        next if defined $1 and $1 =~ /^\s*$/;
-        next if ($in_comment);
-        push @save_lines, $_;
-    }
-
-    print "<- remove_html_comments\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub add_newlines {                           # {{{1
-    my ($ra_lines, ) = @_;
-    print "-> add_newlines \n" if $opt_v > 2;
-
-    my @save_lines = ();
-    foreach (@{$ra_lines}) {
-
-        push @save_lines, "$_\n";
-    }
-
-    print "<- add_newlines \n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub docstring_to_C {                         # {{{1
-    my ($ra_lines, ) = @_;
-    # Converts Python docstrings to C comments.
-
-    print "-> docstring_to_C()\n" if $opt_v > 2;
-
-    my $in_docstring = 0;
-    foreach (@{$ra_lines}) {
-        while (/"""/) {
-            if (!$in_docstring) {
-                s{"""}{/*};
-                $in_docstring = 1;
-            } else {
-                s{"""}{*/};
-                $in_docstring = 0;
-            }
-        }
-    }
-
-    print "<- docstring_to_C\n" if $opt_v > 2;
-    return @{$ra_lines};
-} # 1}}}
-sub smarty_to_C {                            # {{{1
-    my ($ra_lines, ) = @_;
-    # Converts Smarty comments to C comments.
-
-    print "-> smarty_to_C()\n" if $opt_v > 2;
-
-    foreach (@{$ra_lines}) {
-        s[{\*][/*]g;
-        s[\*}][*/]g;
-    }
-
-    print "<- smarty_to_C\n" if $opt_v > 2;
-    return @{$ra_lines};
-} # 1}}}
-sub determine_lit_type {                     # {{{1
-  my ($file) = @_;
-
-  open (FILE, $file);
-  while (<FILE>) {
-    if (m/^\\begin{code}/) { close FILE; return 2; }
-    if (m/^>\s/) { close FILE; return 1; }
-  }
-
-  return 0;
-} # 1}}}
-sub remove_haskell_comments {                # {{{1
-    # Bulk of code taken from SLOCCount's haskell_count script.
-    # Strips out {- .. -} and -- comments and counts the rest.
-    # Pragmas, {-#...}, are counted as SLOC.
-    # BUG: Doesn't handle strings with embedded block comment markers gracefully.
-    #      In practice, that shouldn't be a problem.
-    my ($ra_lines, $file, ) = @_;
-
-    print "-> remove_haskell_comments\n" if $opt_v > 2;
-
-    my @save_lines = ();
-    my $in_comment = 0;
-    my $incomment  = 0;
-    my ($literate, $inlitblock) = (0,0);
-  
-    $literate = 1 if $file =~ /\.lhs$/;
-    if($literate) { $literate = determine_lit_type($file) }
-
-    foreach (@{$ra_lines}) {
-        if ($literate == 1) {
-            if (!s/^>//) { s/.*//; }
-        } elsif ($literate == 2) {
-            if ($inlitblock) {
-                if (m/^\\end{code}/) { s/.*//; $inlitblock = 0; }
-            } elsif (!$inlitblock) {
-                if (m/^\\begin{code}/) { s/.*//; $inlitblock = 1; }
-                else { s/.*//; }
-            }
-        }
-
-        if ($incomment) {
-            if (m/\-\}/) { s/^.*?\-\}//;  $incomment = 0;}
-            else { s/.*//; }
-        }
-        if (!$incomment) {
-            s/--.*//;
-            s!{-[^#].*?-}!!g;
-            if (m/{-/ && (!m/{-#/)) {
-              s/{-.*//;
-              $incomment = 1;
-            }
-        }
-        if (m/\S/) { push @save_lines, $_; }
-    }
-#   if ($incomment) {print "ERROR: ended in comment in $ARGV\n";}
-
-    print "<- remove_haskell_comments\n" if $opt_v > 2;
-    return @save_lines;
-} # 1}}}
-sub print_lines {                            # {{{1
-    my ($file     , # in
-        $title    , # in
-        $ra_lines , # in
-       ) = @_;
-    printf "->%-30s %s\n", $file, $title;
-    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {
-        printf "%5d | %s", $i+1, $ra_lines->[$i];
-        print "\n" unless $ra_lines->[$i] =~ m{\n$}
-    }
-} # 1}}}
-sub set_constants {                          # {{{1
-    my ($rh_Language_by_Extension , # out
-        $rh_Language_by_Script    , # out
-        $rh_Language_by_File      , # out
-        $rhaa_Filters_by_Language , # out
-        $rh_Not_Code_Extension    , # out
-        $rh_Not_Code_Filename     , # out
-        $rh_Scale_Factor          , # out
-        $rh_Known_Binary_Archives , # out
-        $rh_EOL_continuation_re   , # out
-       ) = @_;
-# 1}}}
-%{$rh_Language_by_Extension} = (                 # {{{1
-            'abap'        => 'ABAP'                  ,
-            'ac'          => 'm4'                    ,
-            'ada'         => 'Ada'                   ,
-            'adb'         => 'Ada'                   ,
-            'ads'         => 'Ada'                   ,
-            'adso'        => 'ADSO/IDSM'             ,
-            'am'          => 'make'                  ,
-            'ample'       => 'AMPLE'                 ,
-            'as'          => 'ActionScript'          ,
-            'dofile'      => 'AMPLE'                 ,
-            'startup'     => 'AMPLE'                 ,
-            'asa'         => 'ASP'                   ,
-            'asax'        => 'ASP.Net'               ,
-            'ascx'        => 'ASP.Net'               ,
-            'asm'         => 'Assembly'              ,
-            'asmx'        => 'ASP.Net'               ,
-            'asp'         => 'ASP'                   ,
-            'aspx'        => 'ASP.Net'               ,
-            'master'      => 'ASP.Net'               ,
-            'sitemap'     => 'ASP.Net'               ,
-            'awk'         => 'awk'                   ,
-            'bash'        => 'Bourne Again Shell'    ,
-            'bas'         => 'Visual Basic'          ,
-            'bat'         => 'DOS Batch'             ,
-            'BAT'         => 'DOS Batch'             ,
-            'cbl'         => 'COBOL'                 ,
-            'CBL'         => 'COBOL'                 ,
-            'c'           => 'C'                     ,
-            'C'           => 'C++'                   ,
-            'cc'          => 'C++'                   ,
-            'ccs'         => 'CCS'                   ,
-            'cfm'         => 'ColdFusion'            ,
-            'cl'          => 'Lisp'                  ,
-            'cls'         => 'Visual Basic'          ,
-            'CMakeLists.txt' => 'CMake'              ,
-            'cob'         => 'COBOL'                 ,
-            'COB'         => 'COBOL'                 ,
-            'config'      => 'ASP.Net'               ,
-            'cpp'         => 'C++'                   ,
-            'cs'          => 'C#'                    ,
-            'csh'         => 'C Shell'               ,
-            'css'         => "CSS"                   ,
-            'cxx'         => 'C++'                   ,
-            'd'           => 'D'                     ,
-            'da'          => 'DAL'                   ,
-            'dart'        => 'Dart'                  ,
-            'def'         => 'Teamcenter def'        ,
-            'dmap'        => 'NASTRAN DMAP'          ,
-            'dpr'         => 'Pascal'                ,
-            'dtd'         => 'DTD'                   ,
-            'ec'          => 'C'                     ,
-            'el'          => 'Lisp'                  ,
-            'erl'         => 'Erlang'                ,
-            'exp'         => 'Expect'                ,
-            'f77'         => 'Fortran 77'            ,
-            'F77'         => 'Fortran 77'            ,
-            'f90'         => 'Fortran 90'            ,
-            'F90'         => 'Fortran 90'            ,
-            'f95'         => 'Fortran 95'            ,
-            'F95'         => 'Fortran 95'            ,
-            'f'           => 'Fortran 77'            ,
-            'F'           => 'Fortran 77'            ,
-            'fmt'         => 'Oracle Forms'          ,
-            'focexec'     => 'Focus'                 ,
-            'frm'         => 'Visual Basic'          ,
-            'gnumakefile' => 'make'                  ,
-            'Gnumakefile' => 'make'                  ,
-            'go'          => 'Go'                    ,
-            'groovy'      => 'Groovy'                ,
-            'h'           => 'C/C++ Header'          ,
-            'H'           => 'C/C++ Header'          ,
-            'hh'          => 'C/C++ Header'          ,
-            'hpp'         => 'C/C++ Header'          ,
-            'hrl'         => 'Erlang'                ,
-            'hs'          => 'Haskell'               , 
-            'htm'         => 'HTML'                  ,
-            'html'        => 'HTML'                  ,
-            'i3'          => 'Modula3'               ,
-            'idl'         => 'IDL'                   ,
-            'pro'         => 'IDL'                   ,
-            'ig'          => 'Modula3'               ,
-            'il'          => 'SKILL'                 ,
-            'ils'         => 'SKILL++'               ,
-            'inc'         => 'PHP/Pascal'            , # might be PHP or Pascal
-            'itk'         => 'Tcl/Tk'                ,
-            'java'        => 'Java'                  ,
-            'jcl'         => 'JCL'                   , # IBM Job Control Lang.
-            'jl'          => 'Lisp'                  ,
-            'js'          => 'Javascript'            ,
-            'jsp'         => 'JSP'                   , # Java server pages
-            'ksc'         => 'Kermit'                ,
-            'ksh'         => 'Korn Shell'            ,
-            'lhs'         => 'Haskell'               ,
-            'l'           => 'lex'                   ,
-            'lsp'         => 'Lisp'                  ,
-            'lisp'        => 'Lisp'                  ,
-            'lua'         => 'Lua'                   ,
-            'm3'          => 'Modula3'               ,
-            'm4'          => 'm4'                    ,
-            'makefile'    => 'make'                  ,
-            'Makefile'    => 'make'                  ,
-            'met'         => 'Teamcenter met'        ,
-            'mg'          => 'Modula3'               , 
-#           'mli'         => 'ML'                    , # ML not implemented
-#           'ml'          => 'ML'                    , 
-            'ml'          => 'Ocaml'                 , 
-            'm'           => 'MATLAB/Objective C/MUMPS' ,
-            'mm'          => 'Objective C++'         ,
-            'wdproj'      => 'MSBuild scripts'       ,
-            'csproj'      => 'MSBuild scripts'       ,
-            'mps'         => 'MUMPS'                 ,
-            'mth'         => 'Teamcenter mth'        ,
-            'oscript'     => 'LiveLink OScript'      ,
-            'pad'         => 'Ada'                   , # Oracle Ada preprocessor
-            'pas'         => 'Pascal'                ,
-            'pcc'         => 'C++'                   , # Oracle C++ preprocessor
-            'perl'        => 'Perl'                  ,
-            'pfo'         => 'Fortran 77'            ,
-            'pgc'         => 'C'                     , # Postgres embedded C/C++
-            'php3'        => 'PHP'                   ,
-            'php4'        => 'PHP'                   ,
-            'php5'        => 'PHP'                   ,
-            'php'         => 'PHP'                   ,
-            'plh'         => 'Perl'                  ,
-            'pl'          => 'Perl'                  ,
-            'PL'          => 'Perl'                  ,
-            'plx'         => 'Perl'                  ,
-            'pm'          => 'Perl'                  ,
-            'p'           => 'Pascal'                ,
-            'pp'          => 'Pascal'                ,
-            'psql'        => 'SQL'                   ,
-            'py'          => 'Python'                ,
-            'pyx'         => 'Cython'                ,
-            'rb'          => 'Ruby'                  ,
-         #  'resx'        => 'ASP.Net'               ,
-            'rex'         => 'Oracle Reports'        ,
-            'rexx'        => 'Rexx'                  ,
-            'rhtml'       => 'Ruby HTML'             ,
-            's'           => 'Assembly'              ,
-            'S'           => 'Assembly'              ,
-            'scala'       => 'Scala'                 ,
-            'sbl'         => 'Softbridge Basic'      ,
-            'SBL'         => 'Softbridge Basic'      ,
-            'sc'          => 'Lisp'                  ,
-            'scm'         => 'Lisp'                  ,
-            'sed'         => 'sed'                   ,
-            'ses'         => 'Patran Command Language'   ,
-            'pcl'         => 'Patran Command Language'   ,
-            'sh'          => 'Bourne Shell'          ,
-            'smarty'      => 'Smarty'                ,
-            'sql'         => 'SQL'                   ,
-            'SQL'         => 'SQL'                   ,
-            'sproc.sql'   => 'SQL Stored Procedure'  ,
-            'spoc.sql'    => 'SQL Stored Procedure'  ,
-            'spc.sql'     => 'SQL Stored Procedure'  ,
-            'udf.sql'     => 'SQL Stored Procedure'  ,
-            'data.sql'    => 'SQL Data'              ,
-            'tcl'         => 'Tcl/Tk'                ,
-            'tcsh'        => 'C Shell'               ,
-            'tk'          => 'Tcl/Tk'                ,
-            'tpl'         => 'Smarty'                ,
-            'vhd'         => 'VHDL'                  ,
-            'VHD'         => 'VHDL'                  ,
-            'vhdl'        => 'VHDL'                  ,
-            'VHDL'        => 'VHDL'                  ,
-            'vba'         => 'Visual Basic'          ,
-            'VBA'         => 'Visual Basic'          ,
-         #  'vbp'         => 'Visual Basic'          , # .vbp - autogenerated
-            'vb'          => 'Visual Basic'          ,
-            'VB'          => 'Visual Basic'          ,
-         #  'vbw'         => 'Visual Basic'          , # .vbw - autogenerated
-            'vbs'         => 'Visual Basic'          ,
-            'VBS'         => 'Visual Basic'          ,
-            'webinfo'     => 'ASP.Net'               ,
-            'xml'         => 'XML'                   ,
-            'XML'         => 'XML'                   ,
-            'mxml'        => 'MXML'                  ,
-            'build'       => 'NAnt scripts'          ,
-            'vim'         => 'vim script'            ,
-            'xaml'        => 'XAML'                  ,
-            'xsd'         => 'XSD'                   ,
-            'XSD'         => 'XSD'                   ,
-            'xslt'        => 'XSLT'                  ,
-            'XSLT'        => 'XSLT'                  ,
-            'xsl'         => 'XSLT'                  ,
-            'XSL'         => 'XSLT'                  ,
-            'y'           => 'yacc'                  ,
-            'yaml'        => 'YAML'                  ,
-            'yml'         => 'YAML'                  ,
-            );
-# 1}}}
-%{$rh_Language_by_Script}    = (                 # {{{1
-            'awk'      => 'awk'                   ,
-            'bash'     => 'Bourne Again Shell'    ,
-            'bc'       => 'bc'                    ,# calculator
-            'csh'      => 'C Shell'               ,
-            'dmd'      => 'D'                     ,
-            'idl'      => 'IDL'                   ,
-            'kermit'   => 'Kermit'                ,
-            'ksh'      => 'Korn Shell'            ,
-            'lua'      => 'Lua'                   ,
-            'make'     => 'make'                  ,
-            'octave'   => 'Octave'                ,
-            'perl5'    => 'Perl'                  ,
-            'perl'     => 'Perl'                  ,
-            'ruby'     => 'Ruby'                  ,
-            'sed'      => 'sed'                   ,
-            'sh'       => 'Bourne Shell'          ,
-            'tcl'      => 'Tcl/Tk'                ,
-            'tclsh'    => 'Tcl/Tk'                ,
-            'tcsh'     => 'C Shell'               ,
-            'wish'     => 'Tcl/Tk'                ,
-            );
-# 1}}}
-%{$rh_Language_by_File}      = (                 # {{{1
-            'Makefile'       => 'make'               ,
-            'makefile'       => 'make'               ,
-            'gnumakefile'    => 'make'               ,
-            'Gnumakefile'    => 'make'               ,
-            'CMakeLists.txt' => 'CMake'              ,
-            );
-# 1}}}
-%{$rhaa_Filters_by_Language} = (                 # {{{1
-    'ABAP'               => [   [ 'remove_matches'      , '^\*'    ], ],
-    'ActionScript'       => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-
-    'ASP'                => [   [ 'remove_matches'      , '^\s*\47'], ],  # \47 = '
-    'ASP.Net'            => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'Ada'                => [   [ 'remove_matches'      , '^\s*--' ], ],
-    'ADSO/IDSM'          => [   [ 'remove_matches'      , '^\s*\*[\+\!]' ], ],
-    'AMPLE'              => [   [ 'remove_matches'      , '^\s*//' ], ],
-    'Assembly'           => [  
-                                [ 'remove_matches'      , '^\s*//' ],
-                                [ 'remove_matches'      , '^\s*;'  ],
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                                [ 'remove_inline'       , ';.*$'   ],
-                            ],
-    'awk'                => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'bc'                 => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'C'                  => [   
-                                [ 'remove_matches'      , '^\s*//' ], # C99
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '//.*$'  ], # C99
-                            ], 
-    'C++'                => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-    'C/C++ Header'       => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ],
-    'CMake'              => [   
-                                [ 'remove_matches'      , '^\s*#'  ],
-                                [ 'remove_inline'       , '#.*$'   ], 
-                            ],
-    'Cython'             => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'docstring_to_C'                 ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'C#'                 => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ],
-    'CCS'                => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'CSS'                => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'COBOL'              => [   [ 'remove_cobol_comments',         ], ],
-    'ColdFusion'         => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'Crystal Reports'    => [   [ 'remove_matches'      , '^\s*//' ], ],
-    'D'                  => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ],
-    'DAL'                => [   [ 'remove_between'      , '[]',    ], ],
-    'Dart'               => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-    'NASTRAN DMAP'       => [   
-                                [ 'remove_matches'      , '^\s*\$' ], 
-                                [ 'remove_inline'       , '\$.*$'  ], 
-                            ],
-    'DOS Batch'          => [   [ 'remove_matches'      , '^\s*rem', ], ],
-    'DTD'                => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'Erlang'             => [   
-                                [ 'remove_matches'      , '^\s*%'  ], 
-                                [ 'remove_inline'       , '%.*$'   ],
-                            ],
-    'Expect'             => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Focus'              => [   [ 'remove_matches'      , '^\s*\-\*'  ], ],
-    'Fortran 77'         => [   
-                                [ 'remove_f77_comments' ,          ], 
-                                [ 'remove_inline'       , '\!.*$'  ],
-                            ],
-    'Fortran 90'         => [   
-                                [ 'remove_f77_comments' ,          ],
-                                [ 'remove_f90_comments' ,          ], 
-                                [ 'remove_inline'       , '\!.*$'  ],
-                            ],
-    'Fortran 95'         => [   
-                                [ 'remove_f77_comments' ,          ],
-                                [ 'remove_f90_comments' ,          ], 
-                                [ 'remove_inline'       , '\!.*$'  ],
-                            ],
-    'Go'                 => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-    'Groovy'             => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-    'HTML'               => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'Haskell'            => [   [ 'remove_haskell_comments', '>filename<' ], ],
-    'IDL'                => [   [ 'remove_matches'      , '^\s*;'  ], ],
-    'JSP'                => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ],
-                                [ 'remove_jsp_comments' ,          ], 
-                                [ 'remove_matches'      , '^\s*//' ],
-                                [ 'add_newlines'        ,          ],
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-    'Java'               => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ],
-    'Javascript'         => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ],
-    'JCL'                => [   [ 'remove_jcl_comments' ,          ], ],
-    'Lisp'               => [   [ 'remove_matches'      , '^\s*;'  ], ],
-    'LiveLink OScript'   => [   [ 'remove_matches'      , '^\s*//' ], ],
-#   'Lua'                => [   [ 'call_regexp_common'  , 'lua'    ], ],
-    'Lua'                => [   [ 'remove_matches'      , '^\s*\-\-' ], ],
-    'make'               => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'MATLAB'             => [   
-                                [ 'remove_matches'      , '^\s*%'  ], 
-                                [ 'remove_inline'       , '%.*$'   ],
-                            ], 
-    'Modula3'            => [   [ 'call_regexp_common'  , 'Pascal' ], ],
-        # Modula 3 comments are (* ... *) so applying the Pascal filter
-        # which also treats { ... } as a comment is not really correct.
-    'Objective C'        => [   
-                                [ 'remove_matches'      , '^\s*//' ],
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ], 
-    'Objective C++'      => [   
-                                [ 'remove_matches'      , '^\s*//' ],
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ], 
-    'Ocaml'              => [   
-                                [ 'call_regexp_common'  , 'Pascal' ], 
-                            ],
-    'PHP/Pascal'               => [ [ 'die' ,          ], ], # never called
-    'MATLAB/Objective C/MUMPS' => [ [ 'die' ,          ], ], # never called
-    'MUMPS'              => [   [ 'remove_matches'      , '^\s*;'  ], ], 
-    'Octave'             => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Oracle Forms'       => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'Oracle Reports'     => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'Pascal'             => [   
-                                [ 'call_regexp_common'  , 'Pascal' ], 
-                                [ 'remove_matches'      , '^\s*//' ],
-                            ],
-    'Patran Command Language'=> [   
-                                [ 'remove_matches'      , '^\s*#'   ], 
-                                [ 'remove_matches'      , '^\s*\$#' ], 
-                                [ 'call_regexp_common'  , 'C'       ],
-                            ],
-    'Perl'               => [   [ 'remove_below'        , '^__(END|DATA)__'],
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_below_above'  , '^=head1', '^=cut'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Python'             => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'docstring_to_C'                 ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'PHP'                => [   
-                                [ 'remove_matches'      , '^\s*#'  ],
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                                [ 'remove_inline'       , '//.*$'  ],
-                            ],
-    'Rexx'               => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'Ruby'               => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Ruby HTML'          => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'Scala'              => [   
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'remove_inline'       , '//.*$'  ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ],
-    'SKILL'              => [   
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_matches'      , '^\s*;'  ],
-                            ],
-    'SKILL++'            => [   
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_matches'      , '^\s*;'  ],
-                            ],
-    'SQL'                => [   
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_matches'      , '^\s*--' ],
-                                [ 'remove_inline'       , '--.*$'  ],
-                            ],
-    'SQL Stored Procedure'=> [   
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_matches'      , '^\s*--' ],
-                                [ 'remove_inline'       , '--.*$'  ],
-                            ],
-    'SQL Data'           => [   
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_matches'      , '^\s*--' ],
-                                [ 'remove_inline'       , '--.*$'  ],
-                            ],
-    'sed'                => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Smarty'             => [   
-                                [ 'smarty_to_C'                    ], 
-                                [ 'call_regexp_common'  , 'C'      ],
-                            ], 
-    'Bourne Again Shell' => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Bourne Shell'       => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'm4'                 => [   [ 'remove_matches'      , '^dnl '  ], ], 
-    'C Shell'            => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Kermit'             => [  
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_matches'      , '^\s*;'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Korn Shell'         => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Tcl/Tk'             => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ],
-                            ], 
-    'Teamcenter def'     => [   [ 'remove_matches'      , '^\s*#'  ], ], 
-    'Teamcenter met'     => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'Teamcenter mth'     => [   [ 'remove_matches'      , '^\s*#'  ], ], 
-    'Softbridge Basic'   => [   [ 'remove_above'        , '^\s*Attribute\s+VB_Name\s+=' ],               
-                                [ 'remove_matches'      , '^\s*Attribute\s+'],
-                                [ 'remove_matches'      , '^\s*\47'], ],  # \47 = '
-    # http://www.altium.com/files/learningguides/TR0114%20VHDL%20Language%20Reference.pdf
-    'VHDL'               => [   
-                                [ 'remove_matches'      , '^\s*--' ],
-                                [ 'remove_matches'      , '^\s*//' ], 
-                                [ 'call_regexp_common'  , 'C'      ], 
-                                [ 'remove_inline'       , '--.*$'  ],
-                                [ 'remove_inline'       , '//.*$'  ], 
-                            ],
-    'vim script'         => [   
-                                [ 'remove_matches'      , '^\s*"'  ], 
-                                [ 'remove_inline'       , '".*$'   ], 
-                            ],
-    'Visual Basic'       => [   [ 'remove_above'        , '^\s*Attribute\s+VB_Name\s+=' ],               
-                                [ 'remove_matches'      , '^\s*Attribute\s+'],
-                                [ 'remove_matches'      , '^\s*\47'], ],  # \47 = '
-    'yacc'               => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'YAML'               => [   
-                                [ 'remove_matches'      , '^\s*#'  ], 
-                                [ 'remove_inline'       , '#.*$'   ], 
-                            ],
-    'lex'                => [   [ 'call_regexp_common'  , 'C'      ], ],
-    'XAML'               => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'MXML'               => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'XML'                => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'XSD'                => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'XSLT'               => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'NAnt scripts'       => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    'MSBuild scripts'    => [   [ 'remove_html_comments',          ],
-                                [ 'call_regexp_common'  , 'HTML'   ], ],
-    );
-# 1}}}
-%{$rh_EOL_continuation_re} = (                 # {{{1
-    'ActionScript'       =>     '\\\\$'         ,
-    'Assembly'           =>     '\\\\$'         ,
-    'ASP'                =>     '\\\\$'         ,
-    'ASP.Net'            =>     '\\\\$'         ,
-    'Ada'                =>     '\\\\$'         ,
-    'awk'                =>     '\\\\$'         ,
-    'bc'                 =>     '\\\\$'         ,
-    'C'                  =>     '\\\\$'         ,
-    'C++'                =>     '\\\\$'         ,
-    'C/C++ Header'       =>     '\\\\$'         ,
-    'CMake'              =>     '\\\\$'         ,
-    'Cython'             =>     '\\\\$'         ,
-    'C#'                 =>     '\\\\$'         ,
-    'D'                  =>     '\\\\$'         ,
-    'Dart'               =>     '\\\\$'         ,
-    'Expect'             =>     '\\\\$'         ,
-    'Go'                 =>     '\\\\$'         ,
-    'Java'               =>     '\\\\$'         ,
-    'Javascript'         =>     '\\\\$'         ,
-    'Lua'                =>     '\\\\$'         ,
-    'make'               =>     '\\\\$'         ,
-    'MATLAB'             =>     '\.\.\.\s*$'    ,
-    'Objective C'        =>     '\\\\$'         ,
-    'Objective C++'      =>     '\\\\$'         ,
-    'Ocaml'              =>     '\\\\$'         ,
-    'Octave'             =>     '\.\.\.\s*$'    ,
-    'Patran Command Language'=> '\\\\$'         ,
-    'Python'             =>     '\\\\$'         ,
-    'Ruby'               =>     '\\\\$'         ,
-    'sed'                =>     '\\\\$'         ,
-    'Bourne Again Shell' =>     '\\\\$'         ,
-    'Bourne Shell'       =>     '\\\\$'         ,
-    'C Shell'            =>     '\\\\$'         ,
-    'Kermit'             =>     '\\\\$'         ,
-    'Korn Shell'         =>     '\\\\$'         ,
-    'Tcl/Tk'             =>     '\\\\$'         ,
-    'lex'                =>     '\\\\$'         ,
-    );
-# 1}}}
-%{$rh_Not_Code_Extension}    = (                 # {{{1
-   '1'       => 1,  # Man pages (documentation):
-   '2'       => 1,
-   '3'       => 1,
-   '4'       => 1,
-   '5'       => 1,
-   '6'       => 1,
-   '7'       => 1,
-   '8'       => 1,
-   '9'       => 1,
-   'a'       => 1,  # Static object code.
-   'ad'      => 1,  # X application default resource file.
-   'afm'     => 1,  # font metrics
-   'arc'     => 1,  # arc(1) archive
-   'arj'     => 1,  # arj(1) archive
-   'au'      => 1,  # Audio sound filearj(1) archive
-   'bak'     => 1,  # Backup files - we only want to count the "real" files.
-   'bdf'     => 1,
-   'bmp'     => 1,
-   'bz2'     => 1,  # bzip2(1) compressed file
-   'csv'     => 1,  # comma separated values
-   'desktop' => 1,
-   'dic'     => 1,
-   'doc'     => 1,
-   'elc'     => 1,
-   'eps'     => 1,
-   'fig'     => 1,
-   'gif'     => 1,
-   'gz'      => 1,
-   'hdf'     => 1,  # hierarchical data format
-   'in'      => 1,  # Debatable.
-   'jpg'     => 1,
-   'kdelnk'  => 1,
-   'man'     => 1,
-   'mf'      => 1,
-   'mp3'     => 1,
-   'n'       => 1,
-   'o'       => 1,  # Object code is generated from source code.
-   'pbm'     => 1,
-   'pdf'     => 1,
-   'pfb'     => 1,
-   'png'     => 1,
-   'po'      => 1,
-   'ps'      => 1,  # Postscript is _USUALLY_ generated automatically.
-   'sgm'     => 1,
-   'sgml'    => 1,
-   'so'      => 1,  # Dynamically-loaded object code.
-   'Tag'     => 1,
-   'tex'     => 1,
-   'text'    => 1,
-   'tfm'     => 1,
-   'tgz'     => 1,  # gzipped tarball
-   'tiff'    => 1,
-   'txt'     => 1, 
-   'vf'      => 1,
-   'wav'     => 1,
-   'xbm'     => 1,
-   'xpm'     => 1,
-   'Y'       => 1,  # file compressed with "Yabba"
-   'Z'       => 1,  # file compressed with "compress"
-   'zip'     => 1,  # zip archive
-); # 1}}}
-%{$rh_Not_Code_Filename}     = (                 # {{{1
-   'AUTHORS'     => 1,
-   'BUGS'        => 1,
-   'BUGS'        => 1,
-   'Changelog'   => 1,
-   'ChangeLog'   => 1,
-   'ChangeLog'   => 1,
-   'Changes'     => 1,
-   'CHANGES'     => 1,
-   'COPYING'     => 1,
-   'COPYING'     => 1,
-   '.cvsignore'  => 1,
-   'Entries'     => 1,
-   'FAQ'         => 1,
-   'iconfig.h'   => 1, # Skip "iconfig.h" files; they're used in Imakefiles.
-   'INSTALL'     => 1,
-   'MAINTAINERS' => 1,
-   'MD5SUMS'     => 1,
-   'NEWS'        => 1,
-   'readme'      => 1,
-   'Readme'      => 1,
-   'README'      => 1,
-   'README.tk'   => 1, # used in kdemultimedia, it's confusing.
-   'Repository'  => 1,
-   'Root'        => 1, # CVS
-   'TODO'        => 1,
-);
-# 1}}}
-%{$rh_Scale_Factor}          = (                 # {{{1
-    '1032/af'                      =>   5.00,
-    '1st generation default'       =>   0.25,
-    '2nd generation default'       =>   0.75,
-    '3rd generation default'       =>   1.00,
-    '4th generation default'       =>   4.00,
-    '5th generation default'       =>  16.00,
-    'aas macro'                    =>   0.88,
-    'abap/4'                       =>   5.00,
-    'ABAP'                         =>   5.00,
-    'accel'                        =>   4.21,
-    'access'                       =>   2.11,
-    'ActionScript'                 =>   1.36,
-    'actor'                        =>   3.81,
-    'acumen'                       =>   2.86,
-    'Ada'                          =>   0.52,
-    'Ada 83'                       =>   1.13,
-    'Ada 95'                       =>   1.63,
-    'adr/dl'                       =>   2.00,
-    'adr/ideal/pdl'                =>   4.00,
-    'ads/batch'                    =>   4.00,
-    'ads/online'                   =>   4.00,
-    'ADSO/IDSM'                    =>   3.00,
-    'advantage'                    =>   2.11,
-    'ai shell default'             =>   1.63,
-    'ai shells'                    =>   1.63,
-    'algol 68'                     =>   0.75,
-    'algol w'                      =>   0.75,
-    'ambush'                       =>   2.50,
-    'aml'                          =>   1.63,
-    'AMPLE'                        =>   2.00,
-    'amppl ii'                     =>   1.25,
-    'ansi basic'                   =>   1.25,
-    'ansi cobol 74'                =>   0.75,
-    'ansi cobol 85'                =>   0.88,
-    'SQL'                          =>   6.15,
-    'SQL Stored Procedure'         =>   6.15,
-    'SQL Data'                     =>   1.00,
-    'answer/db'                    =>   6.15,
-    'apl 360/370'                  =>   2.50,
-    'apl default'                  =>   2.50,
-    'apl*plus'                     =>   2.50,
-    'applesoft basic'              =>   0.63,
-    'application builder'          =>   4.00,
-    'application manager'          =>   2.22,
-    'aps'                          =>   0.96,
-    'aps'                          =>   4.71,
-    'apt'                          =>   1.13,
-    'aptools'                      =>   4.00,
-    'arc'                          =>   1.63,
-    'ariel'                        =>   0.75,
-    'arity'                        =>   1.63,
-    'arity prolog'                 =>   1.25,
-    'art'                          =>   1.63,
-    'art enterprise'               =>   1.74,
-    'artemis'                      =>   2.00,
-    'artim'                        =>   1.74,
-    'as/set'                       =>   4.21,
-    'asi/inquiry'                  =>   6.15,
-    'ask windows'                  =>   1.74,
-'asa'                         =>   1.29,
-'ASP'                         =>   1.29,
-'ASP.Net'                     =>   1.29,
-'aspx'                        =>   1.29,
-#'resx'                        =>   1.29,
-'asax'                        =>   1.29,
-'ascx'                        =>   1.29,
-'asmx'                        =>   1.29,
-'config'                      =>   1.29,
-'webinfo'                     =>   1.29,
-'CCS'                         =>   5.33,
-
-#   'assembler (basic)'            =>   0.25,
-    'Assembly'                     =>   0.25,
-
-    'Assembly (macro)'             =>   0.51,
-    'associative default'          =>   1.25,
-    'autocoder'                    =>   0.25,
-    'awk'                          =>   3.81,
-    'aztec c'                      =>   0.63,
-    'balm'                         =>   0.75,
-    'base sas'                     =>   1.51,
-    'basic'                        =>   0.75,
-    'basic a'                      =>   0.63,
-#   'basic assembly'               =>   0.25,
-    'bc'                           =>   1.50,
-    'berkeley pascal'              =>   0.88,
-    'better basic'                 =>   0.88,
-    'bliss'                        =>   0.75,
-    'bmsgen'                       =>   2.22,
-    'boeingcalc'                   =>  13.33,
-    'bteq'                         =>   6.15,
-
-    'C'                            =>   0.77,
-
-    'c set 2'                      =>   0.88,
-
-    'C#'                           =>   1.36,
-
-    'C++'                          =>   1.51,
-
-    'c86plus'                      =>   0.63,
-    'cadbfast'                     =>   2.00,
-    'caearl'                       =>   2.86,
-    'cast'                         =>   1.63,
-    'cbasic'                       =>   0.88,
-    'cdadl'                        =>   4.00,
-    'cellsim'                      =>   1.74,
-'ColdFusion'               =>   4.00,
-    'chili'                        =>   0.75,
-    'chill'                        =>   0.75,
-    'cics'                         =>   1.74,
-    'clarion'                      =>   1.38,
-    'clascal'                      =>   1.00,
-    'cli'                          =>   2.50,
-    'clipper'                      =>   2.05,
-    'clipper db'                   =>   2.00,
-    'clos'                         =>   3.81,
-    'clout'                        =>   2.00,
-    'CMake'                        =>   1.00,
-    'cms2'                         =>   0.75,
-    'cmsgen'                       =>   4.21,
-    'COBOL'                        =>   1.04,
-    'COBOL ii'                     =>   0.75,
-    'COBOL/400'                    =>   0.88,
-    'cobra'                        =>   4.00,
-    'codecenter'                   =>   2.22,
-    'cofac'                        =>   2.22,
-    'cogen'                        =>   2.22,
-    'cognos'                       =>   2.22,
-    'cogo'                         =>   1.13,
-    'comal'                        =>   1.00,
-    'comit ii'                     =>   1.25,
-    'common lisp'                  =>   1.25,
-    'concurrent pascal'            =>   1.00,
-    'conniver'                     =>   1.25,
-    'cool:gen/ief'                 =>   2.58,
-    'coral 66'                     =>   0.75,
-    'corvet'                       =>   4.21,
-    'corvision'                    =>   5.33,
-    'cpl'                          =>   0.50,
-    'Crystal Reports'              =>   4.00,
-    'csl'                          =>   1.63,
-    'csp'                          =>   1.51,
-    'cssl'                         =>   1.74,
-    
-'CSS' => 1.0,
-    
-    'culprit'                      =>   1.57,
-    'cxpert'                       =>   1.63,
-    'cygnet'                       =>   4.21,
-    'D'                            =>   1.70,
-    'DAL'                          =>   1.50,
-    'Dart'                         =>   2.00,
-    'data base default'            =>   2.00,
-    'dataflex'                     =>   2.00,
-    'datatrieve'                   =>   4.00,
-    'dbase iii'                    =>   2.00,
-    'dbase iv'                     =>   1.54,
-    'dcl'                          =>   0.38,
-    'decision support default'     =>   2.22,
-    'decrally'                     =>   2.00,
-    'delphi'                       =>   2.76,
-    'dl/1'                         =>   2.00,
-    'NASTRAN DMAP'                 =>   2.35,
-    'dna4'                         =>   4.21,
-    'DOS Batch'                    =>   0.63,
-    'dsp assembly'                 =>   0.50,
-    'dtabl'                        =>   1.74,
-    'dtipt'                        =>   1.74,
-    'dyana'                        =>   1.13,
-    'dynamoiii'                    =>   1.74,
-    'easel'                        =>   2.76,
-    'easy'                         =>   1.63,
-    'easytrieve+'                  =>   2.35,
-    'eclipse'                      =>   1.63,
-    'eda/sql'                      =>   6.67,
-    'edscheme 3.4'                 =>   1.51,
-    'eiffel'                       =>   3.81,
-    'enform'                       =>   1.74,
-    'englishbased default'         =>   1.51,
-    'ensemble'                     =>   2.76,
-    'epos'                         =>   4.00,
-    'Erlang'                       =>   2.11,
-    'esf'                          =>   2.00,
-    'espadvisor'                   =>   1.63,
-    'espl/i'                       =>   1.13,
-    'euclid'                       =>   0.75,
-    'excel'                        =>   1.74,
-    'excel 12'                     =>  13.33,
-    'excel 34'                     =>  13.33,
-    'excel 5'                      =>  13.33,
-    'express'                      =>   2.22,
-    'exsys'                        =>   1.63,
-    'extended common lisp'         =>   1.43,
-    'eznomad'                      =>   2.22,
-    'facets'                       =>   4.00,
-    'factorylink iv'               =>   2.76,
-    'fame'                         =>   2.22,
-    'filemaker pro'                =>   2.22,
-    'flavors'                      =>   2.76,
-    'flex'                         =>   1.74,
-    'flexgen'                      =>   2.76,
-    'Focus'                        =>   1.90,
-    'foil'                         =>   1.51,
-    'forte'                        =>   4.44,
-    'forth'                        =>   1.25,
-    'Fortran 66'                   =>   0.63,
-    'Fortran 77'                   =>   0.75,
-    'Fortran 90'                   =>   1.00,
-    'Fortran 95'                   =>   1.13,
-    'Fortran II'                   =>   0.63,
-    'foundation'                   =>   2.76,
-    'foxpro'                       =>   2.29,
-    'foxpro 1'                     =>   2.00,
-    'foxpro 2.5'                   =>   2.35,
-    'framework'                    =>  13.33,
-    'g2'                           =>   1.63,
-    'gamma'                        =>   5.00,
-    'genascript'                   =>   2.96,
-    'gener/ol'                     =>   6.15,
-    'genexus'                      =>   5.33,
-    'genifer'                      =>   4.21,
-    'geode 2.0'                    =>   5.00,
-    'gfa basic'                    =>   2.35,
-    'gml'                          =>   1.74,
-    'golden common lisp'           =>   1.25,
-    'gpss'                         =>   1.74,
-    'guest'                        =>   2.86,
-    'guru'                         =>   1.63,
-    'Go'                           =>   2.50,
-    'Groovy'                       =>   4.10,
-    'gw basic'                     =>   0.82,
-    'Haskell'                      =>   2.11,
-    'high c'                       =>   0.63,
-    'hlevel'                       =>   1.38,
-    'hp basic'                     =>   0.63,
-
-'HTML'          => 1.90 ,
-'XML'           => 1.90 ,
-'MXML'          => 1.90 ,
-'XSLT'          => 1.90 ,
-'DTD'           => 1.90 ,
-'XSD'           => 1.90 ,
-'NAnt scripts'    => 1.90 ,
-'MSBuild scripts' => 1.90 , 
-
-    'HTML 2'                       =>   5.00,
-    'HTML 3'                       =>   5.33,
-    'huron'                        =>   5.00,
-    'ibm adf i'                    =>   4.00,
-    'ibm adf ii'                   =>   4.44,
-    'ibm advanced basic'           =>   0.82,
-    'ibm cics/vs'                  =>   2.00,
-    'ibm compiled basic'           =>   0.88,
-    'ibm vs cobol'                 =>   0.75,
-    'ibm vs cobol ii'              =>   0.88,
-    'ices'                         =>   1.13,
-    'icon'                         =>   1.00,
-    'ideal'                        =>   1.54,
-    'idms'                         =>   2.00,
-    'ief'                          =>   5.71,
-    'ief/cool:gen'                 =>   2.58,
-    'iew'                          =>   5.71,
-    'ifps/plus'                    =>   2.50,
-    'imprs'                        =>   2.00,
-    'informix'                     =>   2.58,
-    'ingres'                       =>   2.00,
-    'inquire'                      =>   6.15,
-    'insight2'                     =>   1.63,
-    'install/1'                    =>   5.00,
-    'intellect'                    =>   1.51,
-    'interlisp'                    =>   1.38,
-    'interpreted basic'            =>   0.75,
-    'interpreted c'                =>   0.63,
-    'iqlisp'                       =>   1.38,
-    'iqrp'                         =>   6.15,
-    'j2ee'                         =>   1.60,
-    'janus'                        =>   1.13,
-    'Java'                         =>   1.36,
-'Javascript'                   =>   1.48,
-'JSP'                          =>   1.48,
-    'JCL'                          =>   1.67,
-    'joss'                         =>   0.75,
-    'jovial'                       =>   0.75,
-    'jsp'                          =>   1.36,
-    'kappa'                        =>   2.00,
-    'kbms'                         =>   1.63,
-    'kcl'                          =>   1.25,
-    'kee'                          =>   1.63,
-    'keyplus'                      =>   2.00,
-    'kl'                           =>   1.25,
-    'klo'                          =>   1.25,
-    'knowol'                       =>   1.63,
-    'krl'                          =>   1.38,
-    'Kermit'                       =>   2.00,
-    'Korn Shell'                   =>   3.81,
-    'ladder logic'                 =>   2.22,
-    'lambit/l'                     =>   1.25,
-    'lattice c'                    =>   0.63,
-    'liana'                        =>   0.63,
-    'lilith'                       =>   1.13,
-    'linc ii'                      =>   5.71,
-    'Lisp'                         =>   1.25,
-    'LiveLink OScript'             =>   3.5 ,
-    'loglisp'                      =>   1.38,
-    'loops'                        =>   3.81,
-    'lotus 123 dos'                =>  13.33,
-    'lotus macros'                 =>   0.75,
-    'lotus notes'                  =>   3.64,
-    'lucid 3d'                     =>  13.33,
-    'lyric'                        =>   1.51,
-    'm4'                           =>   1.00,
-    'm'                            =>   5.00,
-    'macforth'                     =>   1.25,
-    'mach1'                        =>   2.00,
-    'machine language'             =>   0.13,
-    'maestro'                      =>   5.00,
-    'magec'                        =>   5.00,
-    'magik'                        =>   3.81,
-    'Lake'                         =>   3.81,
-    'make'                         =>   2.50,
-    'mantis'                       =>   2.96,
-    'mapper'                       =>   0.99,
-    'mark iv'                      =>   2.00,
-    'mark v'                       =>   2.22,
-    'mathcad'                      =>  16.00,
-    'mdl'                          =>   2.22,
-    'mentor'                       =>   1.51,
-    'mesa'                         =>   0.75,
-    'microfocus cobol'             =>   1.00,
-    'microforth'                   =>   1.25,
-    'microsoft c'                  =>   0.63,
-    'microstep'                    =>   4.00,
-    'miranda'                      =>   2.00,
-    'model 204'                    =>   2.11,
-    'modula 2'                     =>   1.00,
-    'mosaic'                       =>  13.33,
-    # 'ms c ++ v. 7'                 =>   1.51,
-    'ms compiled basic'            =>   0.88,
-    'msl'                          =>   1.25,
-    'mulisp'                       =>   1.25,
-    'MUMPS'                        =>   4.21,
-    'Nastran'                      =>   1.13,
-    'natural'                      =>   1.54,
-    'natural 1'                    =>   1.51,
-    'natural 2'                    =>   1.74,
-    'natural construct'            =>   3.20,
-    'natural language'             =>   0.03,
-    'netron/cap'                   =>   4.21,
-    'nexpert'                      =>   1.63,
-    'nial'                         =>   1.63,
-    'nomad2'                       =>   2.00,
-    'nonprocedural default'        =>   2.22,
-    'notes vip'                    =>   2.22,
-    'nroff'                        =>   1.51,
-    'object assembler'             =>   1.25,
-    'object lisp'                  =>   2.76,
-    'object logo'                  =>   2.76,
-    'object pascal'                =>   2.76,
-    'object star'                  =>   5.00,
-    'Objective C'                  =>   2.96,
-    'Objective C++'                =>   2.96,
-    'objectoriented default'       =>   2.76,
-    'objectview'                   =>   3.20,
-    'Ocaml'                        =>   3.00,
-    'ogl'                          =>   1.00,
-    'omnis 7'                      =>   2.00,
-    'oodl'                         =>   2.76,
-    'ops'                          =>   1.74,
-    'ops5'                         =>   1.38,
-    'oracle'                       =>   2.76,
-    'Oracle Reports'               =>   2.76,
-    'Oracle Forms'                 =>   2.67,
-    'Oracle Developer/2000'        =>   3.48,
-    'oscar'                        =>   0.75,
-    'pacbase'                      =>   1.67,
-    'pace'                         =>   2.00,
-    'paradox/pal'                  =>   2.22,
-    'Pascal'                       =>   0.88,
-    'Patran Command Language'      =>   2.50,
-    'pc focus'                     =>   2.22,
-    'pdl millenium'                =>   3.81,
-    'pdp11 ade'                    =>   1.51,
-    'peoplesoft'                   =>   2.50,
-    'Perl'                         =>   4.00,
-    'persistance object builder'   =>   3.81,
-    'pilot'                        =>   1.51,
-    'pl/1'                         =>   1.38,
-    'pl/m'                         =>   1.13,
-    'pl/s'                         =>   0.88,
-    'pl/sql'                       =>   2.58,
-    'planit'                       =>   1.51,
-    'planner'                      =>   1.25,
-    'planperfect 1'                =>  11.43,
-    'plato'                        =>   1.51,
-    'polyforth'                    =>   1.25,
-    'pop'                          =>   1.38,
-    'poplog'                       =>   1.38,
-    'power basic'                  =>   1.63,
-    'powerbuilder'                 =>   3.33,
-    'powerhouse'                   =>   5.71,
-    'ppl (plus)'                   =>   2.00,
-    'problemoriented default'      =>   1.13,
-    'proc'                         =>   2.96,
-    'procedural default'           =>   0.75,
-    'professional pascal'          =>   0.88,
-    'program generator default'    =>   5.00,
-    'progress v4'                  =>   2.22,
-    'proiv'                        =>   1.38,
-    'prolog'                       =>   1.25,
-    'prose'                        =>   0.75,
-    'proteus'                      =>   0.75,
-    'qbasic'                       =>   1.38,
-    'qbe'                          =>   6.15,
-    'qmf'                          =>   5.33,
-    'qnial'                        =>   1.63,
-    'quattro'                      =>  13.33,
-    'quattro pro'                  =>  13.33,
-    'query default'                =>   6.15,
-    'quick basic 1'                =>   1.25,
-    'quick basic 2'                =>   1.31,
-    'quick basic 3'                =>   1.38,
-    'quick c'                      =>   0.63,
-    'quickbuild'                   =>   2.86,
-    'quiz'                         =>   5.33,
-    'rally'                        =>   2.00,
-    'ramis ii'                     =>   2.00,
-    'rapidgen'                     =>   2.86,
-    'ratfor'                       =>   0.88,
-    'rdb'                          =>   2.00,
-    'realia'                       =>   1.74,
-    'realizer 1.0'                 =>   2.00,
-    'realizer 2.0'                 =>   2.22,
-    'relate/3000'                  =>   2.00,
-    'reuse default'                =>  16.00,
-    'Rexx'                         =>   1.19,
-    'Rexx (mvs)'                   =>   1.00,
-    'Rexx (os/2)'                  =>   1.74,
-    'rm basic'                     =>   0.88,
-    'rm cobol'                     =>   0.75,
-    'rm fortran'                   =>   0.75,
-    'rpg i'                        =>   1.00,
-    'rpg ii'                       =>   1.63,
-    'rpg iii'                      =>   1.63,
-    'rtexpert 1.4'                 =>   1.38,
-    'sabretalk'                    =>   0.90,
-    'sail'                         =>   0.75,
-    'sapiens'                      =>   5.00,
-    'sas'                          =>   1.95,
-    'savvy'                        =>   6.15,
-    'sbasic'                       =>   0.88,
-    'Scala'                        =>   4.10,
-    'sceptre'                      =>   1.13,
-    'scheme'                       =>   1.51,
-    'screen painter default'       =>  13.33,
-    'sequal'                       =>   6.67,
-    'Bourne Shell'                 =>   3.81,
-    'Bourne Again Shell'           =>   3.81,
-    'ksh'                          =>   3.81,
-    'C Shell'                      =>   3.81,
-    'siebel tools '                =>   6.15,
-    'simplan'                      =>   2.22,
-    'simscript'                    =>   1.74,
-    'simula'                       =>   1.74,
-    'simula 67'                    =>   1.74,
-    'simulation default'           =>   1.74,
-    'SKILL'                        =>   2.00,
-    'SKILL++'                      =>   2.00,
-    'slogan'                       =>   0.98,
-    'smalltalk'                    =>   2.50,
-    'smalltalk 286'                =>   3.81,
-    'smalltalk 80'                 =>   3.81,
-    'smalltalk/v'                  =>   3.81,
-    'Smarty'                       =>   3.50,
-    'snap'                         =>   1.00,
-    'snobol24'                     =>   0.63,
-    'softscreen'                   =>   5.71,
-    'Softbridge Basic'             =>   2.76,
-    'solo'                         =>   1.38,
-    'speakeasy'                    =>   2.22,
-    'spinnaker ppl'                =>   2.22,
-    'splus'                        =>   2.50,
-    'spreadsheet default'          =>  13.33,
-    'sps'                          =>   0.25,
-    'spss'                         =>   2.50,
-    'SQL'                          =>   2.29,
-    'sqlwindows'                   =>   6.67,
-    'statistical default'          =>   2.50,
-    'strategem'                    =>   2.22,
-    'stress'                       =>   1.13,
-    'strongly typed default'       =>   0.88,
-    'style'                        =>   1.74,
-    'superbase 1.3'                =>   2.22,
-    'surpass'                      =>  13.33,
-    'sybase'                       =>   2.00,
-    'symantec c++'                 =>   2.76,
-    'symbolang'                    =>   1.25,
-    'synchroworks'                 =>   4.44,
-    'synon/2e'                     =>   4.21,
-    'systemw'                      =>   2.22,
-    'tandem access language'       =>   0.88,
-    'Tcl/Tk'                       =>   4.00,
-    'Teamcenter def'               =>   1.00,
-    'Teamcenter met'               =>   1.00,
-    'Teamcenter mth'               =>   1.00,
-    'telon'                        =>   5.00,
-    'tessaract'                    =>   2.00,
-    'the twin'                     =>  13.33,
-    'themis'                       =>   6.15,
-    'tiief'                        =>   5.71,
-    'topspeed c++'                 =>   2.76,
-    'transform'                    =>   5.33,
-    'translisp plus'               =>   1.43,
-    'treet'                        =>   1.25,
-    'treetran'                     =>   1.25,
-    'trs80 basic'                  =>   0.63,
-    'true basic'                   =>   1.25,
-    'turbo c'                      =>   0.63,
-    # 'turbo c++'                    =>   1.51,
-    'turbo expert'                 =>   1.63,
-    'turbo pascal >5'              =>   1.63,
-    'turbo pascal 14'              =>   1.00,
-    'turbo pascal 45'              =>   1.13,
-    'turbo prolog'                 =>   1.00,
-    'turing'                       =>   1.00,
-    'tutor'                        =>   1.51,
-    'twaice'                       =>   1.63,
-    'ucsd pascal'                  =>   0.88,
-    'ufo/ims'                      =>   2.22,
-    'uhelp'                        =>   2.50,
-    'uniface'                      =>   5.00,
-    # 'unix shell scripts'           =>   3.81,
-    'vax acms'                     =>   1.38,
-    'vax ade'                      =>   2.00,
-    'vbscript'                     =>   2.35,
-    'vectran'                      =>   0.75,
-    'VHDL'                         =>   4.21,
-    'vim script'                   =>   3.00,
-    'visible c'                    =>   1.63,
-    'visible cobol'                =>   2.00,
-    'visicalc 1'                   =>   8.89,
-    'visual 4.0'                   =>   2.76,
-    'visual basic'                 =>   1.90,
-    'visual basic 1'               =>   1.74,
-    'visual basic 2'               =>   1.86,
-    'visual basic 3'               =>   2.00,
-    'visual basic 4'               =>   2.22,
-    'visual basic 5'               =>   2.76,
-    'Visual Basic'                 =>   2.76,
-    'visual basic dos'             =>   2.00,
-    'visual c++'                   =>   2.35,
-    'visual cobol'                 =>   4.00,
-    'visual objects'               =>   5.00,
-    'visualage'                    =>   3.81,
-    'visualgen'                    =>   4.44,
-    'vpf'                          =>   0.84,
-    'vsrexx'                       =>   2.50,
-    'vulcan'                       =>   1.25,
-    'vz programmer'                =>   2.22,
-    'warp x'                       =>   2.00,
-    'watcom c'                     =>   0.63,
-    'watcom c/386'                 =>   0.63,
-    'waterloo c'                   =>   0.63,
-    'waterloo pascal'              =>   0.88,
-    'watfiv'                       =>   0.94,
-    'watfor'                       =>   0.88,
-    'web scripts'                  =>   5.33,
-    'whip'                         =>   0.88,
-    'wizard'                       =>   2.86,
-    'xlisp'                        =>   1.25,
-    'XAML'                         =>   1.90,
-    'yacc'                         =>   1.51,
-    'yacc++'                       =>   1.51,
-    'YAML'                         =>   0.90,
-    'zbasic'                       =>   0.88,
-    'zim'                          =>   4.21,
-    'zlisp'                        =>   1.25,
-
-'Expect'  => 2.00,
-'C/C++ Header'  => 1.00, 
-'inc'     => 1.00,
-'lex'     => 1.00,
-'MATLAB'  => 4.00,
-'IDL'     => 3.80,
-'Octave'  => 4.00,
-'ML'      => 3.00,
-'Modula3' => 2.00,
-'PHP'     => 3.50,
-'Python'  => 4.20,
-'Cython'  => 3.80,
-'Ruby'    => 4.20,
-'Ruby HTML' => 4.00,
-'sed'     => 4.00,
-'Lua'     => 4.00,
-);
-# 1}}}
-%{$rh_Known_Binary_Archives} = (                 # {{{1
-            '.tar'     => 1 ,
-            '.tar.Z'   => 1 ,
-            '.tar.gz'  => 1 ,
-            '.tar.bz2' => 1 ,
-            '.zip'     => 1 ,
-            '.Zip'     => 1 ,
-            '.ZIP'     => 1 ,
-            '.ear'     => 1 ,  # Java
-            '.war'     => 1 ,  # contained within .ear
-            );
-# 1}}}
-} # end sub set_constants()
-sub Install_Regexp_Common {                  # {{{1
-    # Installs portions of Damian Conway's & Abigail's Regexp::Common
-    # module, v2.120, into a temporary directory for the duration of
-    # this run.
-
-    my %Regexp_Common_Contents = ();
-$Regexp_Common_Contents{'Common'} = <<'EOCommon'; # {{{2
-package Regexp::Common;
-
-use 5.00473;
-use strict;
-
-local $^W = 1;
-
-use vars qw /$VERSION %RE %sub_interface $AUTOLOAD/;
-
-($VERSION) = q $Revision: 2.120 $ =~ /([\d.]+)/;
-
-
-sub _croak {
-    require Carp;
-    goto &Carp::croak;
-}
-
-sub _carp {
-    require Carp;
-    goto &Carp::carp;
-}
-
-sub new {
-    my ($class, @data) = @_;
-    my %self;
-    tie %self, $class, @data;
-    return \%self;
-}
-
-sub TIEHASH {
-    my ($class, @data) = @_;
-    bless \@data, $class;
-}
-
-sub FETCH {
-    my ($self, $extra) = @_;
-    return bless ref($self)->new(@$self, $extra), ref($self);
-}
-
-# Modification for cloc:  only need a few modules from Regexp::Common.
-my %imports = map {$_ => "Regexp::Common::$_"}
-              qw /balanced comment delimited /;
-#my %imports = map {$_ => "Regexp::Common::$_"}
-#              qw /balanced CC     comment   delimited lingua list
-#                  net      number profanity SEN       URI    whitespace
-#                  zip/;
-
-sub import {
-    shift;  # Shift off the class.
-    tie %RE, __PACKAGE__;
-    {
-        no strict 'refs';
-        *{caller() . "::RE"} = \%RE;
-    }
-
-    my $saw_import;
-    my $no_defaults;
-    my %exclude;
-    foreach my $entry (grep {!/^RE_/} @_) {
-        if ($entry eq 'pattern') {
-            no strict 'refs';
-            *{caller() . "::pattern"} = \&pattern;
-            next;
-        }
-        # This used to prevent $; from being set. We still recognize it,
-        # but we won't do anything.
-        if ($entry eq 'clean') {
-            next;
-        }
-        if ($entry eq 'no_defaults') {
-            $no_defaults ++;
-            next;
-        }
-        if (my $module = $imports {$entry}) {
-            $saw_import ++;
-            eval "require $module;";
-            die $@ if $@;
-            next;
-        }
-        if ($entry =~ /^!(.*)/ && $imports {$1}) {
-            $exclude {$1} ++;
-            next;
-        }
-        # As a last resort, try to load the argument.
-        my $module = $entry =~ /^Regexp::Common/
-                            ? $entry
-                            : "Regexp::Common::" . $entry;
-        eval "require $module;";
-        die $@ if $@;
-    }
-
-    unless ($saw_import || $no_defaults) {
-        foreach my $module (values %imports) {
-            next if $exclude {$module};
-            eval "require $module;";
-            die $@ if $@;
-        }
-    }
-
-    my %exported;
-    foreach my $entry (grep {/^RE_/} @_) {
-        if ($entry =~ /^RE_(\w+_)?ALL$/) {
-            my $m  = defined $1 ? $1 : "";
-            my $re = qr /^RE_${m}.*$/;
-            while (my ($sub, $interface) = each %sub_interface) {
-                next if $exported {$sub};
-                next unless $sub =~ /$re/;
-                {
-                    no strict 'refs';
-                    *{caller() . "::$sub"} = $interface;
-                }
-                $exported {$sub} ++;
-            }
-        }
-        else {
-            next if $exported {$entry};
-            _croak "Can't export unknown subroutine &$entry"
-                unless $sub_interface {$entry};
-            {
-                no strict 'refs';
-                *{caller() . "::$entry"} = $sub_interface {$entry};
-            }
-            $exported {$entry} ++;
-        }
-    }
-}
-
-sub AUTOLOAD { _croak "Can't $AUTOLOAD" }
-
-sub DESTROY {}
-
-my %cache;
-
-my $fpat = qr/^(-\w+)/;
-
-sub _decache {
-        my @args = @{tied %{$_[0]}};
-        my @nonflags = grep {!/$fpat/} @args;
-        my $cache = get_cache(@nonflags);
-        _croak "Can't create unknown regex: \$RE{"
-            . join("}{",@args) . "}"
-                unless exists $cache->{__VAL__};
-        _croak "Perl $] does not support the pattern "
-            . "\$RE{" . join("}{",@args)
-            . "}.\nYou need Perl $cache->{__VAL__}{version} or later"
-                unless ($cache->{__VAL__}{version}||0) <= $];
-        my %flags = ( %{$cache->{__VAL__}{default}},
-                      map { /$fpat\Q$;\E(.*)/ ? ($1 => $2)
-                          : /$fpat/           ? ($1 => undef)
-                          :                     ()
-                          } @args);
-        $cache->{__VAL__}->_clone_with(\@args, \%flags);
-}
-
-use overload q{""} => \&_decache;
-
-
-sub get_cache {
-        my $cache = \%cache;
-        foreach (@_) {
-                $cache = $cache->{$_}
-                      || ($cache->{$_} = {});
-        }
-        return $cache;
-}
-
-sub croak_version {
-        my ($entry, @args) = @_;
-}
-
-sub pattern {
-        my %spec = @_;
-        _croak 'pattern() requires argument: name => [ @list ]'
-                unless $spec{name} && ref $spec{name} eq 'ARRAY';
-        _croak 'pattern() requires argument: create => $sub_ref_or_string'
-                unless $spec{create};
-
-        if (ref $spec{create} ne "CODE") {
-                my $fixed_str = "$spec{create}";
-                $spec{create} = sub { $fixed_str }
-        }
-
-        my @nonflags;
-        my %default;
-        foreach ( @{$spec{name}} ) {
-                if (/$fpat=(.*)/) {
-                        $default{$1} = $2;
-                }
-                elsif (/$fpat\s*$/) {
-                        $default{$1} = undef;
-                }
-                else {
-                        push @nonflags, $_;
-                }
-        }
-
-        my $entry = get_cache(@nonflags);
-
-        if ($entry->{__VAL__}) {
-                _carp "Overriding \$RE{"
-                   . join("}{",@nonflags)
-                   . "}";
-        }
-
-        $entry->{__VAL__} = bless {
-                                create  => $spec{create},
-                                match   => $spec{match} || \&generic_match,
-                                subs    => $spec{subs}  || \&generic_subs,
-                                version => $spec{version},
-                                default => \%default,
-                            }, 'Regexp::Common::Entry';
-
-        foreach (@nonflags) {s/\W/X/g}
-        my $subname = "RE_" . join ("_", @nonflags);
-        $sub_interface{$subname} = sub {
-                push @_ => undef if @_ % 2;
-                my %flags = @_;
-                my $pat = $spec{create}->($entry->{__VAL__},
-                               {%default, %flags}, \@nonflags);
-                if (exists $flags{-keep}) { $pat =~ s/\Q(?k:/(/g; }
-                else { $pat =~ s/\Q(?k:/(?:/g; }
-                return exists $flags {-i} ? qr /(?i:$pat)/ : qr/$pat/;
-        };
-
-        return 1;
-}
-
-sub generic_match {$_ [1] =~  /$_[0]/}
-sub generic_subs  {$_ [1] =~ s/$_[0]/$_[2]/}
-
-sub matches {
-        my ($self, $str) = @_;
-        my $entry = $self -> _decache;
-        $entry -> {match} -> ($entry, $str);
-}
-
-sub subs {
-        my ($self, $str, $newstr) = @_;
-        my $entry = $self -> _decache;
-        $entry -> {subs} -> ($entry, $str, $newstr);
-        return $str;
-}
-
-
-package Regexp::Common::Entry;
-# use Carp;
-
-local $^W = 1;
-
-use overload
-    q{""} => sub {
-        my ($self) = @_;
-        my $pat = $self->{create}->($self, $self->{flags}, $self->{args});
-        if (exists $self->{flags}{-keep}) {
-            $pat =~ s/\Q(?k:/(/g;
-        }
-        else {
-            $pat =~ s/\Q(?k:/(?:/g;
-        }
-        if (exists $self->{flags}{-i})   { $pat = "(?i)$pat" }
-        return $pat;
-    };
-
-sub _clone_with {
-    my ($self, $args, $flags) = @_;
-    bless { %$self, args=>$args, flags=>$flags }, ref $self;
-}
-# 
-#    Copyright (c) 2001 - 2005, Damian Conway and Abigail. All Rights
-#  Reserved. This module is free software. It may be used, redistributed
-#      and/or modified under the terms of the Perl Artistic License
-#            (see http://www.perl.com/perl/misc/Artistic.html)
-EOCommon
-# 2}}}
-$Regexp_Common_Contents{'Common/comment'} = <<'EOC';   # {{{2
-# $Id: comment.pm,v 2.116 2005/03/16 00:00:02 abigail Exp $
-
-package Regexp::Common::comment;
-
-use strict;
-local $^W = 1;
-
-use Regexp::Common qw /pattern clean no_defaults/;
-use vars qw /$VERSION/;
-
-($VERSION) = q $Revision: 2.116 $ =~ /[\d.]+/g;
-
-my @generic = (
-    {languages => [qw /ABC Forth/],
-     to_eol    => ['\\\\']},   # This is for just a *single* backslash.
-
-    {languages => [qw /Ada Alan Eiffel lua/],
-     to_eol    => ['--']},
-
-    {languages => [qw /Advisor/],
-     to_eol    => ['#|//']},
-
-    {languages => [qw /Advsys CQL Lisp LOGO M MUMPS REBOL Scheme
-                       SMITH zonefile/],
-     to_eol    => [';']},
-
-    {languages => ['Algol 60'],
-     from_to   => [[qw /comment ;/]]},
-
-    {languages => [qw {ALPACA B C C-- LPC PL/I}],
-     from_to   => [[qw {/* */}]]},
-
-    {languages => [qw /awk fvwm2 Icon mutt Perl Python QML R Ruby shell Tcl/],
-     to_eol    => ['#']},
-
-    {languages => [[BASIC => 'mvEnterprise']],
-     to_eol    => ['[*!]|REM']},
-
-    {languages => [qw /Befunge-98 Funge-98 Shelta/],
-     id        => [';']},
-
-    {languages => ['beta-Juliet', 'Crystal Report', 'Portia'],
-     to_eol    => ['//']},
-
-    {languages => ['BML'],
-     from_to   => [['<?_c', '_c?>']],
-    },
-
-    {languages => [qw /C++/, 'C#', qw /Cg ECMAScript FPL Java JavaScript/],
-     to_eol    => ['//'],
-     from_to   => [[qw {/* */}]]},
-
-    {languages => [qw /CLU LaTeX slrn TeX/],
-     to_eol    => ['%']},
-
-    {languages => [qw /False/],
-     from_to   => [[qw !{ }!]]},
-
-    {languages => [qw /Fortran/],
-     to_eol    => ['!']},
-
-    {languages => [qw /Haifu/],
-     id        => [',']},
-
-    {languages => [qw /ILLGOL/],
-     to_eol    => ['NB']},
-
-    {languages => [qw /INTERCAL/],
-     to_eol    => [q{(?:(?:PLEASE(?:\s+DO)?|DO)\s+)?(?:NOT|N'T)}]},
-
-    {languages => [qw /J/],
-     to_eol    => ['NB[.]']},
-
-    {languages => [qw /Nickle/],
-     to_eol    => ['#'],
-     from_to   => [[qw {/* */}]]},
-
-    {languages => [qw /Oberon/],
-     from_to   => [[qw /(* *)/]]},
-     
-    {languages => [[qw /Pascal Delphi/], [qw /Pascal Free/], [qw /Pascal GPC/]],
-     to_eol    => ['//'],
-     from_to   => [[qw !{ }!], [qw !(* *)!]]},
-
-    {languages => [[qw /Pascal Workshop/]],
-     id        => [qw /"/],
-     from_to   => [[qw !{ }!], [qw !(* *)!], [qw !/* */!]]},
-
-    {languages => [qw /PEARL/],
-     to_eol    => ['!'],
-     from_to   => [[qw {/* */}]]},
-
-    {languages => [qw /PHP/],
-     to_eol    => ['#', '//'],
-     from_to   => [[qw {/* */}]]},
-
-    {languages => [qw !PL/B!],
-     to_eol    => ['[.;]']},
-
-    {languages => [qw !PL/SQL!],
-     to_eol    => ['--'],
-     from_to   => [[qw {/* */}]]},
-
-    {languages => [qw /Q-BAL/],
-     to_eol    => ['`']},
-
-    {languages => [qw /Smalltalk/],
-     id        => ['"']},
-
-    {languages => [qw /SQL/],
-     to_eol    => ['-{2,}']},
-
-    {languages => [qw /troff/],
-     to_eol    => ['\\\"']},
-
-    {languages => [qw /vi/],
-     to_eol    => ['"']},
-
-    {languages => [qw /*W/],
-     from_to   => [[qw {|| !!}]]},
-);
-
-my @plain_or_nested = (
-   [Caml         =>  undef,       "(*"  => "*)"],
-   [Dylan        =>  "//",        "/*"  => "*/"],
-   [Haskell      =>  "-{2,}",     "{-"  => "-}"],
-   [Hugo         =>  "!(?!\\\\)", "!\\" => "\\!"],
-   [SLIDE        =>  "#",         "(*"  => "*)"],
-);
-
-#
-# Helper subs.
-#
-
-sub combine      {
-    local $_ = join "|", @_;
-    if (@_ > 1) {
-        s/\(\?k:/(?:/g;
-        $_ = "(?k:$_)";
-    }
-    $_
-}
-
-sub to_eol  ($)  {"(?k:(?k:$_[0])(?k:[^\\n]*)(?k:\\n))"}
-sub id      ($)  {"(?k:(?k:$_[0])(?k:[^$_[0]]*)(?k:$_[0]))"}  # One char only!
-sub from_to      {
-    local $^W = 1;
-    my ($begin, $end) = @_;
-
-    my $qb  = quotemeta $begin;
-    my $qe  = quotemeta $end;
-    my $fe  = quotemeta substr $end   => 0, 1;
-    my $te  = quotemeta substr $end   => 1;
-
-    "(?k:(?k:$qb)(?k:(?:[^$fe]+|$fe(?!$te))*)(?k:$qe))";
-}
-
-
-my $count = 0;
-sub nested {
-    local $^W = 1;
-    my ($begin, $end) = @_;
-
-    $count ++;
-    my $r = '(??{$Regexp::Common::comment ['. $count . ']})';
-
-    my $qb  = quotemeta $begin;
-    my $qe  = quotemeta $end;
-    my $fb  = quotemeta substr $begin => 0, 1;
-    my $fe  = quotemeta substr $end   => 0, 1;
-
-    my $tb  = quotemeta substr $begin => 1;
-    my $te  = quotemeta substr $end   => 1;
-
-    use re 'eval';
-
-    my $re;
-    if ($fb eq $fe) {
-        $re = qr /(?:$qb(?:(?>[^$fb]+)|$fb(?!$tb)(?!$te)|$r)*$qe)/;
-    }
-    else {
-        local $"      =  "|";
-        my   @clauses =  "(?>[^$fb$fe]+)";
-        push @clauses => "$fb(?!$tb)" if length $tb;
-        push @clauses => "$fe(?!$te)" if length $te;
-        push @clauses =>  $r;
-        $re           =   qr /(?:$qb(?:@clauses)*$qe)/;
-    }
-
-    $Regexp::Common::comment [$count] = qr/$re/;
-}
-
-#
-# Process data.
-#
-
-foreach my $info (@plain_or_nested) {
-    my ($language, $mark, $begin, $end) = @$info;
-    pattern name    => [comment => $language],
-            create  =>
-                sub {my $re     = nested $begin => $end;
-                     my $prefix = defined $mark ? $mark . "[^\n]*\n|" : "";
-                     exists $_ [1] -> {-keep} ? qr /($prefix$re)/
-                                              : qr  /$prefix$re/
-                },
-            version => 5.006,
-            ;
-}
-
-
-foreach my $group (@generic) {
-    my $pattern = combine +(map {to_eol   $_} @{$group -> {to_eol}}),
-                           (map {from_to @$_} @{$group -> {from_to}}),
-                           (map {id       $_} @{$group -> {id}}),
-                  ;
-    foreach my $language  (@{$group -> {languages}}) {
-        pattern name    => [comment => ref $language ? @$language : $language],
-                create  => $pattern,
-                ;
-    }
-}
-                
-
-    
-#
-# Other languages.
-#
-
-# http://www.pascal-central.com/docs/iso10206.txt
-pattern name    => [qw /comment Pascal/],
-        create  => '(?k:' . '(?k:[{]|[(][*])'
-                          . '(?k:[^}*]*(?:[*][^)][^}*]*)*)'
-                          . '(?k:[}]|[*][)])'
-                          . ')'
-        ;
-
-# http://www.templetons.com/brad/alice/language/
-pattern name    =>  [qw /comment Pascal Alice/],
-        create  =>  '(?k:(?k:[{])(?k:[^}\n]*)(?k:[}]))'
-        ;
-
-
-# http://westein.arb-phys.uni-dortmund.de/~wb/a68s.txt
-pattern name    => [qw (comment), 'Algol 68'],
-        create  => q {(?k:(?:#[^#]*#)|}                           .
-                   q {(?:\bco\b(?:[^c]+|\Bc|\bc(?!o\b))*\bco\b)|} .
-                   q {(?:\bcomment\b(?:[^c]+|\Bc|\bc(?!omment\b))*\bcomment\b))}
-        ;
-
-
-# See rules 91 and 92 of ISO 8879 (SGML).
-# Charles F. Goldfarb: "The SGML Handbook".
-# Oxford: Oxford University Press. 1990. ISBN 0-19-853737-9.
-# Ch. 10.3, pp 390.
-pattern name    => [qw (comment HTML)],
-        create  => q {(?k:(?k:<!)(?k:(?:--(?k:[^-]*(?:-[^-]+)*)--\s*)*)(?k:>))},
-        ;
-
-
-pattern name    => [qw /comment SQL MySQL/],
-        create  => q {(?k:(?:#|-- )[^\n]*\n|} .
-                   q {/\*(?:(?>[^*;"']+)|"[^"]*"|'[^']*'|\*(?!/))*(?:;|\*/))},
-        ;
-
-# Anything that isn't <>[]+-.,
-# http://home.wxs.nl/~faase009/Ha_BF.html
-pattern name    => [qw /comment Brainfuck/],
-        create  => '(?k:[^<>\[\]+\-.,]+)'
-        ;
-
-# Squeak is a variant of Smalltalk-80.
-# http://www.squeak.
-# http://mucow.com/squeak-qref.html
-pattern name    => [qw /comment Squeak/],
-        create  => '(?k:(?k:")(?k:[^"]*(?:""[^"]*)*)(?k:"))'
-        ;
-
-#
-# Scores of less than 5 or above 17....
-# http://www.cliff.biffle.org/esoterica/beatnik.html
-@Regexp::Common::comment::scores = (1,  3,  3,  2,  1,  4,  2,  4,  1,  8,
-                                    5,  1,  3,  1,  1,  3, 10,  1,  1,  1,
-                                    1,  4,  4,  8,  4, 10);
-pattern name    =>  [qw /comment Beatnik/],
-        create  =>  sub {
-            use re 'eval';
-            my ($s, $x);
-            my $re = qr {\b([A-Za-z]+)\b
-                         (?(?{($s, $x) = (0, lc $^N);
-                              $s += $Regexp::Common::comment::scores
-                                    [ord (chop $x) - ord ('a')] while length $x;
-                              $s  >= 5 && $s < 18})XXX|)}x;
-            $re;
-        },
-        version  => 5.008,
-        ;
-
-
-# http://www.cray.com/craydoc/manuals/007-3692-005/html-007-3692-005/
-#  (Goto table of contents/3.3 Source Form)
-# Fortran, in fixed format. Comments start with a C, c or * in the first
-# column, or a ! anywhere, but the sixth column. Then end with a newline.
-pattern name    =>  [qw /comment Fortran fixed/],
-        create  =>  '(?k:(?k:(?:^[Cc*]|(?<!^.....)!))(?k:[^\n]*)(?k:\n))'
-        ;
-
-
-# http://www.csis.ul.ie/cobol/Course/COBOLIntro.htm
-# Traditionally, comments in COBOL were indicated with an asteriks in
-# the seventh column. Modern compilers may be more lenient.
-pattern name    =>  [qw /comment COBOL/],
-        create  =>  '(?<=^......)(?k:(?k:[*])(?k:[^\n]*)(?k:\n))',
-        version =>  '5.008',
-        ;
-
-1;
-#
-#    Copyright (c) 2001 - 2003, Damian Conway. All Rights Reserved.
-#      This module is free software. It may be used, redistributed
-#     and/or modified under the terms of the Perl Artistic License
-#           (see http://www.perl.com/perl/misc/Artistic.html)
-EOC
-# 2}}}
-$Regexp_Common_Contents{'Common/balanced'} = <<'EOB';   # {{{2
-package Regexp::Common::balanced; {
-
-use strict;
-local $^W = 1;
-
-use vars qw /$VERSION/;
-($VERSION) = q $Revision: 2.101 $ =~ /[\d.]+/g;
-
-use Regexp::Common qw /pattern clean no_defaults/;
-
-my %closer = ( '{'=>'}', '('=>')', '['=>']', '<'=>'>' );
-my $count = -1;
-my %cache;
-
-sub nested {
-    local $^W = 1;
-    my ($start, $finish) = @_;
-
-    return $Regexp::Common::balanced [$cache {$start} {$finish}]
-            if exists $cache {$start} {$finish};
-
-    $count ++;
-    my $r = '(??{$Regexp::Common::balanced ['. $count . ']})';
-
-    my @starts   = map {s/\\(.)/$1/g; $_} grep {length}
-                        $start  =~ /([^|\\]+|\\.)+/gs;
-    my @finishes = map {s/\\(.)/$1/g; $_} grep {length}
-                        $finish =~ /([^|\\]+|\\.)+/gs;
-
-    push @finishes => ($finishes [-1]) x (@starts - @finishes);
-
-    my @re;
-    local $" = "|";
-    foreach my $begin (@starts) {
-        my $end = shift @finishes;
-
-        my $qb  = quotemeta $begin;
-        my $qe  = quotemeta $end;
-        my $fb  = quotemeta substr $begin => 0, 1;
-        my $fe  = quotemeta substr $end   => 0, 1;
-
-        my $tb  = quotemeta substr $begin => 1;
-        my $te  = quotemeta substr $end   => 1;
-
-        use re 'eval';
-
-        my $add;
-        if ($fb eq $fe) {
-            push @re =>
-                   qr /(?:$qb(?:(?>[^$fb]+)|$fb(?!$tb)(?!$te)|$r)*$qe)/;
-        }
-        else {
-            my   @clauses =  "(?>[^$fb$fe]+)";
-            push @clauses => "$fb(?!$tb)" if length $tb;
-            push @clauses => "$fe(?!$te)" if length $te;
-            push @clauses =>  $r;
-            push @re      =>  qr /(?:$qb(?:@clauses)*$qe)/;
-        }
-    }
-
-    $cache {$start} {$finish} = $count;
-    $Regexp::Common::balanced [$count] = qr/@re/;
-}
-
-
-pattern name    => [qw /balanced -parens=() -begin= -end=/],
-        create  => sub {
-            my $flag = $_[1];
-            unless (defined $flag -> {-begin} && length $flag -> {-begin} &&
-                    defined $flag -> {-end}   && length $flag -> {-end}) {
-                my @open  = grep {index ($flag->{-parens}, $_) >= 0}
-                             ('[','(','{','<');
-                my @close = map {$closer {$_}} @open;
-                $flag -> {-begin} = join "|" => @open;
-                $flag -> {-end}   = join "|" => @close;
-            }
-            my $pat = nested @$flag {qw /-begin -end/};
-            return exists $flag -> {-keep} ? qr /($pat)/ : $pat;
-        },
-        version => 5.006,
-        ;
-
-}
-
-1;
-#
-#     Copyright (c) 2001 - 2003, Damian Conway. All Rights Reserved.
-#       This module is free software. It may be used, redistributed
-#      and/or modified under the terms of the Perl Artistic License
-#            (see http://www.perl.com/perl/misc/Artistic.html)
-EOB
-# 2}}}
-$Regexp_Common_Contents{'Common/delimited'} = <<'EOD';   # {{{2
-# $Id: delimited.pm,v 2.104 2005/03/16 00:22:45 abigail Exp $
-
-package Regexp::Common::delimited;
-
-use strict;
-local $^W = 1;
-
-use Regexp::Common qw /pattern clean no_defaults/;
-use vars qw /$VERSION/;
-
-($VERSION) = q $Revision: 2.104 $ =~ /[\d.]+/g;
-
-sub gen_delimited {
-
-    my ($dels, $escs) = @_;
-    # return '(?:\S*)' unless $dels =~ /\S/;
-    if (length $escs) {
-        $escs .= substr ($escs, -1) x (length ($dels) - length ($escs));
-    }
-    my @pat = ();
-    my $i;
-    for ($i=0; $i < length $dels; $i++) {
-        my $del = quotemeta substr ($dels, $i, 1);
-        my $esc = length($escs) ? quotemeta substr ($escs, $i, 1) : "";
-        if ($del eq $esc) {
-            push @pat,
-                 "(?k:$del)(?k:[^$del]*(?:(?:$del$del)[^$del]*)*)(?k:$del)";
-        }
-        elsif (length $esc) {
-            push @pat,
-                 "(?k:$del)(?k:[^$esc$del]*(?:$esc.[^$esc$del]*)*)(?k:$del)";
-        }
-        else {
-            push @pat, "(?k:$del)(?k:[^$del]*)(?k:$del)";
-        }
-    }
-    my $pat = join '|', @pat;
-    return "(?k:$pat)";
-}
-
-sub _croak {
-    require Carp;
-    goto &Carp::croak;
-}
-
-pattern name   => [qw( delimited -delim= -esc=\\ )],
-        create => sub {my $flags = $_[1];
-                       _croak 'Must specify delimiter in $RE{delimited}'
-                             unless length $flags->{-delim};
-                       return gen_delimited (@{$flags}{-delim, -esc});
-                  },
-        ;
-
-pattern name   => [qw( quoted -esc=\\ )],
-        create => sub {my $flags = $_[1];
-                       return gen_delimited (q{"'`}, $flags -> {-esc});
-                  },
-        ;
-
-
-1;
-#
-#     Copyright (c) 2001 - 2003, Damian Conway. All Rights Reserved.
-#       This module is free software. It may be used, redistributed
-#      and/or modified under the terms of the Perl Artistic License
-#            (see http://www.perl.com/perl/misc/Artistic.html)
-EOD
-# 2}}}
-    my $problems        = 0;
-    $HAVE_Rexexp_Common = 0;
-    my $dir             = "";
-    if ($opt_sdir) {
-        # write to the user-defined scratch directory
-        $dir = $opt_sdir;
-    } else {
-        # let File::Temp create a suitable temporary directory
-        $dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
-    }
-    print "Using temp dir [$dir] to install Regexp::Common\n" if $opt_v;
-    my $Regexp_dir        = "$dir/Regexp";
-    my $Regexp_Common_dir = "$dir/Regexp/Common";
-    mkdir $Regexp_dir       ;
-    mkdir $Regexp_Common_dir;
-
-    foreach my $module_file (keys %Regexp_Common_Contents) {
-        my $OUT = new IO::File "$dir/Regexp/${module_file}.pm", "w";
-        if (defined $OUT) {
-            print $OUT $Regexp_Common_Contents{$module_file};
-            $OUT->close;
-        } else {
-            warn "Failed to install Regexp::${module_file}.pm\n";
-            $problems = 1;
-        }
-    }
-
-    push @INC, $dir;
-    eval "use Regexp::Common qw /comment RE_comment_HTML balanced/";
-    $HAVE_Rexexp_Common = 1 unless $problems;
-} # 1}}}
-sub Install_Algorithm_Diff {                 # {{{1
-    # Installs Tye McQueen's Algorithm::Diff module, v1.1902, into a 
-    # temporary directory for the duration of this run.
-
-my $Algorithm_Diff_Contents = <<'EOAlgDiff'; # {{{2
-package Algorithm::Diff;
-# Skip to first "=head" line for documentation.
-use strict;
-
-use integer;    # see below in _replaceNextLargerWith() for mod to make
-                # if you don't use this
-use vars qw( $VERSION @EXPORT_OK );
-$VERSION = 1.19_02;
-#          ^ ^^ ^^-- Incremented at will
-#          | \+----- Incremented for non-trivial changes to features
-#          \-------- Incremented for fundamental changes
-require Exporter;
-*import    = \&Exporter::import;
-@EXPORT_OK = qw(
-    prepare LCS LCSidx LCS_length
-    diff sdiff compact_diff
-    traverse_sequences traverse_balanced
-);
-
-# McIlroy-Hunt diff algorithm
-# Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com>
-# by Ned Konz, perl@bike-nomad.com
-# Updates by Tye McQueen, http://perlmonks.org/?node=tye
-
-# Create a hash that maps each element of $aCollection to the set of
-# positions it occupies in $aCollection, restricted to the elements
-# within the range of indexes specified by $start and $end.
-# The fourth parameter is a subroutine reference that will be called to
-# generate a string to use as a key.
-# Additional parameters, if any, will be passed to this subroutine.
-#
-# my $hashRef = _withPositionsOfInInterval( \@array, $start, $end, $keyGen );
-
-sub _withPositionsOfInInterval
-{
-    my $aCollection = shift;    # array ref
-    my $start       = shift;
-    my $end         = shift;
-    my $keyGen      = shift;
-    my %d;
-    my $index;
-    for ( $index = $start ; $index <= $end ; $index++ )
-    {
-        my $element = $aCollection->[$index];
-        my $key = &$keyGen( $element, @_ );
-        if ( exists( $d{$key} ) )
-        {
-            unshift ( @{ $d{$key} }, $index );
-        }
-        else
-        {
-            $d{$key} = [$index];
-        }
-    }
-    return wantarray ? %d : \%d;
-}
-
-# Find the place at which aValue would normally be inserted into the
-# array. If that place is already occupied by aValue, do nothing, and
-# return undef. If the place does not exist (i.e., it is off the end of
-# the array), add it to the end, otherwise replace the element at that
-# point with aValue.  It is assumed that the array's values are numeric.
-# This is where the bulk (75%) of the time is spent in this module, so
-# try to make it fast!
-
-sub _replaceNextLargerWith
-{
-    my ( $array, $aValue, $high ) = @_;
-    $high ||= $#$array;
-
-    # off the end?
-    if ( $high == -1 || $aValue > $array->[-1] )
-    {
-        push ( @$array, $aValue );
-        return $high + 1;
-    }
-
-    # binary search for insertion point...
-    my $low = 0;
-    my $index;
-    my $found;
-    while ( $low <= $high )
-    {
-        $index = ( $high + $low ) / 2;
-
-        # $index = int(( $high + $low ) / 2);  # without 'use integer'
-        $found = $array->[$index];
-
-        if ( $aValue == $found )
-        {
-            return undef;
-        }
-        elsif ( $aValue > $found )
-        {
-            $low = $index + 1;
-        }
-        else
-        {
-            $high = $index - 1;
-        }
-    }
-
-    # now insertion point is in $low.
-    $array->[$low] = $aValue;    # overwrite next larger
-    return $low;
-}
-
-# This method computes the longest common subsequence in $a and $b.
-
-# Result is array or ref, whose contents is such that
-#   $a->[ $i ] == $b->[ $result[ $i ] ]
-# foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined.
-
-# An additional argument may be passed; this is a hash or key generating
-# function that should return a string that uniquely identifies the given
-# element.  It should be the case that if the key is the same, the elements
-# will compare the same. If this parameter is undef or missing, the key
-# will be the element as a string.
-
-# By default, comparisons will use "eq" and elements will be turned into keys
-# using the default stringizing operator '""'.
-
-# Additional parameters, if any, will be passed to the key generation
-# routine.
-
-sub _longestCommonSubsequence
-{
-    my $a        = shift;    # array ref or hash ref
-    my $b        = shift;    # array ref or hash ref
-    my $counting = shift;    # scalar
-    my $keyGen   = shift;    # code ref
-    my $compare;             # code ref
-
-    if ( ref($a) eq 'HASH' )
-    {                        # prepared hash must be in $b
-        my $tmp = $b;
-        $b = $a;
-        $a = $tmp;
-    }
-
-    # Check for bogus (non-ref) argument values
-    if ( !ref($a) || !ref($b) )
-    {
-        my @callerInfo = caller(1);
-        die 'error: must pass array or hash references to ' . $callerInfo[3];
-    }
-
-    # set up code refs
-    # Note that these are optimized.
-    if ( !defined($keyGen) )    # optimize for strings
-    {
-        $keyGen = sub { $_[0] };
-        $compare = sub { my ( $a, $b ) = @_; $a eq $b };
-    }
-    else
-    {
-        $compare = sub {
-            my $a = shift;
-            my $b = shift;
-            &$keyGen( $a, @_ ) eq &$keyGen( $b, @_ );
-        };
-    }
-
-    my ( $aStart, $aFinish, $matchVector ) = ( 0, $#$a, [] );
-    my ( $prunedCount, $bMatches ) = ( 0, {} );
-
-    if ( ref($b) eq 'HASH' )    # was $bMatches prepared for us?
-    {
-        $bMatches = $b;
-    }
-    else
-    {
-        my ( $bStart, $bFinish ) = ( 0, $#$b );
-
-        # First we prune off any common elements at the beginning
-        while ( $aStart <= $aFinish
-            and $bStart <= $bFinish
-            and &$compare( $a->[$aStart], $b->[$bStart], @_ ) )
-        {
-            $matchVector->[ $aStart++ ] = $bStart++;
-            $prunedCount++;
-        }
-
-        # now the end
-        while ( $aStart <= $aFinish
-            and $bStart <= $bFinish
-            and &$compare( $a->[$aFinish], $b->[$bFinish], @_ ) )
-        {
-            $matchVector->[ $aFinish-- ] = $bFinish--;
-            $prunedCount++;
-        }
-
-        # Now compute the equivalence classes of positions of elements
-        $bMatches =
-          _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ );
-    }
-    my $thresh = [];
-    my $links  = [];
-
-    my ( $i, $ai, $j, $k );
-    for ( $i = $aStart ; $i <= $aFinish ; $i++ )
-    {
-        $ai = &$keyGen( $a->[$i], @_ );
-        if ( exists( $bMatches->{$ai} ) )
-        {
-            $k = 0;
-            for $j ( @{ $bMatches->{$ai} } )
-            {
-
-                # optimization: most of the time this will be true
-                if ( $k and $thresh->[$k] > $j and $thresh->[ $k - 1 ] < $j )
-                {
-                    $thresh->[$k] = $j;
-                }
-                else
-                {
-                    $k = _replaceNextLargerWith( $thresh, $j, $k );
-                }
-
-                # oddly, it's faster to always test this (CPU cache?).
-                if ( defined($k) )
-                {
-                    $links->[$k] =
-                      [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];
-                }
-            }
-        }
-    }
-
-    if (@$thresh)
-    {
-        return $prunedCount + @$thresh if $counting;
-        for ( my $link = $links->[$#$thresh] ; $link ; $link = $link->[0] )
-        {
-            $matchVector->[ $link->[1] ] = $link->[2];
-        }
-    }
-    elsif ($counting)
-    {
-        return $prunedCount;
-    }
-
-    return wantarray ? @$matchVector : $matchVector;
-}
-
-sub traverse_sequences
-{
-    my $a                 = shift;          # array ref
-    my $b                 = shift;          # array ref
-    my $callbacks         = shift || {};
-    my $keyGen            = shift;
-    my $matchCallback     = $callbacks->{'MATCH'} || sub { };
-    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };
-    my $finishedACallback = $callbacks->{'A_FINISHED'};
-    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };
-    my $finishedBCallback = $callbacks->{'B_FINISHED'};
-    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );
-
-    # Process all the lines in @$matchVector
-    my $lastA = $#$a;
-    my $lastB = $#$b;
-    my $bi    = 0;
-    my $ai;
-
-    for ( $ai = 0 ; $ai <= $#$matchVector ; $ai++ )
-    {
-        my $bLine = $matchVector->[$ai];
-        if ( defined($bLine) )    # matched
-        {
-            &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;
-            &$matchCallback( $ai,    $bi++, @_ );
-        }
-        else
-        {
-            &$discardACallback( $ai, $bi, @_ );
-        }
-    }
-
-    # The last entry (if any) processed was a match.
-    # $ai and $bi point just past the last matching lines in their sequences.
-
-    while ( $ai <= $lastA or $bi <= $lastB )
-    {
-
-        # last A?
-        if ( $ai == $lastA + 1 and $bi <= $lastB )
-        {
-            if ( defined($finishedACallback) )
-            {
-                &$finishedACallback( $lastA, @_ );
-                $finishedACallback = undef;
-            }
-            else
-            {
-                &$discardBCallback( $ai, $bi++, @_ ) while $bi <= $lastB;
-            }
-        }
-
-        # last B?
-        if ( $bi == $lastB + 1 and $ai <= $lastA )
-        {
-            if ( defined($finishedBCallback) )
-            {
-                &$finishedBCallback( $lastB, @_ );
-                $finishedBCallback = undef;
-            }
-            else
-            {
-                &$discardACallback( $ai++, $bi, @_ ) while $ai <= $lastA;
-            }
-        }
-
-        &$discardACallback( $ai++, $bi, @_ ) if $ai <= $lastA;
-        &$discardBCallback( $ai, $bi++, @_ ) if $bi <= $lastB;
-    }
-
-    return 1;
-}
-
-sub traverse_balanced
-{
-    my $a                 = shift;              # array ref
-    my $b                 = shift;              # array ref
-    my $callbacks         = shift || {};
-    my $keyGen            = shift;
-    my $matchCallback     = $callbacks->{'MATCH'} || sub { };
-    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };
-    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };
-    my $changeCallback    = $callbacks->{'CHANGE'};
-    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );
-
-    # Process all the lines in match vector
-    my $lastA = $#$a;
-    my $lastB = $#$b;
-    my $bi    = 0;
-    my $ai    = 0;
-    my $ma    = -1;
-    my $mb;
-
-    while (1)
-    {
-
-        # Find next match indices $ma and $mb
-        do {
-            $ma++;
-        } while(
-                $ma <= $#$matchVector
-            &&  !defined $matchVector->[$ma]
-        );
-
-        last if $ma > $#$matchVector;    # end of matchVector?
-        $mb = $matchVector->[$ma];
-
-        # Proceed with discard a/b or change events until
-        # next match
-        while ( $ai < $ma || $bi < $mb )
-        {
-
-            if ( $ai < $ma && $bi < $mb )
-            {
-
-                # Change
-                if ( defined $changeCallback )
-                {
-                    &$changeCallback( $ai++, $bi++, @_ );
-                }
-                else
-                {
-                    &$discardACallback( $ai++, $bi, @_ );
-                    &$discardBCallback( $ai, $bi++, @_ );
-                }
-            }
-            elsif ( $ai < $ma )
-            {
-                &$discardACallback( $ai++, $bi, @_ );
-            }
-            else
-            {
-
-                # $bi < $mb
-                &$discardBCallback( $ai, $bi++, @_ );
-            }
-        }
-
-        # Match
-        &$matchCallback( $ai++, $bi++, @_ );
-    }
-
-    while ( $ai <= $lastA || $bi <= $lastB )
-    {
-        if ( $ai <= $lastA && $bi <= $lastB )
-        {
-
-            # Change
-            if ( defined $changeCallback )
-            {
-                &$changeCallback( $ai++, $bi++, @_ );
-            }
-            else
-            {
-                &$discardACallback( $ai++, $bi, @_ );
-                &$discardBCallback( $ai, $bi++, @_ );
-            }
-        }
-        elsif ( $ai <= $lastA )
-        {
-            &$discardACallback( $ai++, $bi, @_ );
-        }
-        else
-        {
-
-            # $bi <= $lastB
-            &$discardBCallback( $ai, $bi++, @_ );
-        }
-    }
-
-    return 1;
-}
-
-sub prepare
-{
-    my $a       = shift;    # array ref
-    my $keyGen  = shift;    # code ref
-
-    # set up code ref
-    $keyGen = sub { $_[0] } unless defined($keyGen);
-
-    return scalar _withPositionsOfInInterval( $a, 0, $#$a, $keyGen, @_ );
-}
-
-sub LCS
-{
-    my $a = shift;                  # array ref
-    my $b = shift;                  # array ref or hash ref
-    my $matchVector = _longestCommonSubsequence( $a, $b, 0, @_ );
-    my @retval;
-    my $i;
-    for ( $i = 0 ; $i <= $#$matchVector ; $i++ )
-    {
-        if ( defined( $matchVector->[$i] ) )
-        {
-            push ( @retval, $a->[$i] );
-        }
-    }
-    return wantarray ? @retval : \@retval;
-}
-
-sub LCS_length
-{
-    my $a = shift;                          # array ref
-    my $b = shift;                          # array ref or hash ref
-    return _longestCommonSubsequence( $a, $b, 1, @_ );
-}
-
-sub LCSidx
-{
-    my $a= shift @_;
-    my $b= shift @_;
-    my $match= _longestCommonSubsequence( $a, $b, 0, @_ );
-    my @am= grep defined $match->[$_], 0..$#$match;
-    my @bm= @{$match}[@am];
-    return \@am, \@bm;
-}
-
-sub compact_diff
-{
-    my $a= shift @_;
-    my $b= shift @_;
-    my( $am, $bm )= LCSidx( $a, $b, @_ );
-    my @cdiff;
-    my( $ai, $bi )= ( 0, 0 );
-    push @cdiff, $ai, $bi;
-    while( 1 ) {
-        while(  @$am  &&  $ai == $am->[0]  &&  $bi == $bm->[0]  ) {
-            shift @$am;
-            shift @$bm;
-            ++$ai, ++$bi;
-        }
-        push @cdiff, $ai, $bi;
-        last   if  ! @$am;
-        $ai = $am->[0];
-        $bi = $bm->[0];
-        push @cdiff, $ai, $bi;
-    }
-    push @cdiff, 0+@$a, 0+@$b
-        if  $ai < @$a || $bi < @$b;
-    return wantarray ? @cdiff : \@cdiff;
-}
-
-sub diff
-{
-    my $a      = shift;    # array ref
-    my $b      = shift;    # array ref
-    my $retval = [];
-    my $hunk   = [];
-    my $discard = sub {
-        push @$hunk, [ '-', $_[0], $a->[ $_[0] ] ];
-    };
-    my $add = sub {
-        push @$hunk, [ '+', $_[1], $b->[ $_[1] ] ];
-    };
-    my $match = sub {
-        push @$retval, $hunk
-            if 0 < @$hunk;
-        $hunk = []
-    };
-    traverse_sequences( $a, $b,
-        { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add }, @_ );
-    &$match();
-    return wantarray ? @$retval : $retval;
-}
-
-sub sdiff
-{
-    my $a      = shift;    # array ref
-    my $b      = shift;    # array ref
-    my $retval = [];
-    my $discard = sub { push ( @$retval, [ '-', $a->[ $_[0] ], "" ] ) };
-    my $add = sub { push ( @$retval, [ '+', "", $b->[ $_[1] ] ] ) };
-    my $change = sub {
-        push ( @$retval, [ 'c', $a->[ $_[0] ], $b->[ $_[1] ] ] );
-    };
-    my $match = sub {
-        push ( @$retval, [ 'u', $a->[ $_[0] ], $b->[ $_[1] ] ] );
-    };
-    traverse_balanced(
-        $a,
-        $b,
-        {
-            MATCH     => $match,
-            DISCARD_A => $discard,
-            DISCARD_B => $add,
-            CHANGE    => $change,
-        },
-        @_
-    );
-    return wantarray ? @$retval : $retval;
-}
-
-########################################
-my $Root= __PACKAGE__;
-package Algorithm::Diff::_impl;
-use strict;
-
-sub _Idx()  { 0 } # $me->[_Idx]: Ref to array of hunk indices
-            # 1   # $me->[1]: Ref to first sequence
-            # 2   # $me->[2]: Ref to second sequence
-sub _End()  { 3 } # $me->[_End]: Diff between forward and reverse pos
-sub _Same() { 4 } # $me->[_Same]: 1 if pos 1 contains unchanged items
-sub _Base() { 5 } # $me->[_Base]: Added to range's min and max
-sub _Pos()  { 6 } # $me->[_Pos]: Which hunk is currently selected
-sub _Off()  { 7 } # $me->[_Off]: Offset into _Idx for current position
-sub _Min() { -2 } # Added to _Off to get min instead of max+1
-
-sub Die
-{
-    require Carp;
-    Carp::confess( @_ );
-}
-
-sub _ChkPos
-{
-    my( $me )= @_;
-    return   if  $me->[_Pos];
-    my $meth= ( caller(1) )[3];
-    Die( "Called $meth on 'reset' object" );
-}
-
-sub _ChkSeq
-{
-    my( $me, $seq )= @_;
-    return $seq + $me->[_Off]
-        if  1 == $seq  ||  2 == $seq;
-    my $meth= ( caller(1) )[3];
-    Die( "$meth: Invalid sequence number ($seq); must be 1 or 2" );
-}
-
-sub getObjPkg
-{
-    my( $us )= @_;
-    return ref $us   if  ref $us;
-    return $us . "::_obj";
-}
-
-sub new
-{
-    my( $us, $seq1, $seq2, $opts ) = @_;
-    my @args;
-    for( $opts->{keyGen} ) {
-        push @args, $_   if  $_;
-    }
-    for( $opts->{keyGenArgs} ) {
-        push @args, @$_   if  $_;
-    }
-    my $cdif= Algorithm::Diff::compact_diff( $seq1, $seq2, @args );
-    my $same= 1;
-    if(  0 == $cdif->[2]  &&  0 == $cdif->[3]  ) {
-        $same= 0;
-        splice @$cdif, 0, 2;
-    }
-    my @obj= ( $cdif, $seq1, $seq2 );
-    $obj[_End] = (1+@$cdif)/2;
-    $obj[_Same] = $same;
-    $obj[_Base] = 0;
-    my $me = bless \@obj, $us->getObjPkg();
-    $me->Reset( 0 );
-    return $me;
-}
-
-sub Reset
-{
-    my( $me, $pos )= @_;
-    $pos= int( $pos || 0 );
-    $pos += $me->[_End]
-        if  $pos < 0;
-    $pos= 0
-        if  $pos < 0  ||  $me->[_End] <= $pos;
-    $me->[_Pos]= $pos || !1;
-    $me->[_Off]= 2*$pos - 1;
-    return $me;
-}
-
-sub Base
-{
-    my( $me, $base )= @_;
-    my $oldBase= $me->[_Base];
-    $me->[_Base]= 0+$base   if  defined $base;
-    return $oldBase;
-}
-
-sub Copy
-{
-    my( $me, $pos, $base )= @_;
-    my @obj= @$me;
-    my $you= bless \@obj, ref($me);
-    $you->Reset( $pos )   if  defined $pos;
-    $you->Base( $base );
-    return $you;
-}
-
-sub Next {
-    my( $me, $steps )= @_;
-    $steps= 1   if  ! defined $steps;
-    if( $steps ) {
-        my $pos= $me->[_Pos];
-        my $new= $pos + $steps;
-        $new= 0   if  $pos  &&  $new < 0;
-        $me->Reset( $new )
-    }
-    return $me->[_Pos];
-}
-
-sub Prev {
-    my( $me, $steps )= @_;
-    $steps= 1   if  ! defined $steps;
-    my $pos= $me->Next(-$steps);
-    $pos -= $me->[_End]   if  $pos;
-    return $pos;
-}
-
-sub Diff {
-    my( $me )= @_;
-    $me->_ChkPos();
-    return 0   if  $me->[_Same] == ( 1 & $me->[_Pos] );
-    my $ret= 0;
-    my $off= $me->[_Off];
-    for my $seq ( 1, 2 ) {
-        $ret |= $seq
-            if  $me->[_Idx][ $off + $seq + _Min ]
-            <   $me->[_Idx][ $off + $seq ];
-    }
-    return $ret;
-}
-
-sub Min {
-    my( $me, $seq, $base )= @_;
-    $me->_ChkPos();
-    my $off= $me->_ChkSeq($seq);
-    $base= $me->[_Base] if !defined $base;
-    return $base + $me->[_Idx][ $off + _Min ];
-}
-
-sub Max {
-    my( $me, $seq, $base )= @_;
-    $me->_ChkPos();
-    my $off= $me->_ChkSeq($seq);
-    $base= $me->[_Base] if !defined $base;
-    return $base + $me->[_Idx][ $off ] -1;
-}
-
-sub Range {
-    my( $me, $seq, $base )= @_;
-    $me->_ChkPos();
-    my $off = $me->_ChkSeq($seq);
-    if( !wantarray ) {
-        return  $me->[_Idx][ $off ]
-            -   $me->[_Idx][ $off + _Min ];
-    }
-    $base= $me->[_Base] if !defined $base;
-    return  ( $base + $me->[_Idx][ $off + _Min ] )
-        ..  ( $base + $me->[_Idx][ $off ] - 1 );
-}
-
-sub Items {
-    my( $me, $seq )= @_;
-    $me->_ChkPos();
-    my $off = $me->_ChkSeq($seq);
-    if( !wantarray ) {
-        return  $me->[_Idx][ $off ]
-            -   $me->[_Idx][ $off + _Min ];
-    }
-    return
-        @{$me->[$seq]}[
-                $me->[_Idx][ $off + _Min ]
-            ..  ( $me->[_Idx][ $off ] - 1 )
-        ];
-}
-
-sub Same {
-    my( $me )= @_;
-    $me->_ChkPos();
-    return wantarray ? () : 0
-        if  $me->[_Same] != ( 1 & $me->[_Pos] );
-    return $me->Items(1);
-}
-
-my %getName;
-BEGIN {
-    %getName= (
-        same => \&Same,
-        diff => \&Diff,
-        base => \&Base,
-        min  => \&Min,
-        max  => \&Max,
-        range=> \&Range,
-        items=> \&Items, # same thing
-    );
-}
-
-sub Get
-{
-    my $me= shift @_;
-    $me->_ChkPos();
-    my @value;
-    for my $arg (  @_  ) {
-        for my $word (  split ' ', $arg  ) {
-            my $meth;
-            if(     $word !~ /^(-?\d+)?([a-zA-Z]+)([12])?$/
-                ||  not  $meth= $getName{ lc $2 }
-            ) {
-                Die( $Root, ", Get: Invalid request ($word)" );
-            }
-            my( $base, $name, $seq )= ( $1, $2, $3 );
-            push @value, scalar(
-                4 == length($name)
-                    ? $meth->( $me )
-                    : $meth->( $me, $seq, $base )
-            );
-        }
-    }
-    if(  wantarray  ) {
-        return @value;
-    } elsif(  1 == @value  ) {
-        return $value[0];
-    }
-    Die( 0+@value, " values requested from ",
-        $Root, "'s Get in scalar context" );
-}
-
-
-my $Obj= getObjPkg($Root);
-no strict 'refs';
-
-for my $meth (  qw( new getObjPkg )  ) {
-    *{$Root."::".$meth} = \&{$meth};
-    *{$Obj ."::".$meth} = \&{$meth};
-}
-for my $meth (  qw(
-    Next Prev Reset Copy Base Diff
-    Same Items Range Min Max Get
-    _ChkPos _ChkSeq
-)  ) {
-    *{$Obj."::".$meth} = \&{$meth};
-}
-
-1;
-# This version released by Tye McQueen (http://perlmonks.org/?node=tye).
-# 
-# =head1 LICENSE
-# 
-# Parts Copyright (c) 2000-2004 Ned Konz.  All rights reserved.
-# Parts by Tye McQueen.
-# 
-# This program is free software; you can redistribute it and/or modify it
-# under the same terms as Perl.
-# 
-# =head1 MAILING LIST
-# 
-# Mark-Jason still maintains a mailing list.  To join a low-volume mailing
-# list for announcements related to diff and Algorithm::Diff, send an
-# empty mail message to mjd-perl-diff-request@plover.com.
-# =head1 CREDITS
-# 
-# Versions through 0.59 (and much of this documentation) were written by:
-# 
-# Mark-Jason Dominus, mjd-perl-diff@plover.com
-# 
-# This version borrows some documentation and routine names from
-# Mark-Jason's, but Diff.pm's code was completely replaced.
-# 
-# This code was adapted from the Smalltalk code of Mario Wolczko
-# <mario@wolczko.com>, which is available at
-# ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-# 
-# C<sdiff> and C<traverse_balanced> were written by Mike Schilli
-# <m@perlmeister.com>.
-# 
-# The algorithm is that described in
-# I<A Fast Algorithm for Computing Longest Common Subsequences>,
-# CACM, vol.20, no.5, pp.350-353, May 1977, with a few
-# minor improvements to improve the speed.
-# 
-# Much work was done by Ned Konz (perl@bike-nomad.com).
-# 
-# The OO interface and some other changes are by Tye McQueen.
-# 
-EOAlgDiff
-# 2}}}
-    my $problems        = 0;
-    $HAVE_Algorith_Diff = 0;
-    my $dir             = "";
-    if ($opt_sdir) {
-        # write to the user-defined scratch directory
-        $dir = $opt_sdir;
-    } else {
-        # let File::Temp create a suitable temporary directory
-        $dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
-    }
-    print "Using temp dir [$dir] to install Algorithm::Diff\n" if $opt_v;
-    my $Algorithm_dir      = "$dir/Algorithm";
-    my $Algorithm_Diff_dir = "$dir/Algorithm/Diff";
-    mkdir $Algorithm_dir     ;
-    mkdir $Algorithm_Diff_dir;
-
-    my $OUT = new IO::File "$dir/Algorithm/Diff.pm", "w";
-    if (defined $OUT) {
-        print $OUT $Algorithm_Diff_Contents;
-        $OUT->close;
-    } else {
-        warn "Failed to install Algorithm/Diff.pm\n";
-        $problems = 1;
-    }
-
-    push @INC, $dir;  # between this & Regexp::Common only need to do once
-    eval "use Algorithm::Diff qw / sdiff /";
-    $HAVE_Algorith_Diff = 1 unless $problems;
-} # 1}}}
-sub call_regexp_common {                     # {{{1
-    my ($ra_lines, $language ) = @_;
-    print "-> call_regexp_common\n" if $opt_v > 2;
-
-    Install_Regexp_Common() unless $HAVE_Rexexp_Common;
-
-    my $all_lines = join("", @{$ra_lines});
-
-    no strict 'vars';
-    # otherwise get:
-    #  Global symbol "%RE" requires explicit package name at cloc line xx.
-    if ($all_lines =~ $RE{comment}{$language}) {
-        # Suppress "Use of uninitialized value in regexp compilation" that
-        # pops up when $1 is undefined--happens if there's a bug in the $RE
-        # This Pascal comment will trigger it:
-        #         (* This is { another } test. **)
-        # Curiously, testing for "defined $1" breaks the substitution.
-        no warnings; 
-        # remove   comments
-        $all_lines =~ s/$1//g;
-    }
-    # a bogus use of %RE to avoid:
-    # Name "main::RE" used only once: possible typo at cloc line xx.
-    print scalar keys %RE if $opt_v < -20;
-#?#print "$all_lines\n";
-    print "<- call_regexp_common\n" if $opt_v > 2;
-    return split("\n", $all_lines);
-} # 1}}}
-sub plural_form {                            # {{{1
-    # For getting the right plural form on some English nouns.
-    my $n = shift @_;
-    if ($n == 1) { return ( 1, "" ); }
-    else         { return ($n, "s"); }
-} # 1}}}
-sub matlab_or_objective_C {                  # {{{1
-    # Decide if code is MATLAB, Objective C, or MUMPS
-    my ($file        , # in
-        $rh_Err      , # in   hash of error codes
-        $raa_errors  , # out
-        $rs_language , # out
-       ) = @_;
-
-    print "-> matlab_or_objective_C\n" if $opt_v > 2;
-    # matlab markers:
-    #   first line starts with "function"
-    #   some lines start with "%"
-    #   high marks for lines that start with [
-    #
-    # Objective C markers:
-    #   must have at least two brace characters, { }
-    #   has /* ... */ style comments
-    #   some lines start with @
-    #   some lines start with #include
-    #
-    # MUMPS:
-    #   has ; comment markers
-    #   do not match:  \w+\s*=\s*\w
-    #   lines begin with   \s*\.?\w+\s+\w
-    #   high marks for lines that start with \s*K\s+ or \s*Kill\s+
-
-    ${$rs_language} = "";
-    my $IN = new IO::File $file, "r";
-    if (!defined $IN) {
-        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
-        return;
-    }
-
-    my $DEBUG              = 0;
-
-    my $matlab_points      = 0;
-    my $objective_C_points = 0;
-    my $mumps_points       = 0;
-    my $has_braces         = 0;
-    while (<$IN>) {
-        ++$has_braces if m/[{}]/;
-        ++$mumps_points if $. == 1 and m{^[A-Z]};
-        if      (m{^\s*/\*}) {           #   /*
-            ++$objective_C_points;
-            --$matlab_points;
-printf ".m:  /*     obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{\w+\s*=\s*\[}) {      # matrix assignment, very matlab
-            $matlab_points += 5;
-printf ".m:  \\w=[   obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\s*\w+\s*=\s*}) {    # definitely not MUMPS
-            --$mumps_points;
-printf ".m:  \\w=    obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\s*\.?(\w)\s+(\w)} and $1 !~ /\d/ and $2 !~ /\d/) {
-            ++$mumps_points;
-printf ".m:  \\w \\w  obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\s*;}) {
-            ++$mumps_points;
-printf ".m:  ;      obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\s*#(include|import)}) {
-            # Objective C without a doubt
-            $objective_C_points = 1;
-            $matlab_points      = 0;
-printf ".m: #includ obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-            last;
-        } elsif (m{^\s*@(interface|implementation|protocol|public|protected|private|end)\s}o) {
-            # Objective C without a doubt
-            $objective_C_points = 1;
-            $matlab_points      = 0;
-printf ".m: keyword obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-            last;
-        } elsif (m{^\s*\[}) {             #   line starts with [  -- very matlab
-            $matlab_points += 5;
-printf ".m:  [      obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\sK(ill)?\s+}) {
-            $mumps_points  += 5;
-printf ".m:  Kill   obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\s*function}) {
-            --$objective_C_points;
-            ++$matlab_points;
-printf ".m:  funct  obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        } elsif (m{^\s*%}) {              #   %
-            --$objective_C_points;
-            ++$matlab_points;
-            ++$mumps_points;
-printf ".m:  pcent  obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
-        }
-    }
-    $IN->close;
-
-    print "<- matlab_or_objective_C(matlab=$matlab_points, C=$objective_C_points, mumps=$mumps_points)\n"
-        if $opt_v > 2;
-    $objective_C_points = -9.9e20 unless $has_braces >= 2;
-    if      (($matlab_points > $objective_C_points) and
-             ($matlab_points > $mumps_points)      ) {
-        ${$rs_language} = "MATLAB";
-    } elsif (($mumps_points > $objective_C_points) and
-             ($mumps_points > $matlab_points)      ) {
-        ${$rs_language} = "MUMPS";
-    } else {
-        ${$rs_language} = "Objective C";
-    }
-
-} # 1}}}
-sub html_colored_text {                      # {{{1
-    # http://www.pagetutor.com/pagetutor/makapage/pics/net216-2.gif
-    my ($color, $text) = @_;
-#?#die "html_colored_text($text)";
-    if      ($color =~ /^red$/i)   {
-        $color = "#ff0000";
-    } elsif ($color =~ /^green$/i) {
-        $color = "#00ff00";
-    } elsif ($color =~ /^blue$/i)  {
-        $color = "#0000ff";
-    } elsif ($color =~ /^grey$/i)  {
-        $color = "#cccccc";
-    }
-#   return "" unless $text;
-    return '<font color="' . $color . '">' . html_metachars($text) . "</font>";
-} # 1}}}
-sub html_metachars {                         # {{{1
-    # Replace HTML metacharacters with their printable forms.
-    # Future:  use HTML-Encoder-0.00_04/lib/HTML/Encoder.pm
-    # from Fabiano Reese Righetti's HTML::Encoder module if 
-    # this subroutine proves to be too simplistic.
-    my ($string, ) = shift @_;
-
-    my  @in_chars    = split(//, $string);
-    my  @out_chars   = ();
-    foreach my $c (@in_chars) {
-        if      ($c eq '<') {
-            push @out_chars, '&lt;'
-        } elsif ($c eq '>') {
-            push @out_chars, '&gt;'
-        } elsif ($c eq '&') {
-            push @out_chars, '&amp;'
-        } else {
-            push @out_chars, $c;
-        }
-    }
-    return join "", @out_chars; 
-} # 1}}}
-sub test_alg_diff {                          # {{{1
-    my ($file_1 ,
-        $file_2 )
-       = @_;
-    my $fh_1 = new IO::File $file_1, "r";
-    die "Unable to read $file_1:  $!\n" unless defined $fh_1;
-    chomp(my @lines_1 = <$fh_1>);
-    $fh_1->close;
-
-    my $fh_2 = new IO::File $file_2, "r";
-    die "Unable to read $file_2:  $!\n" unless defined $fh_2;
-    chomp(my @lines_2 = <$fh_2>);
-    $fh_2->close;
-
-    my $n_no_change = 0;
-    my $n_modified  = 0;
-    my $n_added     = 0;
-    my $n_deleted   = 0;
-    my @min_sdiff   = ();
-my $NN = chr(27) . "[0m";  # normal
-my $BB = chr(27) . "[1m";  # bold
-
-    my @sdiffs = sdiff( \@lines_1, \@lines_2 );
-    foreach my $entry (@sdiffs) {
-        my ($out_1, $out_2) = ('', '');
-        if ($entry->[0] eq 'u') { 
-            ++$n_no_change; 
-          # $out_1 = $entry->[1];
-          # $out_2 = $entry->[2];
-            next; 
-        }
-#       push @min_sdiff, $entry;
-        if      ($entry->[0] eq 'c') { 
-            ++$n_modified;
-            ($out_1, $out_2) = diff_two_strings($entry->[1], $entry->[2]);
-            $out_1 =~ s/\cA(\w)/${BB}$1${NN}/g;
-            $out_2 =~ s/\cA(\w)/${BB}$1${NN}/g;
-          # $out_1 =~ s/\cA//g;
-          # $out_2 =~ s/\cA//g;
-        } elsif ($entry->[0] eq '+') { 
-            ++$n_added;
-            $out_1 = $entry->[1];
-            $out_2 = $entry->[2];
-        } elsif ($entry->[0] eq '-') { 
-            ++$n_deleted;
-            $out_1 = $entry->[1];
-            $out_2 = $entry->[2];
-        } elsif ($entry->[0] eq 'u') { 
-        } else { die "unknown entry->[0]=[$entry->[0]]\n"; }
-        printf "%-80s | %s\n", $out_1, $out_2;
-    }
-
-#   foreach my $entry (@min_sdiff) {
-#       printf "DIFF:  %s  %s  %s\n", @{$entry};
-#   }
-} # 1}}}
-sub write_comments_to_html {                 # {{{1
-    my ($filename      , # in
-        $rah_diff_L    , # in  see routine array_diff() for explanation
-        $rah_diff_R    , # in  see routine array_diff() for explanation
-        $rh_blank      , # in  location and counts of blank lines
-       ) = @_;
-
-    print "-> write_comments_to_html($filename)\n" if $opt_v > 2;
-    my $file = $filename . ".html";
-#use Data::Dumper;
-#print Dumper("rah_diff_L", $rah_diff_L, "rah_diff_R", $rah_diff_R);
-    my $OUT = new IO::File $file, "w";
-    if (!defined $OUT) {
-        warn "Unable to write to $file\n";
-        print "<- write_comments_to_html\n" if $opt_v > 2;
-        return;
-    }
-
-    my $approx_line_count = scalar @{$rah_diff_L};
-    my $n_digits = 1 + int(log($approx_line_count)/2.30258509299405); # log_10
-
-    my $html_out = html_header($filename);
-
-    my $comment_line_number = 0;
-    for (my $i = 0; $i < scalar @{$rah_diff_R}; $i++) {
-        if (defined $rh_blank->{$i}) {
-            foreach (1..$rh_blank->{$i}) {
-                $html_out .= "<!-- blank -->\n";
-            }
-        }
-        my $line_num = "";
-        my $pre      = "";
-        my $post     = '</span> &nbsp;';
-warn "undef rah_diff_R[$i]{type} " unless defined $rah_diff_R->[$i]{type};
-        if ($rah_diff_R->[$i]{type} eq 'nonexist') {
-            ++$comment_line_number;
-            $line_num = sprintf "\&nbsp; <span class=\"clinenum\"> %0${n_digits}d %s",
-                            $comment_line_number, $post;
-            $pre = '<span class="comment">';
-            $html_out .= $line_num;  
-            $html_out .= $pre .  
-                         html_metachars($rah_diff_L->[$i]{char}) . 
-                         $post . "\n";
-            next;
-        }
-        if      ($rah_diff_R->[$i]{type} eq 'code' and
-                 $rah_diff_R->[$i]{desc} eq 'same') {
-            # entire line remains as-is
-            $line_num = sprintf "\&nbsp; <span class=\"linenum\"> %0${n_digits}d %s",
-                            $rah_diff_R->[$i]{lnum}, $post;
-            $pre    = '<span class="normal">';
-            $html_out .= $line_num;  
-            $html_out .= $pre . 
-                         html_metachars($rah_diff_R->[$i]{char}) . $post;
-#XX     } elsif ($rah_diff_R->[$i]{type} eq 'code') { # code+comments
-#XX
-#XX         $line_num = '<span class="linenum">' .
-#XX                      $rah_diff_R->[$i]{lnum} . $post;
-#XX         $html_out .= $line_num;  
-#XX
-#XX         my @strings = @{$rah_diff_R->[$i]{char}{strings}}; 
-#XX         my @type    = @{$rah_diff_R->[$i]{char}{type}}; 
-#XX         for (my $i = 0; $i < scalar @strings; $i++) {
-#XX             if ($type[$i] eq 'u') {
-#XX                 $pre = '<span class="normal">';
-#XX             } else {
-#XX                 $pre = '<span class="comment">';
-#XX             }
-#XX             $html_out .= $pre .  html_metachars($strings[$i]) . $post;
-#XX         }
-# print Dumper(@strings, @type); die;
-
-        } elsif ($rah_diff_R->[$i]{type} eq 'comment') {
-            $line_num = '<span class="clinenum">' . $comment_line_number . $post;
-            # entire line is a comment
-            $pre    = '<span class="comment">';
-            $html_out .= $pre .
-                         html_metachars($rah_diff_R->[$i]{char}) . $post;
-        }
-#printf "%-30s %s %-30s\n", $line_1, $separator, $line_2;
-        $html_out .= "\n";
-    }
-
-    $html_out .= html_end();
-
-    my $out_file = "$filename.html";
-    open  OUT, ">$out_file" or die "Cannot write to $out_file $!\n";
-    print OUT $html_out;
-    close OUT;
-    print "Wrote $out_file\n" unless $opt_quiet;
-    $OUT->close;
-
-    print "<- write_comments_to_html\n" if $opt_v > 2;
-} # 1}}}
-sub array_diff {                             # {{{1
-    my ($file          , # in  only used for error reporting
-        $ra_lines_L    , # in  array of lines in Left  file (no blank lines)
-        $ra_lines_R    , # in  array of lines in Right file (no blank lines)
-        $mode          , # in  "comment" | "revision"
-        $rah_diff_L    , # out
-        $rah_diff_R    , # out
-        $raa_Errors    , # in/out
-       ) = @_;
-
-    # This routine operates in two ways:
-    # A. Computes diffs of the same file with and without comments.
-    #    This is used to classify lines as code, comments, or blank.
-    # B. Computes diffs of two revisions of a file.  This method
-    #    requires a prior run of method A using the older version
-    #    of the file because it needs lines to be classified.
-
-    # $rah_diff structure:
-    # An array with n entries where n equals the number of lines in 
-    # an sdiff of the two files.  Each entry in the array describes
-    # the contents of the corresponding line in file Left and file Right:
-    #  diff[]{type} = blank | code | code+comment | comment | nonexist
-    #        {lnum} = line number within the original file (1-based)
-    #        {desc} = same | added | removed | modified
-    #        {char} = the input line unless {desc} = 'modified' in
-    #                 which case
-    #        {char}{strings} = [ substrings ]
-    #        {char}{type}    = [ disposition (added, removed, etc)]
-    #
-
-    print "-> array_diff()\n" if $opt_v > 2;
-    my $COMMENT_MODE = 0;
-       $COMMENT_MODE = 1 if $mode eq "comment";
-
-#print "array_diff(mode=$mode)\n";
-#print Dumper("block left:" , $ra_lines_L);
-#print Dumper("block right:", $ra_lines_R);
-
-    my @sdiffs = sdiff($ra_lines_L, $ra_lines_R);
-#use Data::Dumper::Simple;
-#print Dumper($ra_lines_L, $ra_lines_R, @sdiffs);
-#die;
-
-    my $n_L        = 0;
-    my $n_R        = 0;
-    my $n_sdiff    = 0;  # index to $rah_diff_L, $rah_diff_R
-    @{$rah_diff_L} = ();
-    @{$rah_diff_R} = ();
-    foreach my $triple (@sdiffs) {
-        my $flag   = $triple->[0];
-        my $line_L = $triple->[1];
-        my $line_R = $triple->[2];
-        $rah_diff_L->[$n_sdiff]{char} = $line_L;
-        $rah_diff_R->[$n_sdiff]{char} = $line_R;
-        if      ($flag eq 'u') {  # u = unchanged
-            ++$n_L;
-            ++$n_R;
-            if ($COMMENT_MODE) {
-                # line exists in both with & without comments, must be code
-                $rah_diff_L->[$n_sdiff]{type} = "code";
-                $rah_diff_R->[$n_sdiff]{type} = "code";
-            }
-            $rah_diff_L->[$n_sdiff]{desc} = "same";
-            $rah_diff_R->[$n_sdiff]{desc} = "same";
-            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;
-            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;
-        } elsif ($flag eq 'c') {  # c = changed
-# warn "per line sdiff() commented out\n"; if (0) {
-            ++$n_L;
-            ++$n_R;
-
-            if ($COMMENT_MODE) {
-                # line has text both with & without comments;
-                # count as code
-                $rah_diff_L->[$n_sdiff]{type} = "code";
-                $rah_diff_R->[$n_sdiff]{type} = "code";
-            }
-
-            my @chars_L = split '', $line_L;
-            my @chars_R = split '', $line_R;
-
-#XX         my @inline_sdiffs = sdiff( \@chars_L, \@chars_R );
-
-#use Data::Dumper::Simple; 
-#if ($n_R == 6 or $n_R == 1 or $n_R == 2) {
-#print "L=[$line_L]\n";
-#print "R=[$line_R]\n";
-#print Dumper(@chars_L, @chars_R, @inline_sdiffs);
-#}
-#XX         my @index = ();
-#XX         foreach my $il_triple (@inline_sdiffs) {
-#XX             # make an array of u|c|+|- corresponding
-#XX             # to each character
-#XX             push @index, $il_triple->[0];
-#XX         }
-#XX#print Dumper(@index); die;
-#XX          # expect problems if arrays @index and $inline_sdiffs[1];
-#XX          # (@{$inline_sdiffs->[1]} are the characters of line_L)
-#XX          # aren't the same length
-#XX          my $prev_type = $index[0];
-#XX          my @strings   = ();  # blocks of consecutive code or comment
-#XX          my @type      = ();  # u (=code) or c (=comment)
-#XX          my $j_str     = 0;
-#XX          $strings[$j_str] .= $chars_L[0];
-#XX          $type[$j_str] = $prev_type;
-#XX          for (my $i = 1; $i < scalar @chars_L; $i++) {
-#XX              if ($index[$i] ne $prev_type) {
-#XX                  ++$j_str;
-#XX#print "change at j_str=$j_str type=$index[$i]\n";
-#XX                  $type[$j_str] = $index[$i];
-#XX                  $prev_type    = $index[$i];
-#XX              }
-#XX              $strings[$j_str] .= $chars_L[$i];
-#XX          }
-# print Dumper(@strings, @type); die;
-#XX         delete $rah_diff_R->[$n_sdiff]{char};
-#XX         @{$rah_diff_R->[$n_sdiff]{char}{strings}} = @strings;
-#XX         @{$rah_diff_R->[$n_sdiff]{char}{type}}    = @type;
-            $rah_diff_L->[$n_sdiff]{desc} = "modified";
-            $rah_diff_R->[$n_sdiff]{desc} = "modified";
-            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;
-            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;
-#}
-
-        } elsif ($flag eq '+') {  # + = added
-            ++$n_R;
-            if ($COMMENT_MODE) {
-                # should never get here
-                @{$rah_diff_L} = ();
-                @{$rah_diff_R} = ();
-                push @{$raa_Errors}, 
-                     [ $Error_Codes{'Diff error (quoted comments?)'}, $file ];
-                if ($opt_v) {
-                  warn "array_diff: diff failure (diff says the\n";
-                  warn "comment-free file has added lines).\n";
-                  warn "$n_sdiff  $line_L\n";
-                }
-                last;
-            }
-            $rah_diff_L->[$n_sdiff]{type} = "nonexist";
-            $rah_diff_L->[$n_sdiff]{desc} = "removed";
-            $rah_diff_R->[$n_sdiff]{desc} = "added";
-            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;
-        } elsif ($flag eq '-') {  # - = removed
-            ++$n_L;
-            if ($COMMENT_MODE) {
-                # line must be comment because blanks already gone
-                $rah_diff_L->[$n_sdiff]{type} = "comment";
-            }
-            $rah_diff_R->[$n_sdiff]{type} = "nonexist";
-            $rah_diff_R->[$n_sdiff]{desc} = "removed";
-            $rah_diff_L->[$n_sdiff]{desc} = "added";
-            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;
-        }
-#printf "%-30s %s %-30s\n", $line_L, $separator, $line_R;
-        ++$n_sdiff;
-    }
-#use Data::Dumper::Simple;
-#print Dumper($rah_diff_L, $rah_diff_R);
-
-    print "<- array_diff\n" if $opt_v > 2;
-} # 1}}}
-sub remove_leading_dir {                     # {{{1 
-    my @filenames = @_;
-    #
-    #  Input should be a list of file names
-    #  with the same leading directory such as
-    # 
-    #      dir1/dir2/a.txt
-    #      dir1/dir2/b.txt
-    #      dir1/dir2/dir3/c.txt
-    #
-    #  Output is the same list minus the common
-    #  directory path:
-    # 
-    #      a.txt
-    #      b.txt
-    #      dir3/c.txt
-    #
-    print "-> remove_leading_dir()\n" if $opt_v > 2;
-    my @D = (); # a matrix:   [ [ dir1, dir2 ],         # dir1/dir2/a.txt
-                #               [ dir1, dir2 ],         # dir1/dir2/b.txt
-                #               [ dir1, dir2 , dir3] ]  # dir1/dir2/dir3/c.txt
-    if ($ON_WINDOWS) {
-        foreach my $F (@filenames) {
-            $F =~ s{\\}{/}g;
-            $F = ucfirst($F) if $F =~ /^\w:/;  # uppercase drive letter
-        }
-    }
-    if (scalar @filenames == 1) {
-        # special case:  with only one filename
-        # cannot determine a baseline
-        return ( basename $filenames[0] );
-    }
-    foreach my $F (@filenames) {
-        my ($Vol, $Dir, $File) = File::Spec->splitpath($F);
-        my @x = File::Spec->splitdir( $Dir );
-        pop @x unless $x[$#x]; # last entry usually null, remove it
-        if ($ON_WINDOWS) {
-            if (defined($Vol) and $Vol) {
-                # put the drive letter, eg, C:, at the front
-                unshift @x, uc $Vol;
-            }
-        }
-#print "F=$F, Dir=$Dir  x=[", join("][", @x), "]\n";
-        push @D, [ @x ];
-    }
-
-    # now loop over columns until either they are all
-    # eliminated or a unique column is found
-
-#use Data::Dumper::Simple;
-#print Dumper("remove_leading_dir after ", @D);
-
-    my @common   = ();  # to contain the common leading directories
-    my $mismatch = 0;
-    while (!$mismatch) {
-        for (my $row = 1; $row < scalar @D; $row++) {
-#print "comparing $D[$row][0] to $D[0][0]\n";
-
-            if (!defined $D[$row][0] or !defined $D[0][0] or
-                ($D[$row][0] ne $D[0][0])) {
-                $mismatch = 1;
-                last;
-            }
-        }
-#print "mismatch=$mismatch\n";
-        if (!$mismatch) {
-            push @common, $D[0][0];
-            # all terms in the leading match; unshift the batch
-            foreach my $ra (@D) {
-                shift @{$ra};
-            }
-        }
-    }
-
-    push @common, " ";  # so that $leading will end with "/ "
-    my $leading = File::Spec->catdir( @common );
-       $leading =~ s{ $}{};  # now take back the bogus appended space
-#print "remove_leading_dir leading=[$leading]\n"; die;
-    if ($ON_WINDOWS) {
-       $leading =~ s{\\}{/}g;
-    }
-    foreach my $F (@filenames) {
-        $F =~ s{^$leading}{};
-    }
-
-    print "<- remove_leading_dir()\n" if $opt_v > 2;
-    return @filenames;
-
-} # 1}}}
-sub align_by_pairs {                         # {{{1 
-    my ($rh_file_list_L        , # in
-        $rh_file_list_R        , # in
-        $ra_added              , # out
-        $ra_removed            , # out
-        $ra_compare_list       , # out
-        ) = @_;
-    print "-> align_by_pairs()\n" if $opt_v > 2;
-    @{$ra_compare_list} = ();
-
-    my @files_L = sort keys %{$rh_file_list_L};
-    my @files_R = sort keys %{$rh_file_list_R};
-    return () unless @files_L or  @files_R;  # at least one must have stuff
-    if      ( @files_L and !@files_R) {
-        # left side has stuff, right side is empty; everything deleted
-        @{$ra_added   }     = ();
-        @{$ra_removed }     = @files_L;
-        @{$ra_compare_list} = ();
-        return;
-    } elsif (!@files_L and  @files_R) {
-        # left side is empty, right side has stuff; everything added
-        @{$ra_added   }     = @files_R;
-        @{$ra_removed }     = ();
-        @{$ra_compare_list} = ();
-        return;
-    }
-#use Data::Dumper::Simple;
-#print Dumper("align_by_pairs", @files_L, @files_R);
-#die;
-    if (scalar @files_L == 1 and scalar @files_R == 1) {
-        # The easy case:  compare two files.
-        push @{$ra_compare_list}, [ $files_L[0],  $files_R[0] ]; 
-        @{$ra_added  } = ();
-        @{$ra_removed} = ();
-        return;
-    }
-    # The harder case:  compare groups of files.  This only works
-    # if the groups are in different directories so the first step
-    # is to strip the leading directory names from file lists to
-    # make it possible to align by file names.
-    my @files_L_minus_dir = remove_leading_dir(@files_L);
-    my @files_R_minus_dir = remove_leading_dir(@files_R);
-
-    # Keys of the stripped_X arrays are canonical file names;
-    # should overlap mostly.  Keys in stripped_L but not in
-    # stripped_R are files that have been deleted.  Keys in
-    # stripped_R but not in stripped_L have been added.
-    my %stripped_L = ();
-       @stripped_L{ @files_L_minus_dir } = @files_L;
-    my %stripped_R = ();
-       @stripped_R{ @files_R_minus_dir } = @files_R;
-
-    my %common = ();
-    foreach my $f (keys %stripped_L) {
-        $common{$f}  = 1 if     defined $stripped_R{$f};
-    }
-
-    my %deleted = ();
-    foreach my $f (keys %stripped_L) {
-        $deleted{$stripped_L{$f}} = $f unless defined $stripped_R{$f};
-    }
-
-    my %added = ();
-    foreach my $f (keys %stripped_R) {
-        $added{$stripped_R{$f}}   = $f unless defined $stripped_L{$f};
-    }
-
-#use Data::Dumper::Simple;
-#print Dumper("align_by_pairs", %stripped_L, %stripped_R);
-#print Dumper("align_by_pairs", %common, %added, %deleted);
-    
-    foreach my $f (keys %common) {
-        push @{$ra_compare_list}, [ $stripped_L{$f},  
-                                    $stripped_R{$f} ]; 
-    }
-    @{$ra_added   } = keys %added  ;
-    @{$ra_removed } = keys %deleted;
-
-    print "<- align_by_pairs()\n" if $opt_v > 2;
-    return;
-#print Dumper("align_by_pairs", @files_L_minus_dir, @files_R_minus_dir);
-#die;
-} # 1}}}
-sub html_header {                            # {{{1
-    my ($title , ) = @_;
-
-    print "-> html_header\n" if $opt_v > 2;
-    return 
-'<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="GENERATOR" content="cloc http://cloc.sourceforge.net">
-' .
-"
-<!-- Created by $script v$VERSION -->
-<title>$title</title>
-" .
-'
-<style TYPE="text/css">
-<!--
-    body {
-        color: black;
-        background-color: white;
-        font-family: monospace
-    }
-
-    .whitespace {
-        background-color: gray;
-    }
-
-    .comment {
-        color: gray;
-        font-style: italic;
-    }
-
-    .clinenum {
-        color: red;
-    }
-
-    .linenum {
-        color: green;
-    }
- -->
-</style>
-</head>
-<body>
-<pre><tt>
-';
-    print "<- html_header\n" if $opt_v > 2;
-} # 1}}}
-sub html_end {                               # {{{1
-return 
-'</tt></pre>
-</body>
-</html>
-';
-} # 1}}}
-sub die_unknown_lang {                       # {{{1
-    my ($lang, $option_name) = @_;
-    die "Unknown language '$lang' used with $option_name option.  " .
-        "The command\n  $script --show-lang\n" .
-        "will print all recognized languages.  Language names are " .
-        "case sensitive.\n" ;
-} # 1}}}
-sub unicode_file {                           # {{{1
-    my $file = shift @_; 
-
-    print "-> unicode_file($file)\n" if $opt_v > 2;
-    return 0 if (-s $file > 2_000_000);  
-    # don't bother trying to test binary files bigger than 2 MB
-
-    my $IN = new IO::File $file, "r";
-    if (!defined $IN) {
-        warn "Unable to read $file; ignoring.\n";
-        return 0;
-    }
-    my @lines = <$IN>;
-    $IN->close;
-
-    if (unicode_to_ascii( join('', @lines) )) {
-        print "<- unicode_file()\n" if $opt_v > 2;
-        return 1;
-    } else {
-        print "<- unicode_file()\n" if $opt_v > 2;
-        return 0;
-    }
-
-} # 1}}}
-sub unicode_to_ascii {                       # {{{1
-    my $string = shift @_; 
-
-    # A trivial attempt to convert Microsoft Windows style Unicode
-    # files into ASCII.  These files exhibit the following byte
-    # sequence:
-    # byte   1:  255
-    # byte   2:  254
-    # byte   3:  ord of ASCII character
-    # byte   4:    0
-    # byte 3+i:  ord of ASCII character
-    # byte 4+i:    0
-
-    my @ascii              = ();
-    my $looks_like_unicode = 1;
-    my $length             = length $string;
-# print "length=$length\n";
-    if ($length <= 3) {
-        $looks_like_unicode = 0;
-        return '';
-    }
-    my @unicode            = split(//, $string);
-
-    for (my $i = 2; $i < $length; $i += 2) {
-# print "examining [$unicode[$i]]  ord ", ord($unicode[$i]), "\n";
-        if (32 <= ord($unicode[$i]) and ord($unicode[$i]) <= 127
-            or ord($unicode[$i]) == 13
-            or ord($unicode[$i]) == 10
-            or ord($unicode[$i]) ==  9
-            ) {
-            push @ascii, $unicode[$i];
-# print "adding [$unicode[$i]]\n";
-        } else {
-            $looks_like_unicode = 0;
-            last;
-        }
-        if ($i+1 < $length) {
-            if (!$unicode[$i+1]) {
-                $looks_like_unicode = 0;
-                last;
-            }
-        }
-    }
-    if ($looks_like_unicode) {
-        return join("", @ascii);
-    } else {
-        return '';
-    }
-} # 1}}}
-sub uncompress_archive_cmd {                 # {{{1
-    my ($archive_file, ) = @_;
-
-    # Wrap $archive_file in single or double quotes in the system
-    # commands below to avoid filename chicanery (including
-    # spaces in the names).
-
-    print "-> uncompress_archive_cmd($archive_file)\n" if $opt_v > 2;
-    my $extract_cmd = "";
-    my $missing     = "";
-    if ($opt_extract_with) {
-        ( $extract_cmd = $opt_extract_with ) =~ s/>FILE</$archive_file/g;
-    } elsif (($archive_file =~ /\.tar\.(gz|Z)$/ or 
-              $archive_file =~ /\.tgz$/       ) and !$ON_WINDOWS)    {
-        if (external_utility_exists("gzip --version")) {
-            if (external_utility_exists("tar --version")) {
-                $extract_cmd = "gzip -dc '$archive_file' | tar xf -";
-            } else {
-                $missing = "tar";
-            }
-        } else {
-            $missing = "gzip";
-        }
-    } elsif ($archive_file =~ /\.tar\.bz2$/ and !$ON_WINDOWS)    {
-        if (external_utility_exists("bzip2 --help")) {
-            if (external_utility_exists("tar --version")) {
-                $extract_cmd = "bzip2 -dc '$archive_file' | tar xf -";
-            } else {
-                $missing = "tar";
-            }
-        } else {
-            $missing = "bzip2";
-        }
-    } elsif ($archive_file =~ /\.tar$/ and !$ON_WINDOWS)    {
-        $extract_cmd = "tar xf '$archive_file'";
-    } elsif ($archive_file =~ /\.src\.rpm$/i and !$ON_WINDOWS) {
-        if (external_utility_exists("cpio --version")) {
-            if (external_utility_exists("rpm2cpio")) {
-                $extract_cmd = "rpm2cpio '$archive_file' | cpio -i";
-            } else {
-                $missing = "rpm2cpio";
-            }
-        } else {
-            $missing = "bzip2";
-        }
-    } elsif ($archive_file =~ /\.zip$/i and !$ON_WINDOWS)    {
-        if (external_utility_exists("unzip")) {
-            $extract_cmd = "unzip -qq -d . '$archive_file'";
-        } else {
-            $missing = "unzip";
-        }
-    } elsif ($ON_WINDOWS and $archive_file =~ /\.zip$/i) {
-        # zip on Windows, guess default Winzip install location
-        $extract_cmd = "";
-        my $WinZip = '"C:\\Program Files\\WinZip\\WinZip32.exe"';
-        if (external_utility_exists($WinZip)) {
-            $extract_cmd = "$WinZip -e -o \"$archive_file\" .";
-#print "trace 5 extract_cmd=[$extract_cmd]\n";
-        } else {
-#print "trace 6\n";
-            $missing = $WinZip;
-        }
-    }
-    print "<- uncompress_archive_cmd\n" if $opt_v > 2;
-    if ($missing) {
-        die "Unable to expand $archive_file because external\n",
-            "utility '$missing' is not available.\n",
-            "Another possibility is to use the --extract-with option.\n";
-    } else {
-        return $extract_cmd;
-    }
-}
-# 1}}}
-sub read_list_file {                         # {{{1
-    my ($file, ) = @_;
-
-    print "-> read_list_file($file)\n" if $opt_v > 2;
-    my $IN = new IO::File $file, "r";
-    if (!defined $IN) {
-        warn "Unable to read $file; ignoring.\n";
-        next;
-    }
-    my @entry = ();
-    while (<$IN>) {
-        next if /^\s*$/ or /^\s*#/; # skip empty or commented lines
-        chomp;
-        push @entry, $_;
-    }
-    $IN->close;
-
-    print "<- read_list_file\n" if $opt_v > 2;
-    return @entry;
-}
-# 1}}}
-sub external_utility_exists {                # {{{1
-    my $exe = shift @_;
-
-    my $success      = 0;
-    if ($ON_WINDOWS) {
-        $success = 1 unless system $exe . ' > nul';
-    } else {
-        $success = 1 unless system $exe . ' >& /dev/null';
-        if (!$success) {
-            $success = 1 unless system "which" . " $exe" . ' >& /dev/null';
-        }
-    }
-    
-    return $success;
-} # 1}}}
-sub write_xsl_file {                         # {{{1
-    my $OUT = new IO::File $CLOC_XSL, "w";
-    if (!defined $OUT) {
-        warn "Unable to write $CLOC_XSL  $!\n";
-        return;
-    }
-    my $XSL =             # <style>  </style> {{{2
-'<?xml version="1.0" encoding="US-ASCII"?>
-<!-- XLS file by Paul Schwann, January 2009.
-     Fixes for by-file and by-file-by-lang by d_uragan, November 2010.
-     -->
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-  <xsl:output method="html"/>
-  <xsl:template match="/">
-    <html xmlns="http://www.w3.org/1999/xhtml">
-      <head>
-        <title>CLOC Results</title>
-      </head>
-      <style type="text/css">
-        table {
-          table-layout: auto;
-          border-collapse: collapse;
-          empty-cells: show;
-        }
-        td, th {
-          padding: 4px;
-        }
-        th {
-          background-color: #CCCCCC;
-        }
-        td {
-          text-align: center;
-        }
-        table, td, tr, th {
-          border: thin solid #999999;
-        }
-      </style>
-      <body>
-        <h3><xsl:value-of select="results/header"/></h3>
-';
-# 2}}}
-
-    if ($opt_by_file) {
-        $XSL .=             # <table> </table>{{{2
-'        <table>
-          <thead>
-            <tr>
-              <th>File</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>
-              <th>Language</th>
-';
-        $XSL .=
-'             <th>3<sup>rd</sup> Generation Equivalent</th>
-              <th>Scale</th>
-' if $opt_3;
-        $XSL .=
-'           </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="results/files/file">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>
-              <td><xsl:value-of select="@language"/></td>
-';
-        $XSL .=
-'             <td><xsl:value-of select="@factor"/></td>
-              <td><xsl:value-of select="@scaled"/></td>
-' if $opt_3;
-        $XSL .=
-'           </tr>
-          </xsl:for-each>
-            <tr>
-              <th>Total</th>
-              <th><xsl:value-of select="results/files/total/@blank"/></th>
-              <th><xsl:value-of select="results/files/total/@comment"/></th>
-              <th><xsl:value-of select="results/files/total/@code"/></th>
-              <th><xsl:value-of select="results/files/total/@language"/></th>
-';
-        $XSL .=
-'             <th><xsl:value-of select="results/files/total/@factor"/></th>
-              <th><xsl:value-of select="results/files/total/@scaled"/></th>
-' if $opt_3;
-        $XSL .=
-'           </tr>
-          </tbody>
-        </table>
-        <br/>
-';
-# 2}}}
-    }
-
-    if (!$opt_by_file or $opt_by_file_by_lang) {
-        $XSL .=             # <table> </table> {{{2
-'       <table>
-          <thead>
-            <tr>
-              <th>Language</th>
-              <th>Files</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>
-';
-        $XSL .=
-'             <th>Scale</th>
-              <th>3<sup>rd</sup> Generation Equivalent</th>
-' if $opt_3;
-        $XSL .=
-'           </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="results/languages/language">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@files_count"/></td>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>
-';
-        $XSL .=
-'             <td><xsl:value-of select="@factor"/></td>
-              <td><xsl:value-of select="@scaled"/></td>
-' if $opt_3;
-        $XSL .=
-'          </tr>
-          </xsl:for-each>
-            <tr>
-              <th>Total</th>
-              <th><xsl:value-of select="results/languages/total/@sum_files"/></th>
-              <th><xsl:value-of select="results/languages/total/@blank"/></th>
-              <th><xsl:value-of select="results/languages/total/@comment"/></th>
-              <th><xsl:value-of select="results/languages/total/@code"/></th>
-';
-        $XSL .=
-'             <th><xsl:value-of select="results/languages/total/@factor"/></th>
-              <th><xsl:value-of select="results/languages/total/@scaled"/></th>
-' if $opt_3;
-        $XSL .=
-'           </tr>
-          </tbody>
-        </table>
-';
-# 2}}}
-    }
-
-    $XSL.= <<'EO_XSL'; # {{{2
-      </body>
-    </html>
-  </xsl:template>
-</xsl:stylesheet>
-
-EO_XSL
-# 2}}}
-
-    my $XSL_DIFF = <<'EO_DIFF_XSL'; # {{{2
-<?xml version="1.0" encoding="US-ASCII"?>
-<!-- XLS file by Blazej Kroll, November 2010 -->
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-  <xsl:output method="html"/>
-  <xsl:template match="/">
-    <html xmlns="http://www.w3.org/1999/xhtml">
-      <head>
-        <title>CLOC Results</title>
-      </head>
-      <style type="text/css">
-        table {
-          table-layout: auto;
-          border-collapse: collapse;
-          empty-cells: show;
-		  margin: 1em;
-        }
-        td, th {
-          padding: 4px;
-        }
-        th {
-          background-color: #CCCCCC;
-        }
-        td {
-          text-align: center;
-        }
-        table, td, tr, th {
-          border: thin solid #999999;
-        }
-      </style>
-      <body>
-        <h3><xsl:value-of select="results/header"/></h3>
-EO_DIFF_XSL
-# 2}}}
-
-    if ($opt_by_file) {
-        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2
-		<table>
-          <thead>
-		  <tr><th colspan="4">Same</th>
-		  </tr>
-            <tr>
-              <th>File</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/same/file">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-		
-		<table>
-          <thead>
-		  <tr><th colspan="4">Modified</th>
-		  </tr>
-            <tr>
-              <th>File</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/modified/file">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-		
-		<table>
-          <thead>
-		  <tr><th colspan="4">Added</th>
-		  </tr>
-            <tr>
-              <th>File</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/added/file">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-		
-		<table>
-          <thead>
-		  <tr><th colspan="4">Removed</th>
-		  </tr>
-            <tr>
-              <th>File</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/removed/file">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-EO_DIFF_XSL
-# 2}}}
-    }
-
-    if (!$opt_by_file or $opt_by_file_by_lang) {
-        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2
-		<table>
-          <thead>
-		  <tr><th colspan="5">Same</th>
-		  </tr>
-            <tr>
-              <th>Language</th>
-              <th>Files</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/same/language">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@files_count"/></td>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-		
-		<table>
-          <thead>
-		  <tr><th colspan="5">Modified</th>
-		  </tr>
-            <tr>
-              <th>Language</th>
-              <th>Files</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/modified/language">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@files_count"/></td>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-		
-		<table>
-          <thead>
-		  <tr><th colspan="5">Added</th>
-		  </tr>
-            <tr>
-              <th>Language</th>
-              <th>Files</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/added/language">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@files_count"/></td>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-		
-		<table>
-          <thead>
-		  <tr><th colspan="5">Removed</th>
-		  </tr>
-            <tr>
-              <th>Language</th>
-              <th>Files</th>
-              <th>Blank</th>
-              <th>Comment</th>
-              <th>Code</th>              
-            </tr>
-          </thead>
-          <tbody>
-          <xsl:for-each select="diff_results/removed/language">
-            <tr>
-              <th><xsl:value-of select="@name"/></th>
-              <td><xsl:value-of select="@files_count"/></td>
-              <td><xsl:value-of select="@blank"/></td>
-              <td><xsl:value-of select="@comment"/></td>
-              <td><xsl:value-of select="@code"/></td>              
-            </tr>
-          </xsl:for-each>            
-          </tbody>
-        </table>
-EO_DIFF_XSL
-# 2}}}
-
-    }
-    
-    $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2
-      </body>
-    </html>
-  </xsl:template>
-</xsl:stylesheet>
-EO_DIFF_XSL
-# 2}}}
-    if ($opt_diff) {
-        print $OUT $XSL_DIFF;
-    } else {
-        print $OUT $XSL;
-    }
-    $OUT->close();
-} # 1}}}
-sub normalize_file_names {                   # {{{1 
-    my (@files, ) = @_;
-
-    # Returns a hash of file names reduced to a canonical form
-    # (fully qualified file names, all path separators changed to /,
-    # Windows file names lowercased).  Hash values are the original
-    # file name.
-
-    my %normalized = ();
-    foreach my $F (@files) {
-        my $F_norm = $F;
-        if ($ON_WINDOWS) {
-            $F_norm = lc $F_norm; # for case insensitive file name comparisons
-            $F_norm =~ s{\\}{/}g; # Windows directory separators to Unix
-            $F_norm =~ s{^\./}{}g;  # remove leading ./
-            if (($F_norm !~ m{^/}) and ($F_norm !~ m{^\w:/})) {
-                # looks like a relative path; prefix with cwd
-                $F_norm = lc "$cwd/$F_norm";
-            }
-        } else {
-            $F_norm =~ s{^\./}{}g;  # remove leading ./
-            if ($F_norm !~ m{^/}) {
-                # looks like a relative path; prefix with cwd
-                $F_norm = lc "$cwd/$F_norm";
-            }
-        }
-        $normalized{ $F_norm } = $F;
-    }
-    return %normalized;
-} # 1}}}
-sub combine_diffs {                          # {{{1
-    # subroutine by Andy (awalshe@sf.net)
-    # https://sourceforge.net/tracker/?func=detail&aid=3261017&group_id=174787&atid=870625
-    my ($ra_files) = @_;
-
-    my $res   = "$URL v $VERSION\n";
-    my $dl    = '-';
-    my $width = 79;
-    # columns are in this order
-    my @cols  = ('files', 'blank', 'comment', 'code');
-    my %HoH   = ();
-  
-    foreach my $file (@{$ra_files}) {
-        my $IN = new IO::File $file, "r";
-        if (!defined $IN) {
-            warn "Unable to read $file; ignoring.\n";
-            next;
-        }
-
-        my $sec;
-        while (<$IN>) {
-            next if /^(http|Language|-----)/;
-            if (/^[A-Z][a-z]*/) {        # section title
-                $sec = $_;
-                chomp($sec);
-                $HoH{$sec} = () if ! exists $HoH{$sec};
-                next;
-            }
-  
-            if (/^\s(same|modified|added|removed)/) {  # calculated totals row
-                my @ar = grep { $_ ne '' } split(/ /, $_);
-                chomp(@ar);
-                my $ttl = shift @ar;
-                my $i = 0;
-                foreach(@ar) {
-                    my $t = "$ttl$dl$cols[$i]";
-                    $HoH{$sec}{$t} = 0 if ! exists $HoH{$sec}{$t};
-                    $HoH{$sec}{$t} += $_;
-                    $i++;
-                }
-            }
-        }
-        $IN->close;
-    }
-  
-    # rows are in this order
-    my @rows = ('same', 'modified', 'added', 'removed');
-  
-    $res .= sprintf("%s\n", "-" x $width);
-    $res .= sprintf("%-19s %14s %14s %14s %14s\n", 'Language', 
-                    $cols[0], $cols[1], $cols[2], $cols[3]);
-    $res .= sprintf("%s\n", "-" x $width);
-  
-    for my $sec ( keys %HoH ) {
-        next if $sec =~ /SUM:/;
-        $res .= "$sec\n";
-        foreach (@rows) {
-            $res .= sprintf(" %-18s %14s %14s %14s %14s\n", 
-                            $_, $HoH{$sec}{"$_$dl$cols[0]"},
-                                $HoH{$sec}{"$_$dl$cols[1]"},
-                                $HoH{$sec}{"$_$dl$cols[2]"},
-                                $HoH{$sec}{"$_$dl$cols[3]"});
-        }
-    }
-    $res .= sprintf("%s\n", "-" x $width);
-    my $sec = 'SUM:';
-    $res .= "$sec\n";
-    foreach (@rows) {
-        $res .= sprintf(" %-18s %14s %14s %14s %14s\n", 
-                        $_, $HoH{$sec}{"$_$dl$cols[0]"},
-                            $HoH{$sec}{"$_$dl$cols[1]"},
-                            $HoH{$sec}{"$_$dl$cols[2]"},
-                            $HoH{$sec}{"$_$dl$cols[3]"});
-    }
-    $res .= sprintf("%s\n", "-" x $width);
-  
-    return $res;
-} # 1}}}
-# subroutines copied from SLOCCount
-my %lex_files    = ();  # really_is_lex()
-my %expect_files = ();  # really_is_expect()
-my %pascal_files = ();  # really_is_pascal(), really_is_incpascal()
-my %php_files    = ();  # really_is_php()
-sub really_is_lex {                          # {{{1
-# Given filename, returns TRUE if its contents really is lex.
-# lex file must have "%%", "%{", and "%}".
-# In theory, a lex file doesn't need "%{" and "%}", but in practice
-# they all have them, and requiring them avoid mislabeling a
-# non-lexfile as a lex file.
-
- my $filename = shift;
- chomp($filename);
-
- my $is_lex = 0;      # Value to determine.
- my $percent_percent = 0;
- my $percent_opencurly = 0;
- my $percent_closecurly = 0;
-
- # Return cached result, if available:
- if ($lex_files{$filename}) { return $lex_files{$filename};}
-
- open(LEX_FILE, "<$filename") ||
-      die "Can't open $filename to determine if it's lex.\n";
- while(<LEX_FILE>) {
-   $percent_percent++     if (m/^\s*\%\%/);
-   $percent_opencurly++   if (m/^\s*\%\{/);
-   $percent_closecurly++   if (m/^\s*\%\}/);
- }
- close(LEX_FILE);
-
- if ($percent_percent && $percent_opencurly && $percent_closecurly)
-          {$is_lex = 1;}
-
- $lex_files{$filename} = $is_lex; # Store result in cache.
-
- return $is_lex;
-} # 1}}}
-sub really_is_expect {                       # {{{1
-# Given filename, returns TRUE if its contents really are Expect.
-# Many "exp" files (such as in Apache and Mesa) are just "export" data,
-# summarizing something else # (e.g., its interface).
-# Sometimes (like in RPM) it's just misc. data.
-# Thus, we need to look at the file to determine
-# if it's really an "expect" file.
-
- my $filename = shift;
- chomp($filename);
-
-# The heuristic is as follows: it's Expect _IF_ it:
-# 1. has "load_lib" command and either "#" comments or {}.
-# 2. {, }, and one of: proc, if, [...], expect
-
- my $is_expect = 0;      # Value to determine.
-
- my $begin_brace = 0;  # Lines that begin with curly braces.
- my $end_brace = 0;    # Lines that begin with curly braces.
- my $load_lib = 0;     # Lines with the Load_lib command.
- my $found_proc = 0;
- my $found_if = 0;
- my $found_brackets = 0;
- my $found_expect = 0;
- my $found_pound = 0;
-
- # Return cached result, if available:
- if ($expect_files{$filename}) { return expect_files{$filename};}
-
- open(EXPECT_FILE, "<$filename") ||
-      die "Can't open $filename to determine if it's expect.\n";
- while(<EXPECT_FILE>) {
-
-   if (m/#/) {$found_pound++; s/#.*//;}
-   if (m/^\s*\{/) { $begin_brace++;}
-   if (m/\{\s*$/) { $begin_brace++;}
-   if (m/^\s*\}/) { $end_brace++;}
-   if (m/\};?\s*$/) { $end_brace++;}
-   if (m/^\s*load_lib\s+\S/) { $load_lib++;}
-   if (m/^\s*proc\s/) { $found_proc++;}
-   if (m/^\s*if\s/) { $found_if++;}
-   if (m/\[.*\]/) { $found_brackets++;}
-   if (m/^\s*expect\s/) { $found_expect++;}
- }
- close(EXPECT_FILE);
-
- if ($load_lib && ($found_pound || ($begin_brace && $end_brace)))
-          {$is_expect = 1;}
- if ( $begin_brace && $end_brace &&
-      ($found_proc || $found_if || $found_brackets || $found_expect))
-          {$is_expect = 1;}
-
- $expect_files{$filename} = $is_expect; # Store result in cache.
-
- return $is_expect;
-} # 1}}}
-sub really_is_pascal {                       # {{{1
-# Given filename, returns TRUE if its contents really are Pascal.
-
-# This isn't as obvious as it seems.
-# Many ".p" files are Perl files
-# (such as /usr/src/redhat/BUILD/ispell-3.1/dicts/czech/glob.p),
-# others are C extractions
-# (such as /usr/src/redhat/BUILD/linux/include/linux/umsdos_fs.p
-# and some files in linuxconf).
-# However, test files in "p2c" really are Pascal, for example.
-
-# Note that /usr/src/redhat/BUILD/ucd-snmp-4.1.1/ov/bitmaps/UCD.20.p
-# is actually C code.  The heuristics determine that they're not Pascal,
-# but because it ends in ".p" it's not counted as C code either.
-# I believe this is actually correct behavior, because frankly it
-# looks like it's automatically generated (it's a bitmap expressed as code).
-# Rather than guess otherwise, we don't include it in a list of
-# source files.  Let's face it, someone who creates C files ending in ".p"
-# and expects them to be counted by default as C files in SLOCCount needs
-# their head examined.  I suggest examining their head
-# with a sucker rod (see syslogd(8) for more on sucker rods).
-
-# This heuristic counts as Pascal such files such as:
-#  /usr/src/redhat/BUILD/teTeX-1.0/texk/web2c/tangleboot.p
-# Which is hand-generated.  We don't count woven documents now anyway,
-# so this is justifiable.
-
- my $filename = shift;
- chomp($filename);
-
-# The heuristic is as follows: it's Pascal _IF_ it has all of the following
-# (ignoring {...} and (*...*) comments):
-# 1. "^..program NAME" or "^..unit NAME",
-# 2. "procedure", "function", "^..interface", or "^..implementation",
-# 3. a "begin", and
-# 4. it ends with "end.",
-#
-# Or it has all of the following:
-# 1. "^..module NAME" and
-# 2. it ends with "end.".
-#
-# Or it has all of the following:
-# 1. "^..program NAME",
-# 2. a "begin", and
-# 3. it ends with "end.".
-#
-# The "end." requirements in particular filter out non-Pascal.
-#
-# Note (jgb): this does not detect Pascal main files in fpc, like
-# fpc-1.0.4/api/test/testterminfo.pas, which does not have "program" in
-# it
-
- my $is_pascal = 0;      # Value to determine.
-
- my $has_program = 0;
- my $has_unit = 0;
- my $has_module = 0;
- my $has_procedure_or_function = 0;
- my $found_begin = 0;
- my $found_terminating_end = 0;
- my $has_begin = 0;
-
- # Return cached result, if available:
- if ($pascal_files{$filename}) { return pascal_files{$filename};}
-
- open(PASCAL_FILE, "<$filename") ||
-      die "Can't open $filename to determine if it's pascal.\n";
- while(<PASCAL_FILE>) {
-   s/\{.*?\}//g;  # Ignore {...} comments on this line; imperfect, but effective.
-   s/\(\*.*?\*\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.
-   if (m/\bprogram\s+[A-Za-z]/i)  {$has_program=1;}
-   if (m/\bunit\s+[A-Za-z]/i)     {$has_unit=1;}
-   if (m/\bmodule\s+[A-Za-z]/i)   {$has_module=1;}
-   if (m/\bprocedure\b/i)         { $has_procedure_or_function = 1; }
-   if (m/\bfunction\b/i)          { $has_procedure_or_function = 1; }
-   if (m/^\s*interface\s+/i)      { $has_procedure_or_function = 1; }
-   if (m/^\s*implementation\s+/i) { $has_procedure_or_function = 1; }
-   if (m/\bbegin\b/i) { $has_begin = 1; }
-   # Originally I said:
-   # "This heuristic fails if there are multi-line comments after
-   # "end."; I haven't seen that in real Pascal programs:"
-   # But jgb found there are a good quantity of them in Debian, specially in 
-   # fpc (at the end of a lot of files there is a multiline comment
-   # with the changelog for the file).
-   # Therefore, assume Pascal if "end." appears anywhere in the file.
-   if (m/end\.\s*$/i) {$found_terminating_end = 1;}
-#   elsif (m/\S/) {$found_terminating_end = 0;}
- }
- close(PASCAL_FILE);
-
- # Okay, we've examined the entire file looking for clues;
- # let's use those clues to determine if it's really Pascal:
-
- if ( ( ($has_unit || $has_program) && $has_procedure_or_function &&
-     $has_begin && $found_terminating_end ) ||
-      ( $has_module && $found_terminating_end ) ||
-      ( $has_program && $has_begin && $found_terminating_end ) )
-          {$is_pascal = 1;}
-
- $pascal_files{$filename} = $is_pascal; # Store result in cache.
-
- return $is_pascal;
-} # 1}}}
-sub really_is_incpascal {                    # {{{1
-# Given filename, returns TRUE if its contents really are Pascal.
-# For .inc files (mainly seen in fpc)
-
- my $filename = shift;
- chomp($filename);
-
-# The heuristic is as follows: it is Pacal if any of the following:
-# 1. really_is_pascal returns true
-# 2. Any usual reserverd word is found (program, unit, const, begin...)
-
- # If the general routine for Pascal files works, we have it
- if (&really_is_pascal ($filename)) { 
-   $pascal_files{$filename} = 1;
-   return 1;
- }
-
- my $is_pascal = 0;      # Value to determine.
- my $found_begin = 0;
-
- open(PASCAL_FILE, "<$filename") ||
-      die "Can't open $filename to determine if it's pascal.\n";
- while(<PASCAL_FILE>) {
-   s/\{.*?\}//g;  # Ignore {...} comments on this line; imperfect, but effective.
-   s/\(\*.*?\*\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.
-   if (m/\bprogram\s+[A-Za-z]/i)  {$is_pascal=1;}
-   if (m/\bunit\s+[A-Za-z]/i)     {$is_pascal=1;}
-   if (m/\bmodule\s+[A-Za-z]/i)   {$is_pascal=1;}
-   if (m/\bprocedure\b/i)         {$is_pascal = 1; }
-   if (m/\bfunction\b/i)          {$is_pascal = 1; }
-   if (m/^\s*interface\s+/i)      {$is_pascal = 1; }
-   if (m/^\s*implementation\s+/i) {$is_pascal = 1; }
-   if (m/\bconstant\s+/i)         {$is_pascal=1;}
-   if (m/\bbegin\b/i) { $found_begin = 1; }
-   if ((m/end\.\s*$/i) && ($found_begin = 1)) {$is_pascal = 1;}
-   if ($is_pascal) {
-     last;
-   }
- }
-
- close(PASCAL_FILE);
- $pascal_files{$filename} = $is_pascal; # Store result in cache.
- return $is_pascal;
-} # 1}}}
-sub really_is_php {                          # {{{1
-# Given filename, returns TRUE if its contents really is php.
-
- my $filename = shift;
- chomp($filename);
-
- my $is_php = 0;      # Value to determine.
- # Need to find a matching pair of surrounds, with ending after beginning:
- my $normal_surround = 0;  # <?; bit 0 = <?, bit 1 = ?>
- my $script_surround = 0;  # <script..>; bit 0 = <script language="php">
- my $asp_surround = 0;     # <%; bit 0 = <%, bit 1 = %>
-
- # Return cached result, if available:
- if ($php_files{$filename}) { return $php_files{$filename};}
-
- open(PHP_FILE, "<$filename") ||
-      die "Can't open $filename to determine if it's php.\n";
- while(<PHP_FILE>) {
-   if (m/\<\?/)                           { $normal_surround |= 1; }
-   if (m/\?\>/ && ($normal_surround & 1)) { $normal_surround |= 2; }
-   if (m/\<script.*language="?php"?/i)    { $script_surround |= 1; }
-   if (m/\<\/script\>/i && ($script_surround & 1)) { $script_surround |= 2; }
-   if (m/\<\%/)                           { $asp_surround |= 1; }
-   if (m/\%\>/ && ($asp_surround & 1)) { $asp_surround |= 2; }
- }
- close(PHP_FILE);
-
- if ( ($normal_surround == 3) || ($script_surround == 3) ||
-      ($asp_surround == 3)) {
-   $is_php = 1;
- }
-
- $php_files{$filename} = $is_php; # Store result in cache.
-
- return $is_php;
-} # 1}}}
-__END__
-mode values (stat $item)[2]
-       Unix    Windows
-file:  33188   33206
-dir :  16832   16895
-link:  33261   33206
-pipe:   4544    null
Index: /issm/trunk/scripts/cloc-1.60.pl
===================================================================
--- /issm/trunk/scripts/cloc-1.60.pl	(revision 17989)
+++ /issm/trunk/scripts/cloc-1.60.pl	(revision 17989)
@@ -0,0 +1,9064 @@
+#!/usr/bin/env perl
+# cloc -- Count Lines of Code                  {{{1
+# Copyright (C) 2006-2013 Northrop Grumman Corporation
+# Author:  Al Danial <al.danial@gmail.com>
+#          First release August 2006
+#
+# Includes code from:
+#   - SLOCCount v2.26 
+#     http://www.dwheeler.com/sloccount/
+#     by David Wheeler.
+#   - Regexp::Common v2.120
+#     http://search.cpan.org/~abigail/Regexp-Common-2.120/lib/Regexp/Common.pm
+#     by Damian Conway and Abigail.
+#   - Win32::Autoglob 
+#     http://search.cpan.org/~sburke/Win32-Autoglob-1.01/Autoglob.pm
+#     by Sean M. Burke.
+#   - Algorithm::Diff
+#     http://search.cpan.org/~tyemq/Algorithm-Diff-1.1902/lib/Algorithm/Diff.pm
+#     by Tye McQueen.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details:
+# <http://www.gnu.org/licenses/gpl.txt>.
+#
+# 1}}}
+my $VERSION = "1.60";  # odd number == beta; even number == stable
+my $URL     = "http://cloc.sourceforge.net";
+require 5.006;
+# use modules                                  {{{1
+use warnings;
+use strict;
+use Getopt::Long;
+use File::Basename;
+use File::Temp qw { tempfile tempdir };
+use File::Find;
+use File::Path;
+use File::Spec;
+use IO::File;
+use POSIX "strftime";
+
+# Digest::MD5 isn't in the standard distribution. Use it only if installed.
+my $HAVE_Digest_MD5 = 0;
+eval "use Digest::MD5;";
+if (defined $Digest::MD5::VERSION) {
+    $HAVE_Digest_MD5 = 1;
+} else {
+    warn "Digest::MD5 not installed; will skip file uniqueness checks.\n";
+}
+
+# Time::HiRes became standard with Perl 5.8
+my $HAVE_Time_HiRes = 0;
+eval "use Time::HiRes;";
+$HAVE_Time_HiRes = 1 if defined $Time::HiRes::VERSION;
+
+my $HAVE_Rexexp_Common;
+# Regexp::Common isn't in the standard distribution.  It will
+# be installed in a temp directory if necessary.
+BEGIN {
+    if (eval "use Regexp::Common;") {
+        $HAVE_Rexexp_Common = 1;
+    } else {
+        $HAVE_Rexexp_Common = 0;
+    }
+}
+
+my $HAVE_Algorith_Diff = 0;
+# Algorithm::Diff isn't in the standard distribution.  It will
+# be installed in a temp directory if necessary.
+eval "use Algorithm::Diff qw ( sdiff ) ";
+if (defined $Algorithm::Diff::VERSION) {
+    $HAVE_Algorith_Diff = 1;
+} else {
+    Install_Algorithm_Diff();
+}
+# print "2 HAVE_Algorith_Diff = $HAVE_Algorith_Diff\n";
+# test_alg_diff($ARGV[$#ARGV - 1], $ARGV[$#ARGV]); die;
+
+# Uncomment next two lines when building Windows executable with perl2exe
+# or if running on a system that already has Regexp::Common.
+#use Regexp::Common;
+#$HAVE_Rexexp_Common = 1;
+
+#perl2exe_include "Regexp/Common/whitespace.pm"
+#perl2exe_include "Regexp/Common/URI.pm"
+#perl2exe_include "Regexp/Common/URI/fax.pm"
+#perl2exe_include "Regexp/Common/URI/file.pm"
+#perl2exe_include "Regexp/Common/URI/ftp.pm"
+#perl2exe_include "Regexp/Common/URI/gopher.pm"
+#perl2exe_include "Regexp/Common/URI/http.pm"
+#perl2exe_include "Regexp/Common/URI/pop.pm"
+#perl2exe_include "Regexp/Common/URI/prospero.pm"
+#perl2exe_include "Regexp/Common/URI/news.pm"
+#perl2exe_include "Regexp/Common/URI/tel.pm"
+#perl2exe_include "Regexp/Common/URI/telnet.pm"
+#perl2exe_include "Regexp/Common/URI/tv.pm"
+#perl2exe_include "Regexp/Common/URI/wais.pm"
+#perl2exe_include "Regexp/Common/CC.pm"
+#perl2exe_include "Regexp/Common/SEN.pm"
+#perl2exe_include "Regexp/Common/number.pm"
+#perl2exe_include "Regexp/Common/delimited.pm"
+#perl2exe_include "Regexp/Common/profanity.pm"
+#perl2exe_include "Regexp/Common/net.pm"
+#perl2exe_include "Regexp/Common/zip.pm"
+#perl2exe_include "Regexp/Common/comment.pm"
+#perl2exe_include "Regexp/Common/balanced.pm"
+#perl2exe_include "Regexp/Common/lingua.pm"
+#perl2exe_include "Regexp/Common/list.pm"
+#perl2exe_include "File/Glob.pm"
+
+use Text::Tabs qw { expand };
+use Cwd qw { cwd };
+use File::Glob;
+my $PERL_516 = $] >= 5.016 ? 1 : 0;  # 5.16 deprecates defined(@array)
+no warnings 'deprecated';            # will need to comment this out to test
+                                     # each new Perl version
+# 1}}}
+# Usage information, options processing.       {{{1
+my $ON_WINDOWS = 0;
+   $ON_WINDOWS = 1 if ($^O =~ /^MSWin/) or ($^O eq "Windows_NT");
+if ($ON_WINDOWS and $ENV{'SHELL'}) {
+    if ($ENV{'SHELL'} =~ m{^/}) {
+        $ON_WINDOWS = 0;  # make Cygwin look like Unix
+    } else {
+        $ON_WINDOWS = 1;  # MKS defines $SHELL but still acts like Windows
+    }
+}
+
+my $NN     = chr(27) . "[0m";  # normal
+   $NN     = "" if $ON_WINDOWS or !(-t STDERR); # -t STDERR:  is it a terminal?
+my $BB     = chr(27) . "[1m";  # bold
+   $BB     = "" if $ON_WINDOWS or !(-t STDERR);
+my $script = basename $0;
+my $usage  = "
+Usage: $script [options] <file(s)/dir(s)> | <set 1> <set 2> | <report files>
+
+ Count, or compute differences of, physical lines of source code in the
+ given files (may be archives such as compressed tarballs or zip files)
+ and/or recursively below the given directories.
+
+ ${BB}Input Options${NN}
+   --extract-with=<cmd>      This option is only needed if cloc is unable
+                             to figure out how to extract the contents of
+                             the input file(s) by itself.
+                             Use <cmd> to extract binary archive files (e.g.:
+                             .tar.gz, .zip, .Z).  Use the literal '>FILE<' as
+                             a stand-in for the actual file(s) to be
+                             extracted.  For example, to count lines of code
+                             in the input files
+                                gcc-4.2.tar.gz  perl-5.8.8.tar.gz
+                             on Unix use
+                               --extract-with='gzip -dc >FILE< | tar xf -'
+                             or, if you have GNU tar,
+                               --extract-with='tar zxf >FILE<'
+                             and on Windows use, for example:
+                               --extract-with=\"\\\"c:\\Program Files\\WinZip\\WinZip32.exe\\\" -e -o >FILE< .\"
+                             (if WinZip is installed there).
+   --list-file=<file>        Take the list of file and/or directory names to
+                             process from <file> which has one file/directory
+                             name per line.  See also --exclude-list-file.
+   --unicode                 Check binary files to see if they contain Unicode
+                             expanded ASCII text.  This causes performance to
+                             drop noticably.
+
+ ${BB}Processing Options${NN}
+   --autoconf                Count .in files (as processed by GNU autoconf) of
+                             recognized languages.
+   --by-file                 Report results for every source file encountered.
+   --by-file-by-lang         Report results for every source file encountered
+                             in addition to reporting by language.
+   --diff <set1> <set2>      Compute differences in code and comments between
+                             source file(s) of <set1> and <set2>.  The inputs
+                             may be pairs of files, directories, or archives.
+                             Use --diff-alignment to generate a list showing
+                             which file pairs where compared.  See also
+                             --ignore-case, --ignore-whitespace.
+   --diff-timeout <N>        Ignore files which take more than <N> seconds
+                             to process.  Default is 10 seconds.
+                             (Large files with many repeated lines can cause 
+                             Algorithm::Diff::sdiff() to take hours.)
+   --follow-links            [Unix only] Follow symbolic links to directories
+                             (sym links to files are always followed).
+   --force-lang=<lang>[,<ext>]
+                             Process all files that have a <ext> extension
+                             with the counter for language <lang>.  For
+                             example, to count all .f files with the
+                             Fortran 90 counter (which expects files to
+                             end with .f90) instead of the default Fortran 77
+                             counter, use
+                               --force-lang=\"Fortran 90\",f
+                             If <ext> is omitted, every file will be counted
+                             with the <lang> counter.  This option can be
+                             specified multiple times (but that is only
+                             useful when <ext> is given each time).
+                             See also --script-lang, --lang-no-ext.
+   --force-lang-def=<file>   Load language processing filters from <file>,
+                             then use these filters instead of the built-in
+                             filters.  Note:  languages which map to the same 
+                             file extension (for example:
+                             MATLAB/Objective C/MUMPS;  Pascal/PHP; 
+                             Lisp/OpenCL) will be ignored as these require 
+                             additional processing that is not expressed in 
+                             language definition files.  Use --read-lang-def 
+                             to define new language filters without replacing 
+                             built-in filters (see also --write-lang-def).
+   --ignore-whitespace       Ignore horizontal white space when comparing files
+                             with --diff.  See also --ignore-case.
+   --ignore-case             Ignore changes in case; consider upper- and lower-
+                             case letters equivalent when comparing files with
+                             --diff.  See also --ignore-whitespace.
+   --lang-no-ext=<lang>      Count files without extensions using the <lang>
+                             counter.  This option overrides internal logic
+                             for files without extensions (where such files
+                             are checked against known scripting languages
+                             by examining the first line for #!).  See also
+                             --force-lang, --script-lang.
+   --max-file-size=<MB>      Skip files larger than <MB> megabytes when
+                             traversing directories.  By default, <MB>=100.
+                             cloc's memory requirement is roughly twenty times 
+                             larger than the largest file so running with 
+                             files larger than 100 MB on a computer with less 
+                             than 2 GB of memory will cause problems.  
+                             Note:  this check does not apply to files 
+                             explicitly passed as command line arguments.
+   --read-binary-files       Process binary files in addition to text files.
+                             This is usually a bad idea and should only be
+                             attempted with text files that have embedded
+                             binary data.
+   --read-lang-def=<file>    Load new language processing filters from <file>
+                             and merge them with those already known to cloc.  
+                             If <file> defines a language cloc already knows 
+                             about, cloc's definition will take precedence.  
+                             Use --force-lang-def to over-ride cloc's 
+                             definitions (see also --write-lang-def ).
+   --script-lang=<lang>,<s>  Process all files that invoke <s> as a #!
+                             scripting language with the counter for language
+                             <lang>.  For example, files that begin with
+                                #!/usr/local/bin/perl5.8.8
+                             will be counted with the Perl counter by using
+                                --script-lang=Perl,perl5.8.8
+                             The language name is case insensitive but the
+                             name of the script language executable, <s>,
+                             must have the right case.  This option can be
+                             specified multiple times.  See also --force-lang,
+                             --lang-no-ext.
+   --sdir=<dir>              Use <dir> as the scratch directory instead of
+                             letting File::Temp chose the location.  Files
+                             written to this location are not removed at
+                             the end of the run (as they are with File::Temp).
+   --skip-uniqueness         Skip the file uniqueness check.  This will give
+                             a performance boost at the expense of counting
+                             files with identical contents multiple times
+                             (if such duplicates exist).
+   --stdin-name=<file>       Give a file name to use to determine the language
+                             for standard input.
+   --strip-comments=<ext>    For each file processed, write to the current
+                             directory a version of the file which has blank
+                             lines and comments removed.  The name of each
+                             stripped file is the original file name with
+                             .<ext> appended to it.  It is written to the
+                             current directory unless --original-dir is on.
+   --original-dir            [Only effective in combination with
+                             --strip-comments]  Write the stripped files
+                             to the same directory as the original files.
+   --sum-reports             Input arguments are report files previously
+                             created with the --report-file option.  Makes
+                             a cumulative set of results containing the
+                             sum of data from the individual report files.
+   --unix                    Override the operating system autodetection
+                             logic and run in UNIX mode.  See also
+                             --windows, --show-os.
+   --windows                 Override the operating system autodetection
+                             logic and run in Microsoft Windows mode.
+                             See also --unix, --show-os.
+
+ ${BB}Filter Options${NN}
+   --exclude-dir=<D1>[,D2,]  Exclude the given comma separated directories
+                             D1, D2, D3, et cetera, from being scanned.  For
+                             example  --exclude-dir=.cache,test  will skip
+                             all files that have /.cache/ or /test/ as part
+                             of their path.
+                             Directories named .bzr, .cvs, .hg, .git, and
+                             .svn are always excluded.
+   --exclude-ext=<ext1>[,<ext2>[...]]
+                             Do not count files having the given file name
+                             extensions.
+   --exclude-lang=<L1>[,L2,] Exclude the given comma separated languages
+                             L1, L2, L3, et cetera, from being counted.
+   --exclude-list-file=<file>  Ignore files and/or directories whose names
+                             appear in <file>.  <file> should have one entry
+                             per line.  Relative path names will be resolved
+                             starting from the directory where cloc is
+                             invoked.  See also --list-file.
+   --match-d=<regex>         Only count files in directories matching the Perl
+                             regex.  For example
+                               --match-d='/(src|include)/'
+                             only counts files in directories containing
+                             /src/ or /include/.
+   --not-match-d=<regex>     Count all files except those in directories
+                             matching the Perl regex.
+   --match-f=<regex>         Only count files whose basenames match the Perl
+                             regex.  For example
+                               --match-f='^[Ww]idget'
+                             only counts files that start with Widget or widget.
+   --not-match-f=<regex>     Count all files except those whose basenames
+                             match the Perl regex.
+   --skip-archive=<regex>    Ignore files that end with the given Perl regular
+                             expression.  For example, if given
+                               --skip-archive='(zip|tar(\.(gz|Z|bz2|xz|7z))?)'
+                             the code will skip files that end with .zip,
+                             .tar, .tar.gz, .tar.Z, .tar.bz2, .tar.xz, and
+                             .tar.7z.
+   --skip-win-hidden         On Windows, ignore hidden files.
+
+ ${BB}Debug Options${NN}
+   --categorized=<file>      Save names of categorized files to <file>.
+   --counted=<file>          Save names of processed source files to <file>.
+   --diff-alignment=<file>   Write to <file> a list of files and file pairs
+                             showing which files were added, removed, and/or
+                             compared during a run with --diff.  This switch
+                             forces the --diff mode on.
+   --help                    Print this usage information and exit.
+   --found=<file>            Save names of every file found to <file>.
+   --ignored=<file>          Save names of ignored files and the reason they
+                             were ignored to <file>.
+   --print-filter-stages     Print to STDOUT processed source code before and
+                             after each filter is applied.
+   --show-ext[=<ext>]        Print information about all known (or just the
+                             given) file extensions and exit.
+   --show-lang[=<lang>]      Print information about all known (or just the
+                             given) languages and exit.
+   --show-os                 Print the value of the operating system mode
+                             and exit.  See also --unix, --windows.
+   -v[=<n>]                  Verbose switch (optional numeric value).
+   --version                 Print the version of this program and exit.
+   --write-lang-def=<file>   Writes to <file> the language processing filters
+                             then exits.  Useful as a first step to creating
+                             custom language definitions (see also
+                             --force-lang-def, --read-lang-def).
+
+ ${BB}Output Options${NN}
+   --3                       Print third-generation language output.
+                             (This option can cause report summation to fail
+                             if some reports were produced with this option
+                             while others were produced without it.)
+   --progress-rate=<n>       Show progress update after every <n> files are
+                             processed (default <n>=100).  Set <n> to 0 to
+                             suppress progress output (useful when redirecting
+                             output to STDOUT).
+   --quiet                   Suppress all information messages except for
+                             the final report.
+   --report-file=<file>      Write the results to <file> instead of STDOUT.
+   --out=<file>              Synonym for --report-file=<file>.
+   --csv                     Write the results as comma separated values.
+   --csv-delimiter=<C>       Use the character <C> as the delimiter for comma
+                             separated files instead of ,.  This switch forces
+                             --csv to be on.
+   --sql=<file>              Write results as SQL create and insert statements
+                             which can be read by a database program such as
+                             SQLite.  If <file> is -, output is sent to STDOUT.
+   --sql-project=<name>      Use <name> as the project identifier for the
+                             current run.  Only valid with the --sql option.
+   --sql-append              Append SQL insert statements to the file specified
+                             by --sql and do not generate table creation
+                             statements.  Only valid with the --sql option.
+   --sum-one                 For plain text reports, show the SUM: output line
+                             even if only one input file is processed.
+   --xml                     Write the results in XML.
+   --xsl=<file>              Reference <file> as an XSL stylesheet within
+                             the XML output.  If <file> is 1 (numeric one),
+                             writes a default stylesheet, cloc.xsl (or
+                             cloc-diff.xsl if --diff is also given).
+                             This switch forces --xml on.
+   --yaml                    Write the results in YAML.
+
+";
+#  Help information for options not yet implemented:
+#  --inline                  Process comments that appear at the end
+#                            of lines containing code.
+#  --html                    Create HTML files of each input file showing
+#                            comment and code lines in different colors.
+
+$| = 1;  # flush STDOUT
+my $start_time = get_time();
+my (
+    $opt_categorized          ,
+    $opt_found                ,
+    @opt_force_lang           ,
+    $opt_lang_no_ext          ,
+    @opt_script_lang          ,
+    $opt_diff                 ,
+    $opt_diff_alignment       ,
+    $opt_diff_timeout         ,
+    $opt_html                 ,
+    $opt_ignored              ,
+    $opt_counted              ,
+    $opt_show_ext             ,
+    $opt_show_lang            ,
+    $opt_progress_rate        ,
+    $opt_print_filter_stages  ,
+    $opt_v                    ,
+    $opt_version              ,
+    $opt_exclude_lang         ,
+    $opt_exclude_list_file    ,
+    $opt_exclude_dir          ,
+    $opt_force_lang_def       ,
+    $opt_read_lang_def        ,
+    $opt_write_lang_def       ,
+    $opt_strip_comments       ,
+    $opt_original_dir         ,
+    $opt_quiet                ,
+    $opt_report_file          ,
+    $opt_sdir                 ,
+    $opt_sum_reports          ,
+    $opt_unicode              ,
+    $opt_no3                  ,   # accept it but don't use it
+    $opt_3                    ,
+    $opt_extract_with         ,
+    $opt_by_file              ,
+    $opt_by_file_by_lang      ,
+    $opt_xml                  ,
+    $opt_xsl                  ,
+    $opt_yaml                 ,
+    $opt_csv                  ,
+    $opt_csv_delimiter        ,
+    $opt_match_f              ,
+    $opt_not_match_f          ,
+    $opt_match_d              ,
+    $opt_not_match_d          ,
+    $opt_skip_uniqueness      ,
+    $opt_list_file            ,
+    $opt_help                 ,
+    $opt_skip_win_hidden      ,
+    $opt_read_binary_files    ,
+    $opt_sql                  ,
+    $opt_sql_append           ,
+    $opt_sql_project          ,
+    $opt_inline               ,
+    $opt_exclude_ext          ,
+    $opt_ignore_whitespace    ,
+    $opt_ignore_case          ,
+    $opt_follow_links         ,
+    $opt_autoconf             ,
+    $opt_sum_one              ,
+    $opt_stdin_name           ,
+    $opt_force_on_windows     ,
+    $opt_force_on_unix        ,   # actually forces !$ON_WINDOWS
+    $opt_show_os              ,
+    $opt_skip_archive         ,
+    $opt_max_file_size        ,   # in MB
+   );
+my $getopt_success = GetOptions(
+   "by_file|by-file"                         => \$opt_by_file             ,
+   "by_file_by_lang|by-file-by-lang"         => \$opt_by_file_by_lang     ,
+   "categorized=s"                           => \$opt_categorized         ,
+   "counted=s"                               => \$opt_counted             ,
+   "exclude_lang|exclude-lang=s"             => \$opt_exclude_lang        ,
+   "exclude_dir|exclude-dir=s"               => \$opt_exclude_dir         ,
+   "exclude_list_file|exclude-list-file=s"   => \$opt_exclude_list_file   ,
+   "extract_with|extract-with=s"             => \$opt_extract_with        ,
+   "found=s"                                 => \$opt_found               ,
+   "diff"                                    => \$opt_diff                ,
+   "diff-alignment|diff_alignment=s"         => \$opt_diff_alignment      ,
+   "diff-timeout|diff_timeout=i"             => \$opt_diff_timeout        ,
+   "html"                                    => \$opt_html                ,
+   "ignored=s"                               => \$opt_ignored             ,
+   "quiet"                                   => \$opt_quiet               ,
+   "force_lang_def|force-lang-def=s"         => \$opt_force_lang_def      ,
+   "read_lang_def|read-lang-def=s"           => \$opt_read_lang_def       ,
+   "show_ext|show-ext:s"                     => \$opt_show_ext            ,
+   "show_lang|show-lang:s"                   => \$opt_show_lang           ,
+   "progress_rate|progress-rate=i"           => \$opt_progress_rate       ,
+   "print_filter_stages|print-filter-stages" => \$opt_print_filter_stages ,
+   "report_file|report-file=s"               => \$opt_report_file         ,
+   "out=s"                                   => \$opt_report_file         ,
+   "script_lang|script-lang=s"               => \@opt_script_lang         ,
+   "sdir=s"                                  => \$opt_sdir                ,
+   "skip_uniqueness|skip-uniqueness"         => \$opt_skip_uniqueness     ,
+   "strip_comments|strip-comments=s"         => \$opt_strip_comments      ,
+   "original_dir|original-dir"               => \$opt_original_dir        ,
+   "sum_reports|sum-reports"                 => \$opt_sum_reports         ,
+   "unicode"                                 => \$opt_unicode             ,
+   "no3"                                     => \$opt_no3                 ,  # ignored
+   "3"                                       => \$opt_3                   ,
+   "v:i"                                     => \$opt_v                   ,
+   "version"                                 => \$opt_version             ,
+   "write_lang_def|write-lang-def=s"         => \$opt_write_lang_def      ,
+   "xml"                                     => \$opt_xml                 ,
+   "xsl=s"                                   => \$opt_xsl                 ,
+   "force_lang|force-lang=s"                 => \@opt_force_lang          ,
+   "lang_no_ext|lang-no-ext=s"               => \$opt_lang_no_ext         ,
+   "yaml"                                    => \$opt_yaml                ,
+   "csv"                                     => \$opt_csv                 ,
+   "csv_delimeter|csv-delimiter=s"           => \$opt_csv_delimiter       ,
+   "match_f|match-f=s"                       => \$opt_match_f             ,
+   "not_match_f|not-match-f=s"               => \$opt_not_match_f         ,
+   "match_d|match-d=s"                       => \$opt_match_d             ,
+   "not_match_d|not-match-d=s"               => \$opt_not_match_d         ,
+   "list_file|list-file=s"                   => \$opt_list_file           ,
+   "help"                                    => \$opt_help                ,
+   "skip_win_hidden|skip-win-hidden"         => \$opt_skip_win_hidden     ,
+   "read_binary_files|read-binary-files"     => \$opt_read_binary_files   ,
+   "sql=s"                                   => \$opt_sql                 ,
+   "sql_project|sql-project=s"               => \$opt_sql_project         ,
+   "sql_append|sql-append"                   => \$opt_sql_append          ,
+   "inline"                                  => \$opt_inline              ,
+   "exclude_ext|exclude-ext=s"               => \$opt_exclude_ext         ,
+   "ignore_whitespace|ignore-whitespace"     => \$opt_ignore_whitespace   ,
+   "ignore_case|ignore-case"                 => \$opt_ignore_case         ,
+   "follow_links|follow-links"               => \$opt_follow_links        ,
+   "autoconf"                                => \$opt_autoconf            ,
+   "sum_one|sum-one"                         => \$opt_sum_one             ,
+   "stdin_name|stdin-name=s"                 => \$opt_stdin_name          ,
+   "windows"                                 => \$opt_force_on_windows    ,
+   "unix"                                    => \$opt_force_on_unix       ,
+   "show_os|show-os"                         => \$opt_show_os             ,
+   "skip_archive|skip-archive=s"             => \$opt_skip_archive        ,
+   "max_file_size|max-file-size=i"           => \$opt_max_file_size       ,
+  );
+$opt_by_file  = 1 if defined  $opt_by_file_by_lang;
+my $CLOC_XSL = "cloc.xsl"; # created with --xsl
+   $CLOC_XSL = "cloc-diff.xsl" if $opt_diff;
+die "\n" unless $getopt_success;
+die $usage if $opt_help;
+my %Exclude_Language = ();
+   %Exclude_Language = map { $_ => 1 } split(/,/, $opt_exclude_lang) 
+        if $opt_exclude_lang;
+my %Exclude_Dir      = ();
+   %Exclude_Dir      = map { $_ => 1 } split(/,/, $opt_exclude_dir ) 
+        if $opt_exclude_dir ;
+# Forcibly exclude .svn, .cvs, .hg, .git, .bzr directories.  The contents of these
+# directories often conflict with files of interest.
+$opt_exclude_dir       = 1;
+$Exclude_Dir{".svn"}   = 1;
+$Exclude_Dir{".cvs"}   = 1;
+$Exclude_Dir{".hg"}    = 1;
+$Exclude_Dir{".git"}   = 1;
+$Exclude_Dir{".bzr"}   = 1;
+$opt_diff              = 1  if $opt_diff_alignment;
+$opt_exclude_ext       = "" unless $opt_exclude_ext;
+$opt_ignore_whitespace = 0  unless $opt_ignore_whitespace;
+$opt_ignore_case       = 0  unless $opt_ignore_case;
+$opt_lang_no_ext       = 0  unless $opt_lang_no_ext;
+$opt_follow_links      = 0  unless $opt_follow_links;
+$opt_diff_timeout      =10  unless $opt_diff_timeout;
+$opt_csv               = 1  if $opt_csv_delimiter;
+$ON_WINDOWS            = 1  if $opt_force_on_windows;
+$ON_WINDOWS            = 0  if $opt_force_on_unix;
+$opt_max_file_size     = 100 unless $opt_max_file_size;
+
+# Options defaults:
+$opt_progress_rate = 100 unless defined $opt_progress_rate;
+if (!defined $opt_v) {
+    $opt_v  = 0;
+} elsif (!$opt_v) {
+    $opt_v  = 1;
+}
+if (defined $opt_xsl) {
+    $opt_xsl = $CLOC_XSL if $opt_xsl eq "1";
+    $opt_xml = 1;
+}
+my $skip_generate_report = 0;
+$opt_sql = 0 unless defined $opt_sql;
+if ($opt_sql eq "-" || $opt_sql eq "1") { # stream SQL output to STDOUT
+    $opt_quiet            = 1;
+    $skip_generate_report = 1;
+    $opt_by_file          = 1;
+    $opt_sum_reports      = 0;
+    $opt_progress_rate    = 0;
+} elsif ($opt_sql)  { # write SQL output to a file
+    $opt_by_file          = 1;
+    $skip_generate_report = 1;
+    $opt_sum_reports      = 0;
+}
+
+die $usage unless defined $opt_version         or
+                  defined $opt_show_lang       or
+                  defined $opt_show_ext        or
+                  defined $opt_show_os         or
+                  defined $opt_write_lang_def  or
+                  defined $opt_list_file       or
+                  defined $opt_xsl             or
+                  scalar @ARGV >= 1;
+die "--diff requires at least two arguments\n" 
+    if $opt_diff and scalar @ARGV < 2;
+if ($opt_version) {
+    printf "$VERSION\n";
+    exit;
+}
+# 1}}}
+# Step 1:  Initialize global constants.        {{{1
+#
+my $nFiles_Found = 0;  # updated in make_file_list
+my (%Language_by_Extension, %Language_by_Script,
+    %Filters_by_Language, %Not_Code_Extension, %Not_Code_Filename,
+    %Language_by_File, %Scale_Factor, %Known_Binary_Archives,
+    %EOL_Continuation_re,
+   );
+my $ALREADY_SHOWED_HEADER = 0;
+my $ALREADY_SHOWED_XML_SECTION = 0;
+my %Error_Codes = ( 'Unable to read'                => -1,
+                    'Neither file nor directory'    => -2, 
+                    'Diff error (quoted comments?)' => -3, 
+                    'Diff error, exceeded timeout'  => -4, 
+                  );
+if ($opt_force_lang_def) {
+    # replace cloc's definitions
+    read_lang_def(
+        $opt_force_lang_def    , #        Sample values:
+        \%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77' 
+        \%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'
+        \%Language_by_File     , # Language_by_File{makefile}  = 'make'
+        \%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] = 
+                                 #      [ 'remove_matches' , '^\s*#'  ]
+        \%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1
+        \%Not_Code_Filename    , # Not_Code_Filename{README}   = 1
+        \%Scale_Factor         , # Scale_Factor{Perl}          = 4.0
+        \%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\$'
+        );
+} else {
+    set_constants(               #
+        \%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77' 
+        \%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'
+        \%Language_by_File     , # Language_by_File{makefile}  = 'make'
+        \%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] = 
+                                 #      [ 'remove_matches' , '^\s*#'  ]
+        \%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1
+        \%Not_Code_Filename    , # Not_Code_Filename{README}   = 1
+        \%Scale_Factor         , # Scale_Factor{Perl}          = 4.0
+        \%Known_Binary_Archives, # Known_Binary_Archives{.tar} = 1
+        \%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\$'
+        );
+}
+if ($opt_read_lang_def) {
+    # augment cloc's definitions (keep cloc's where there are overlaps)
+    merge_lang_def(
+        $opt_read_lang_def     , #        Sample values:
+        \%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77' 
+        \%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'
+        \%Language_by_File     , # Language_by_File{makefile}  = 'make'
+        \%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] = 
+                                 #      [ 'remove_matches' , '^\s*#'  ]
+        \%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1
+        \%Not_Code_Filename    , # Not_Code_Filename{README}   = 1
+        \%Scale_Factor         , # Scale_Factor{Perl}          = 4.0
+        \%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\$'
+        );
+}
+if ($opt_lang_no_ext and !defined $Filters_by_Language{$opt_lang_no_ext}) {
+    die_unknown_lang($opt_lang_no_ext, "--lang-no-ext")
+}
+
+# Process command line provided extention-to-language mapping overrides.
+# Make a hash of known languages in lower case for easier matching.
+my %Recognized_Language_lc = (); # key = language name in lc, value = true name
+foreach my $language (keys %Filters_by_Language) {
+    my $lang_lc = lc $language;
+    $Recognized_Language_lc{$lang_lc} = $language;
+}
+my %Forced_Extension = (); # file name extensions which user wants to count
+my $All_One_Language = 0;  # set to !0 if --force-lang's <ext> is missing
+foreach my $pair (@opt_force_lang) {
+    my ($lang, $extension) = split(',', $pair);
+    my $lang_lc = lc $lang;
+    if (defined $extension) {
+        $Forced_Extension{$extension} = $lang;
+
+        die_unknown_lang($lang, "--force-lang")
+            unless $Recognized_Language_lc{$lang_lc}; 
+
+        $Language_by_Extension{$extension} = $Recognized_Language_lc{$lang_lc};
+    } else {
+        # the scary case--count everything as this language
+        $All_One_Language = $Recognized_Language_lc{$lang_lc};
+    }
+}
+
+foreach my $pair (@opt_script_lang) {
+    my ($lang, $script_name) = split(',', $pair);
+    my $lang_lc = lc $lang;
+    if (!defined $script_name) {
+        die "The --script-lang option requires a comma separated pair of ".
+            "strings.\n";
+    }
+
+    die_unknown_lang($lang, "--script-lang")
+        unless $Recognized_Language_lc{$lang_lc}; 
+
+    $Language_by_Script{$script_name} = $Recognized_Language_lc{$lang_lc};
+}
+
+# If user provided file extensions to ignore, add these to
+# the exclusion list.
+foreach my $ext (map { $_ => 1 } split(/,/, $opt_exclude_ext ) ) {
+    $ext = lc $ext if $ON_WINDOWS;
+    $Not_Code_Extension{$ext} = 1;
+}
+
+# If SQL or --by-file output is requested, keep track of directory names
+# generated by File::Temp::tempdir and used to temporarily hold the results
+# of compressed archives.  Contents of the SQL table 't' will be much
+# cleaner if these meaningless directory names are stripped from the front
+# of files pulled from the archives.
+my %TEMP_DIR = ();
+my $TEMP_OFF =  0;  # Needed for --sdir; keep track of the number of
+                    # scratch directories made in this run to avoid
+                    # file overwrites by multiple extractions to same
+                    # sdir.
+# Also track locations where temporary installations, if necessary, of
+# Algorithm::Diff and/or Regexp::Common are done.  Make sure these 
+# directories are not counted as inputs (ref bug #80 2012-11-23).
+my %TEMP_INST = ();
+
+# invert %Language_by_Script hash to get an easy-to-look-up list of known
+# scripting languages
+my %Script_Language = map { $_ => 1 } values %Language_by_Script ;
+# 1}}}
+# Step 2:  Early exits for display, summation. {{{1
+#
+print_extension_info($opt_show_ext ) if defined $opt_show_ext ;
+print_language_info( $opt_show_lang) if defined $opt_show_lang;
+exit if (defined $opt_show_ext) or (defined $opt_show_lang);
+
+#print "Before glob have [", join(",", @ARGV), "]\n";
+@ARGV = windows_glob(@ARGV) if $ON_WINDOWS;
+#print "after  glob have [", join(",", @ARGV), "]\n";
+
+# filter out archive files if requested to do so
+if (defined $opt_skip_archive) {
+    my @non_archive = ();
+    foreach my $candidate (@ARGV) {
+        if ($candidate !~ m/${opt_skip_archive}$/) {
+            push @non_archive, $candidate;
+
+        } 
+    }
+    @ARGV = @non_archive;
+}
+
+if ($opt_sum_reports and $opt_diff) {
+    my @results = ();
+    if ($opt_list_file) { # read inputs from the list file
+        my @list = read_list_file($opt_list_file);
+        @results = combine_diffs(\@list);
+    } else { # get inputs from the command line
+        @results = combine_diffs(\@ARGV);
+    }
+    if ($opt_report_file) {
+        write_file($opt_report_file, @results);
+    } else {
+        print "\n", join("\n", @results), "\n";
+    }
+    exit;
+}
+if ($opt_sum_reports) {
+    my %Results = ();
+    foreach my $type( "by language", "by report file" ) {
+        my $found_lang = undef; 
+        if ($opt_list_file) { # read inputs from the list file
+            my @list = read_list_file($opt_list_file);
+            $found_lang = combine_results(\@list, 
+                                           $type, 
+                                          \%{$Results{ $type }}, 
+                                          \%Filters_by_Language );
+        } else { # get inputs from the command line
+            $found_lang = combine_results(\@ARGV, 
+                                           $type, 
+                                          \%{$Results{ $type }}, 
+                                          \%Filters_by_Language );
+        }
+        next unless %Results;
+        my $end_time = get_time();
+        my @results  = generate_report($VERSION, $end_time - $start_time,
+                                       $type,
+                                      \%{$Results{ $type }}, \%Scale_Factor);
+        if ($opt_report_file) {
+            my $ext  = ".lang";
+               $ext  = ".file" unless $type eq "by language";
+            next if !$found_lang and  $ext  eq ".lang";
+            write_file($opt_report_file . $ext, @results);
+        } else {
+            print "\n", join("\n", @results), "\n";
+        }
+    }
+    exit;
+}
+if ($opt_write_lang_def) {
+    write_lang_def($opt_write_lang_def   ,
+                  \%Language_by_Extension,
+                  \%Language_by_Script   ,
+                  \%Language_by_File     ,
+                  \%Filters_by_Language  ,
+                  \%Not_Code_Extension   ,
+                  \%Not_Code_Filename    ,
+                  \%Scale_Factor         ,
+                  \%EOL_Continuation_re  ,
+                  );
+    exit;
+}
+if ($opt_show_os) {
+    if ($ON_WINDOWS) {
+        print "Windows\n";
+    } else {
+        print "UNIX\n";
+    }
+    exit;
+}
+# 1}}}
+# Step 3:  Create a list of files to consider. {{{1
+#  a) If inputs are binary archives, first cd to a temp
+#     directory, expand the archive with the user-given
+#     extraction tool, then add the temp directory to
+#     the list of dirs to process.
+#  b) Create a list of every file that might contain source
+#     code.  Ignore binary files, zero-sized files, and
+#     any file in a directory the user says to exclude.
+#  c) Determine the language for each file in the list.
+#
+my @binary_archive = ();
+my $cwd            = cwd();
+if ($opt_extract_with) {
+#print "cwd main = [$cwd]\n";
+    my @extract_location = ();
+    foreach my $bin_file (@ARGV) {
+        my $extract_dir = undef;
+        if ($opt_sdir) {
+            ++$TEMP_OFF;
+            $extract_dir = "$opt_sdir/$TEMP_OFF";
+            File::Path::rmtree($extract_dir) if     is_dir($extract_dir);
+            File::Path::mkpath($extract_dir) unless is_dir($extract_dir);
+        } else {
+            $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
+        }
+        $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;
+        print "mkdir $extract_dir\n"  if $opt_v;
+        print "cd    $extract_dir\n"  if $opt_v;
+        chdir $extract_dir;
+        my $bin_file_full_path = "";
+        if (File::Spec->file_name_is_absolute( $bin_file )) {
+            $bin_file_full_path = $bin_file;
+#print "bin_file_full_path (was ful) = [$bin_file_full_path]\n";
+        } else {
+            $bin_file_full_path = File::Spec->catfile( $cwd, $bin_file );
+#print "bin_file_full_path (was rel) = [$bin_file_full_path]\n";
+        }
+        my     $extract_cmd = uncompress_archive_cmd($bin_file_full_path);
+        print  $extract_cmd, "\n" if $opt_v;
+        system $extract_cmd;
+        push @extract_location, $extract_dir;
+        chdir $cwd;
+    }
+    # It is possible that the binary archive itself contains additional
+    # files compressed the same way (true for Java .ear files).  Go
+    # through all the files that were extracted, see if they are binary
+    # archives and try to extract them.  Lather, rinse, repeat.
+    my $binary_archives_exist = 1;
+    my $count_binary_archives = 0;
+    my $previous_count        = 0;
+    my $n_pass                = 0;
+    while ($binary_archives_exist) {
+        @binary_archive = ();
+        foreach my $dir (@extract_location) {
+            find(\&archive_files, $dir);  # populates global @binary_archive
+        }
+        foreach my $archive (@binary_archive) {
+            my $extract_dir = undef;
+            if ($opt_sdir) {
+                ++$TEMP_OFF;
+                $extract_dir = "$opt_sdir/$TEMP_OFF";
+                File::Path::rmtree($extract_dir) if     is_dir($extract_dir);
+                File::Path::mkpath($extract_dir) unless is_dir($extract_dir);
+            } else {
+                $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
+            }
+            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;
+            print "mkdir $extract_dir\n"  if $opt_v;
+            print "cd    $extract_dir\n"  if $opt_v;
+            chdir  $extract_dir;
+
+            my     $extract_cmd = uncompress_archive_cmd($archive);
+            print  $extract_cmd, "\n" if $opt_v;
+            system $extract_cmd;
+            push @extract_location, $extract_dir;
+            unlink $archive;  # otherwise will be extracting it forever 
+        }
+        $count_binary_archives = scalar @binary_archive;
+        if ($count_binary_archives == $previous_count) {
+            $binary_archives_exist = 0;
+        }
+        $previous_count = $count_binary_archives;
+    }
+    chdir $cwd;
+
+    @ARGV = @extract_location;
+} else {
+    # see if any of the inputs need to be auto-uncompressed &/or expanded
+    my @updated_ARGS = ();
+    foreach my $Arg (@ARGV) {
+        if (is_dir($Arg)) {
+            push @updated_ARGS, $Arg;
+            next;
+        }
+        my $full_path = "";
+        if (File::Spec->file_name_is_absolute( $Arg )) {
+            $full_path = $Arg;
+        } else {
+            $full_path = File::Spec->catfile( $cwd, $Arg );
+        }
+#print "full_path = [$full_path]\n";
+        my $extract_cmd = uncompress_archive_cmd($full_path);
+        if ($extract_cmd) {
+            my $extract_dir = undef;
+            if ($opt_sdir) {
+                ++$TEMP_OFF;
+                $extract_dir = "$opt_sdir/$TEMP_OFF";
+                File::Path::rmtree($extract_dir) if     is_dir($extract_dir);
+                File::Path::mkpath($extract_dir) unless is_dir($extract_dir);
+            } else {
+                $extract_dir = tempdir( CLEANUP => 1 ); # 1 = delete on exit
+            }
+            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;
+            print "mkdir $extract_dir\n"  if $opt_v;
+            print "cd    $extract_dir\n"  if $opt_v;
+            chdir  $extract_dir;
+            print  $extract_cmd, "\n" if $opt_v;
+            system $extract_cmd;
+            push @updated_ARGS, $extract_dir;
+            chdir $cwd;
+        } else {
+            # this is a conventional, uncompressed, unarchived file
+            # or a directory; keep as-is
+            push @updated_ARGS, $Arg;
+        }
+    }
+    @ARGV = @updated_ARGS;
+
+    # make sure we're not counting any directory containing
+    # temporary installations of Regexp::Common, Algorithm::Diff
+    foreach my $d (sort keys %TEMP_INST) {
+        foreach my $a (@ARGV) {
+            next unless is_dir($a);
+            if ($opt_v > 2) {
+                printf "Comparing %s (location of %s) to input [%s]\n",
+                        $d, $TEMP_INST{$d}, $a;
+            }
+            if ($a eq $d) {
+                die "File::Temp::tempdir chose directory ",
+                    $d, " to install ", $TEMP_INST{$d}, " but this ",
+                    "matches one of your input directories.  Rerun ",
+                    "with --sdir and supply a different temporary ",
+                    "directory for ", $TEMP_INST{$d}, "\n";
+            }
+        }
+    }
+}
+# 1}}}
+my @Errors    = ();
+my @file_list = ();  # global variable updated in files()
+my %Ignored   = ();  # files that are not counted (language not recognized or
+                     # problems reading the file)
+my @Lines_Out = ();
+if ($opt_diff) {
+# Step 4:  Separate code from non-code files.  {{{1
+my @fh            = ();
+my @files_for_set = ();
+# make file lists for each separate argument
+if ($opt_exclude_list_file) {
+    process_exclude_list_file($opt_exclude_list_file, 
+                             \%Exclude_Dir,
+                             \%Ignored);
+}
+for (my $i = 0; $i < scalar @ARGV; $i++) {
+    push @fh, 
+         make_file_list([ $ARGV[$i] ], \%Error_Codes, \@Errors, \%Ignored);
+    @{$files_for_set[$i]} = @file_list;
+    @file_list = ();
+}
+# 1}}}
+# Step 5:  Remove duplicate files.             {{{1
+#
+my %Language           = ();
+my %unique_source_file = ();
+my $n_set = 0;
+foreach my $FH (@fh) {  # loop over each pair of file sets
+    ++$n_set;
+    remove_duplicate_files($FH, 
+                               \%{$Language{$FH}}               , 
+                               \%{$unique_source_file{$FH}}     , 
+                          \%Error_Codes                         , 
+                               \@Errors                         , 
+                               \%Ignored                        );
+    printf "%2d: %8d unique file%s.                          \r", 
+        $n_set,
+        plural_form(scalar keys %unique_source_file) 
+        unless $opt_quiet;
+}
+# 1}}}
+# Step 6:  Count code, comments, blank lines.  {{{1
+#
+my %Results_by_Language = ();
+my %Results_by_File     = ();
+my %Delta_by_Language   = ();
+my %Delta_by_File       = ();
+my $nFiles_added        = 0;
+my $nFiles_removed      = 0;
+my $nFiles_modified     = 0;
+my $nFiles_same         = 0;
+
+foreach (my $F = 0; $F < scalar @fh - 1; $F++) { 
+    # loop over file sets; do diff between set $F to $F+1
+
+    my $nCounted = 0;
+
+    my @file_pairs    = ();
+    my @files_added   = ();
+    my @files_removed = ();
+
+    align_by_pairs(\%{$unique_source_file{$fh[$F  ]}}    , # in
+                   \%{$unique_source_file{$fh[$F+1]}}    , # in
+                   \@files_added                         , # out
+                   \@files_removed                       , # out
+                   \@file_pairs                          , # out
+                   );
+    my %already_counted = (); # already_counted{ filename } = 1
+                              
+    if (!@file_pairs) {
+        # Special case where all files were either added or deleted.
+        # In this case, one of these arrays will be empty: 
+        #   @files_added, @files_removed
+        # so loop over both to cover both cases.
+        my $status = @files_added ? 'added' : 'removed';
+        my $offset = @files_added ? 1       : 0        ;
+        foreach my $file (@files_added, @files_removed) {
+            next unless defined $Language{$fh[$F+$offset]}{$file};
+            my $Lang = $Language{$fh[$F+$offset]}{$file};
+            next if $Lang eq '(unknown)';
+            my ($all_line_count,
+                $blank_count   ,
+                $comment_count ,
+               ) = call_counter($file, $Lang, \@Errors);
+            $already_counted{$file} = 1;
+            my $code_count = $all_line_count-$blank_count-$comment_count;
+            if ($opt_by_file) {
+                $Delta_by_File{$file}{'code'   }{$status} += $code_count   ;
+                $Delta_by_File{$file}{'blank'  }{$status} += $blank_count  ;
+                $Delta_by_File{$file}{'comment'}{$status} += $comment_count;
+                $Delta_by_File{$file}{'lang'   }{$status}  = $Lang         ;
+                $Delta_by_File{$file}{'nFiles' }{$status} += 1             ;
+            }
+            $Delta_by_Language{$Lang}{'code'   }{$status} += $code_count   ;
+            $Delta_by_Language{$Lang}{'blank'  }{$status} += $blank_count  ;
+            $Delta_by_Language{$Lang}{'comment'}{$status} += $comment_count;
+            $Delta_by_Language{$Lang}{'nFiles' }{$status} += 1             ;
+        }
+    }
+   #use Data::Dumper::Simple;
+   #use Data::Dumper;
+   #print Dumper(\@files_added, \@files_removed, \@file_pairs);
+    my @alignment = (); # only  used if --diff-alignment
+#print "after align_by_pairs:\n";
+
+#print "added:\n";
+    push @alignment, sprintf "Files added: %d\n", scalar @files_added
+        if $opt_diff_alignment;
+    foreach my $f (@files_added) {
+        next if $already_counted{$f};
+#printf "%10s -> %s\n", $f, $Language{$fh[$F+1]}{$f};
+        # Don't proceed unless the file (both L and R versions)
+        # is in a known language.
+        next if $Language{$fh[$F+1]}{$f} eq "(unknown)";
+        next if $Exclude_Language{$Language{$fh[$F+1]}{$f}};
+        push @alignment, sprintf "  + %s ; %s\n", $f, $Language{$fh[$F+1]}{$f}
+            if $opt_diff_alignment;
+        ++$Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'nFiles'}{'added'};
+        # Additionally, add contents of file $f to 
+        #        Delta_by_File{$f}{comment/blank/code}{'added'}
+        #        Delta_by_Language{$lang}{comment/blank/code}{'added'}
+        my ($all_line_count,
+            $blank_count   ,
+            $comment_count ,
+           ) = call_counter($f, $Language{$fh[$F+1]}{$f}, \@Errors);
+        $Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'comment'}{'added'} +=
+            $comment_count;
+        $Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'blank'}{'added'}   +=
+            $blank_count;
+        $Delta_by_Language{ $Language{$fh[$F+1]}{$f} }{'code'}{'added'}    +=
+            $all_line_count - $blank_count - $comment_count;
+        $Delta_by_File{ $f }{'comment'}{'added'} = $comment_count;
+        $Delta_by_File{ $f }{'blank'}{'added'}   = $blank_count;
+        $Delta_by_File{ $f }{'code'}{'added'}    = 
+            $all_line_count - $blank_count - $comment_count;
+    }
+    push @alignment, "\n";
+
+#print "removed:\n";
+    push @alignment, sprintf "Files removed: %d\n", scalar @files_removed
+        if $opt_diff_alignment;
+    foreach my $f (@files_removed) {
+        next if $already_counted{$f};
+        # Don't proceed unless the file (both L and R versions)
+        # is in a known language.
+        next if $Language{$fh[$F  ]}{$f} eq "(unknown)";
+        next if $Exclude_Language{$Language{$fh[$F  ]}{$f}};
+        ++$Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'nFiles'}{'removed'};
+        push @alignment, sprintf "  - %s ; %s\n", $f, $Language{$fh[$F]}{$f}
+            if $opt_diff_alignment;
+#printf "%10s -> %s\n", $f, $Language{$fh[$F  ]}{$f};
+        # Additionally, add contents of file $f to 
+        #        Delta_by_File{$f}{comment/blank/code}{'removed'}
+        #        Delta_by_Language{$lang}{comment/blank/code}{'removed'}
+        my ($all_line_count,
+            $blank_count   ,
+            $comment_count ,
+           ) = call_counter($f, $Language{$fh[$F  ]}{$f}, \@Errors);
+        $Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'comment'}{'removed'} +=
+            $comment_count;
+        $Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'blank'}{'removed'}   +=
+            $blank_count;
+        $Delta_by_Language{ $Language{$fh[$F  ]}{$f} }{'code'}{'removed'}    +=
+            $all_line_count - $blank_count - $comment_count;
+        $Delta_by_File{ $f }{'comment'}{'removed'} = $comment_count;
+        $Delta_by_File{ $f }{'blank'}{'removed'}   = $blank_count;
+        $Delta_by_File{ $f }{'code'}{'removed'}    = 
+            $all_line_count - $blank_count - $comment_count;
+    }
+    push @alignment, "\n";
+
+    my $alignment_pairs_index = scalar @alignment;
+    my $n_file_pairs_compared = 0;
+    # Don't know ahead of time how many file pairs will be compared
+    # since duplicates are weeded out below.  The answer is
+    # scalar @file_pairs only if there are no duplicates.
+    push @alignment, sprintf "File pairs compared: UPDATE_ME\n"
+        if $opt_diff_alignment;
+
+    foreach my $pair (@file_pairs) {
+        my $file_L = $pair->[0];
+        my $file_R = $pair->[1];
+        my $Lang_L = $Language{$fh[$F  ]}{$file_L};
+        my $Lang_R = $Language{$fh[$F+1]}{$file_R};
+#print "main step 6 file_L=$file_L    file_R=$file_R\n";
+        ++$nCounted;
+        printf "Counting:  %d\r", $nCounted 
+            unless (!$opt_progress_rate or ($nCounted % $opt_progress_rate));
+        next if $Ignored{$file_L};
+
+        # filter out excluded or unrecognized languages
+        if ($Exclude_Language{$Lang_L} or $Exclude_Language{$Lang_R}) {
+            $Ignored{$file_L} = "--exclude-lang=$Lang_L}";
+            $Ignored{$file_R} = "--exclude-lang=$Lang_R}";
+            next;
+        }
+        my $not_Filters_by_Language_Lang_LR = 0;
+        if ($PERL_516) {
+            if (!(@{$Filters_by_Language{$Lang_L} }) or
+                !(@{$Filters_by_Language{$Lang_R} })) {
+                $not_Filters_by_Language_Lang_LR = 1;
+            }
+        } else {
+            if (!defined(@{$Filters_by_Language{$Lang_L} }) or
+                !defined(@{$Filters_by_Language{$Lang_R} })) {
+                $not_Filters_by_Language_Lang_LR = 1;
+            }
+        }
+        if ($not_Filters_by_Language_Lang_LR) {
+            if (($Lang_L eq "(unknown)") or ($Lang_R eq "(unknown)")) {
+                $Ignored{$fh[$F  ]}{$file_L} = "language unknown (#1)";
+                $Ignored{$fh[$F+1]}{$file_R} = "language unknown (#1)";
+            } else {
+                $Ignored{$fh[$F  ]}{$file_L} = "missing Filters_by_Language{$Lang_L}";
+                $Ignored{$fh[$F+1]}{$file_R} = "missing Filters_by_Language{$Lang_R}";
+            }
+            next;
+        }
+
+#print "DIFF($file_L, $file_R)\n";
+        # step 0: compare the two files' contents 
+        chomp ( my @lines_L = read_file($file_L) );
+        chomp ( my @lines_R = read_file($file_R) );
+        my $language_file_L = "";
+        if (defined $Language{$fh[$F]}{$file_L}) {
+            $language_file_L = $Language{$fh[$F]}{$file_L};
+        } else {
+            # files $file_L and $file_R do not contain known language
+            next;
+        }
+        my $contents_are_same = 1;
+        if (scalar @lines_L == scalar @lines_R) {
+            # same size, must compare line-by-line
+            for (my $i = 0; $i < scalar @lines_L; $i++) {
+                if ($lines_L[$i] ne $lines_R[$i]) {
+                    $contents_are_same = 0;
+                    last;
+                }
+            }
+            if ($contents_are_same) {
+                ++$Delta_by_Language{$language_file_L}{'nFiles'}{'same'};
+            } else {
+                ++$Delta_by_Language{$language_file_L}{'nFiles'}{'modified'};
+            }
+        } else {
+            $contents_are_same = 0;
+            # different sizes, contents have changed
+            ++$Delta_by_Language{$language_file_L}{'nFiles'}{'modified'};
+        }
+        if ($opt_diff_alignment) {
+            my $str =  "$file_L | $file_R ; $language_file_L";
+            if ($contents_are_same) {
+                push @alignment, "  == $str";
+            } else {
+                push @alignment, "  != $str";
+            }
+            ++$n_file_pairs_compared;
+        }
+
+        # step 1: identify comments in both files
+#print "Diff blank removal L language= $Lang_L";
+#print " scalar(lines_L)=", scalar @lines_L, "\n";
+        my @original_minus_blanks_L 
+                    = rm_blanks(  \@lines_L, $Lang_L, \%EOL_Continuation_re);
+#print "1: scalar(original_minus_blanks_L)=", scalar @original_minus_blanks_L, "\n";
+        @lines_L    = @original_minus_blanks_L;
+#print "2: scalar(lines_L)=", scalar @lines_L, "\n";
+        @lines_L    = add_newlines(\@lines_L); # compensate for rm_comments()
+        @lines_L    = rm_comments( \@lines_L, $Lang_L, $file_L,
+                                   \%EOL_Continuation_re);
+#print "3: scalar(lines_L)=", scalar @lines_L, "\n";
+
+#print "Diff blank removal R language= $Lang_R\n";
+        my @original_minus_blanks_R 
+                    = rm_blanks(  \@lines_R, $Lang_R, \%EOL_Continuation_re);
+        @lines_R    = @original_minus_blanks_R;
+        @lines_R    = add_newlines(\@lines_R); # taken away by rm_comments()
+        @lines_R    = rm_comments( \@lines_R, $Lang_R, $file_R,
+                                   \%EOL_Continuation_re);
+
+        my (@diff_LL, @diff_LR, );
+        array_diff( $file_L                  ,   # in
+                   \@original_minus_blanks_L ,   # in
+                   \@lines_L                 ,   # in
+                   "comment"                 ,   # in
+                   \@diff_LL, \@diff_LR      ,   # out
+                   \@Errors);                    # in/out
+
+        my (@diff_RL, @diff_RR, );
+        array_diff( $file_R                  ,   # in
+                   \@original_minus_blanks_R ,   # in
+                   \@lines_R                 ,   # in
+                   "comment"                 ,   # in
+                   \@diff_RL, \@diff_RR      ,   # out
+                   \@Errors);                    # in/out
+        # each line of each file is now classified as
+        # code or comment
+
+#use Data::Dumper; 
+#print Dumper("diff_LL", \@diff_LL, "diff_LR", \@diff_LR, );
+#print Dumper("diff_RL", \@diff_RL, "diff_RR", \@diff_RR, );
+#die;
+        # step 2: separate code from comments for L and R files
+        my @code_L = ();
+        my @code_R = ();
+        my @comm_L = ();
+        my @comm_R = ();
+        foreach my $line_info (@diff_LL) {
+            if      ($line_info->{'type'} eq "code"   ) {
+                push @code_L, $line_info->{char};
+            } elsif ($line_info->{'type'} eq "comment") {
+                push @comm_L, $line_info->{char};
+            } else {
+                die "Diff unexpected line type ",
+                    $line_info->{'type'}, "for $file_L line ",
+                    $line_info->{'lnum'};
+            }
+        }
+        foreach my $line_info (@diff_RL) {
+            if      ($line_info->{type} eq "code"   ) {
+                push @code_R, $line_info->{'char'};
+            } elsif ($line_info->{type} eq "comment") {
+                push @comm_R, $line_info->{'char'};
+            } else {
+                die "Diff unexpected line type ",
+                    $line_info->{'type'}, "for $file_R line ",
+                    $line_info->{'lnum'};
+            }
+        }
+
+        if ($opt_ignore_whitespace) {
+            # strip all whitespace from each line of source code
+            # and comments then use these stripped arrays in diffs
+            foreach (@code_L) { s/\s+//g }
+            foreach (@code_R) { s/\s+//g }
+            foreach (@comm_L) { s/\s+//g }
+            foreach (@comm_R) { s/\s+//g }
+        }
+        if ($opt_ignore_case) {
+            # change all text to lowercase in diffs
+            foreach (@code_L) { $_ = lc }
+            foreach (@code_R) { $_ = lc }
+            foreach (@comm_L) { $_ = lc }
+            foreach (@comm_R) { $_ = lc }
+        }
+        # step 3: compute code diffs
+        array_diff("$file_L v. $file_R"   ,   # in
+                   \@code_L               ,   # in
+                   \@code_R               ,   # in
+                   "revision"             ,   # in
+                   \@diff_LL, \@diff_LR   ,   # out
+                   \@Errors);                 # in/out
+#print Dumper("diff_LL", \@diff_LL, "diff_LR", \@diff_LR, );
+#print Dumper("diff_LR", \@diff_LR);
+        foreach my $line_info (@diff_LR) {
+            my $status = $line_info->{'desc'}; # same|added|removed|modified
+            ++$Delta_by_Language{$Lang_L}{'code'}{$status};
+            if ($opt_by_file) {
+                ++$Delta_by_File{$file_L}{'code'}{$status};
+            }
+        }
+#use Data::Dumper;
+#print Dumper("code diffs:", \@diff_LL, \@diff_LR);
+
+        # step 4: compute comment diffs
+        array_diff("$file_L v. $file_R"   ,   # in
+                   \@comm_L               ,   # in
+                   \@comm_R               ,   # in
+                   "revision"             ,   # in
+                   \@diff_LL, \@diff_LR   ,   # out
+                   \@Errors);                 # in/out
+#print Dumper("comment diff_LR", \@diff_LR);
+        foreach my $line_info (@diff_LR) {
+            my $status = $line_info->{'desc'}; # same|added|removed|modified
+            ++$Delta_by_Language{$Lang_L}{'comment'}{$status};
+            if ($opt_by_file) {
+                ++$Delta_by_File{$file_L}{'comment'}{$status};
+            }
+        }
+#print Dumper("comment diffs:", \@diff_LL, \@diff_LR);
+#die; here=  need to save original line number in diff result for html display
+
+        # step 5: compute difference in blank lines (kind of pointless)
+        next if $Lang_L eq '(unknown)' or 
+                $Lang_R eq '(unknown)';
+        my ($all_line_count_L,
+            $blank_count_L   ,
+            $comment_count_L ,
+           ) = call_counter($file_L, $Lang_L, \@Errors);
+
+        my ($all_line_count_R,
+            $blank_count_R   ,
+            $comment_count_R ,
+           ) = call_counter($file_R, $Lang_R, \@Errors);
+
+        if ($blank_count_L <  $blank_count_R) {
+            my $D = $blank_count_R - $blank_count_L;
+            $Delta_by_Language{$Lang_L}{'blank'}{'added'}   += $D;
+        } else {
+            my $D = $blank_count_L - $blank_count_R;
+            $Delta_by_Language{$Lang_L}{'blank'}{'removed'} += $D;
+        }
+        if ($opt_by_file) {
+            if ($blank_count_L <  $blank_count_R) {
+                my $D = $blank_count_R - $blank_count_L;
+                $Delta_by_File{$file_L}{'blank'}{'added'}   += $D;
+            } else {
+                my $D = $blank_count_L - $blank_count_R;
+                $Delta_by_File{$file_L}{'blank'}{'removed'} += $D;
+            }
+        }
+
+        my $code_count_L = $all_line_count_L-$blank_count_L-$comment_count_L;
+        if ($opt_by_file) {
+            $Results_by_File{$file_L}{'code'   } = $code_count_L    ;
+            $Results_by_File{$file_L}{'blank'  } = $blank_count_L   ;
+            $Results_by_File{$file_L}{'comment'} = $comment_count_L ;
+            $Results_by_File{$file_L}{'lang'   } = $Lang_L          ;
+            $Results_by_File{$file_L}{'nFiles' } = 1                ;
+        } else {
+            $Results_by_File{$file_L} = 1;  # just keep track of counted files
+        }
+   
+        $Results_by_Language{$Lang_L}{'nFiles'}++;
+        $Results_by_Language{$Lang_L}{'code'}    += $code_count_L   ;
+        $Results_by_Language{$Lang_L}{'blank'}   += $blank_count_L  ;
+        $Results_by_Language{$Lang_L}{'comment'} += $comment_count_L;
+    }
+    if ($opt_diff_alignment) {
+        $alignment[$alignment_pairs_index] =~ s/UPDATE_ME/$n_file_pairs_compared/;
+        write_file($opt_diff_alignment, @alignment);
+    }
+
+}
+#use Data::Dumper;
+#print Dumper("Delta_by_Language:"  , \%Delta_by_Language);
+#print Dumper("Results_by_Language:", \%Results_by_Language);
+#print Dumper("Delta_by_File:"      , \%Delta_by_File);
+#print Dumper("Results_by_File:"    , \%Results_by_File);
+#die;
+my @ignored_reasons = map { "$_: $Ignored{$_}" } sort keys %Ignored;
+write_file($opt_ignored, @ignored_reasons   ) if $opt_ignored;
+write_file($opt_counted, sort keys %Results_by_File) if $opt_counted;
+# 1}}}
+# Step 7:  Assemble results.                   {{{1
+#
+my $end_time = get_time();
+printf "%8d file%s ignored.                           \n", 
+    plural_form(scalar keys %Ignored) unless $opt_quiet;
+print_errors(\%Error_Codes, \@Errors) if @Errors;
+if (!%Delta_by_Language) {
+    print "Nothing to count.\n";
+    exit;
+}
+
+if ($opt_by_file) {
+    @Lines_Out = diff_report($VERSION, get_time() - $start_time,
+                            "by file",
+                            \%Delta_by_File, \%Scale_Factor);
+} else {
+    @Lines_Out = diff_report($VERSION, get_time() - $start_time,
+                            "by language",
+                            \%Delta_by_Language, \%Scale_Factor);
+}
+
+# 1}}}
+} else {
+# Step 4:  Separate code from non-code files.  {{{1
+my $fh = 0;
+if ($opt_list_file) {
+    my @list = read_list_file($opt_list_file);
+    $fh = make_file_list(\@list, \%Error_Codes, \@Errors, \%Ignored);
+} else {
+    $fh = make_file_list(\@ARGV, \%Error_Codes, \@Errors, \%Ignored);
+    #     make_file_list populates global variable @file_list via call to 
+    #     File::Find's find() which in turn calls files()
+}
+if ($opt_exclude_list_file) {
+    process_exclude_list_file($opt_exclude_list_file, 
+                             \%Exclude_Dir,
+                             \%Ignored);
+}
+if ($opt_skip_win_hidden and $ON_WINDOWS) {
+    my @file_list_minus_hidded = ();
+    # eval code to run on Unix without 'missing Win32::File module' error.
+    my $win32_file_invocation = '
+        use Win32::File;
+        foreach my $F (@file_list) {
+            my $attr = undef;
+            Win32::File::GetAttributes($F, $attr);
+            if ($attr & HIDDEN) {
+                $Ignored{$F} = "Windows hidden file";
+                print "Ignoring $F since it is a Windows hidden file\n" 
+                    if $opt_v > 1;
+            } else {
+                push @file_list_minus_hidded, $F;
+            }
+        }';
+    eval $win32_file_invocation;
+    @file_list = @file_list_minus_hidded;
+}
+#printf "%8d file%s excluded.                     \n", 
+#   plural_form(scalar keys %Ignored) 
+#   unless $opt_quiet;
+# die print ": ", join("\n: ", @file_list), "\n";
+# 1}}}
+# Step 5:  Remove duplicate files.             {{{1
+#
+my %Language           = ();
+my %unique_source_file = ();
+remove_duplicate_files($fh                          ,   # in 
+                           \%Language               ,   # out
+                           \%unique_source_file     ,   # out
+                      \%Error_Codes                 ,   # in
+                           \@Errors                 ,   # out
+                           \%Ignored                );  # out
+printf "%8d unique file%s.                              \n", 
+    plural_form(scalar keys %unique_source_file) 
+    unless $opt_quiet;
+# 1}}}
+# Step 6:  Count code, comments, blank lines.  {{{1
+#
+
+my %Results_by_Language = ();
+my %Results_by_File     = ();
+my $nCounted = 0;
+foreach my $file (sort keys %unique_source_file) {
+    ++$nCounted;
+    printf "Counting:  %d\r", $nCounted 
+        unless (!$opt_progress_rate or ($nCounted % $opt_progress_rate));
+    next if $Ignored{$file};
+    if ($Exclude_Language{$Language{$file}}) {
+        $Ignored{$file} = "--exclude-lang=$Language{$file}";
+        next;
+    }
+    my $Filters_by_Language_Language_file = !defined @{$Filters_by_Language{$Language{$file}} };
+    if ($Filters_by_Language_Language_file) {
+        if ($Language{$file} eq "(unknown)") {
+            $Ignored{$file} = "language unknown (#1)";
+        } else {
+            $Ignored{$file} = "missing Filters_by_Language{$Language{$file}}";
+        }
+        next;
+    }
+
+    my ($all_line_count,
+        $blank_count   ,
+        $comment_count ,
+       ) = call_counter($file, $Language{$file}, \@Errors);
+    my $code_count = $all_line_count - $blank_count - $comment_count;
+    if ($opt_by_file) {
+        $Results_by_File{$file}{'code'   } = $code_count     ;
+        $Results_by_File{$file}{'blank'  } = $blank_count    ;
+        $Results_by_File{$file}{'comment'} = $comment_count  ;
+        $Results_by_File{$file}{'lang'   } = $Language{$file};
+        $Results_by_File{$file}{'nFiles' } = 1;
+    } else {
+        $Results_by_File{$file} = 1;  # just keep track of counted files
+    }
+
+    $Results_by_Language{$Language{$file}}{'nFiles'}++;
+    $Results_by_Language{$Language{$file}}{'code'}    += $code_count   ;
+    $Results_by_Language{$Language{$file}}{'blank'}   += $blank_count  ;
+    $Results_by_Language{$Language{$file}}{'comment'} += $comment_count;
+}
+my @ignored_reasons = map { "$_: $Ignored{$_}" } sort keys %Ignored;
+write_file($opt_ignored, @ignored_reasons   ) if $opt_ignored;
+write_file($opt_counted, sort keys %Results_by_File) if $opt_counted;
+# 1}}}
+# Step 7:  Assemble results.                   {{{1
+#
+my $end_time = get_time();
+printf "%8d file%s ignored.\n", plural_form(scalar keys %Ignored) 
+    unless $opt_quiet;
+print_errors(\%Error_Codes, \@Errors) if @Errors;
+exit unless %Results_by_Language;
+
+generate_sql($end_time - $start_time,
+            \%Results_by_File, \%Scale_Factor) if $opt_sql;
+
+exit if $skip_generate_report;
+if      ($opt_by_file_by_lang) {
+    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
+                                      "by file",
+                                      \%Results_by_File,    \%Scale_Factor);
+    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
+                                      "by language",
+                                      \%Results_by_Language, \%Scale_Factor);
+} elsif ($opt_by_file) {
+    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
+                                      "by file",
+                                      \%Results_by_File,    \%Scale_Factor);
+} else {
+    push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,
+                                      "by language",
+                                      \%Results_by_Language, \%Scale_Factor);
+}
+# 1}}}
+}
+if ($opt_report_file) { write_file($opt_report_file, @Lines_Out); } 
+else                  { print "\n", join("\n", @Lines_Out), "\n"; }
+
+sub process_exclude_list_file {              # {{{1
+    my ($list_file      , # in
+        $rh_exclude_dir , # out
+        $rh_ignored     , # out
+       ) = @_;
+    print "-> process_exclude_list_file($list_file)\n" if $opt_v > 2;
+    # reject a specific set of files and/or directories
+    my @reject_list   = read_list_file($list_file);
+    my @file_reject_list = ();
+    foreach my $F_or_D (@reject_list) {
+        if (is_dir($F_or_D)) {
+            $rh_exclude_dir->{$F_or_D} = 1;
+        } elsif (is_file($F_or_D)) {
+            push @file_reject_list, $F_or_D;
+        }
+    }
+
+    # Normalize file names for better comparison.
+    my %normalized_input   = normalize_file_names(@file_list);
+    my %normalized_reject  = normalize_file_names(@file_reject_list);
+    my %normalized_exclude = normalize_file_names(keys %{$rh_exclude_dir});
+    foreach my $F (keys %normalized_input) {
+        if ($normalized_reject{$F} or is_excluded($F, \%normalized_exclude)) {
+            my $orig_F = $normalized_input{$F};
+            $rh_ignored->{$orig_F} = "listed in exclusion file $opt_exclude_list_file";
+            print "Ignoring $orig_F because it appears in $opt_exclude_list_file\n" 
+                if $opt_v > 1;
+        }
+    }
+    print "<- process_exclude_list_file\n" if $opt_v > 2;
+} # 1}}}
+sub combine_results {                        # {{{1
+    # returns 1 if the inputs are categorized by language
+    #         0 if no identifiable language was found
+    my ($ra_report_files, # in
+        $report_type    , # in  "by language" or "by report file"
+        $rhh_count      , # out count{TYPE}{nFiles|code|blank|comment|scaled}
+        $rhaa_Filters_by_Language , # in
+       ) = @_;
+
+    print "-> combine_results(report_type=$report_type)\n" if $opt_v > 2;
+    my $found_language = 0;
+
+    foreach my $file (@{$ra_report_files}) {
+        my $IN = new IO::File $file, "r";
+        if (!defined $IN) {
+            warn "Unable to read $file; ignoring.\n";
+            next;
+        }
+        while (<$IN>) {
+            next if /^(http|Language|SUM|-----)/;
+            if (!$opt_by_file  and
+                m{^(.*?)\s+         # language
+                   (\d+)\s+         # files
+                   (\d+)\s+         # blank
+                   (\d+)\s+         # comments
+                   (\d+)\s+         # code
+                   (                #    next four entries missing with -nno3
+                   x\s+             # x
+                   \d+\.\d+\s+      # scale
+                   =\s+             # =
+                   (\d+\.\d+)\s*    # scaled code
+                   )?
+                   $}x) {
+                if ($report_type eq "by language") {
+                    if ($PERL_516) {
+                        next unless         @{$rhaa_Filters_by_Language->{$1}};
+                    } else {
+                        next unless defined @{$rhaa_Filters_by_Language->{$1}};
+                    }
+                    # above test necessary to avoid trying to sum reports
+                    # of reports (which have no language breakdown).
+                    $found_language = 1;
+                    $rhh_count->{$1   }{'nFiles' } += $2;
+                    $rhh_count->{$1   }{'blank'  } += $3;
+                    $rhh_count->{$1   }{'comment'} += $4;
+                    $rhh_count->{$1   }{'code'   } += $5;
+                    $rhh_count->{$1   }{'scaled' } += $7 if $opt_3;
+                } else {
+                    $rhh_count->{$file}{'nFiles' } += $2;
+                    $rhh_count->{$file}{'blank'  } += $3;
+                    $rhh_count->{$file}{'comment'} += $4;
+                    $rhh_count->{$file}{'code'   } += $5;
+                    $rhh_count->{$file}{'scaled' } += $7 if $opt_3;
+                }
+            } elsif ($opt_by_file  and
+                m{^(.*?)\s+         # language
+                   (\d+)\s+         # blank
+                   (\d+)\s+         # comments
+                   (\d+)\s+         # code
+                   (                #    next four entries missing with -nno3
+                   x\s+             # x
+                   \d+\.\d+\s+      # scale
+                   =\s+             # =
+                   (\d+\.\d+)\s*    # scaled code
+                   )?
+                   $}x) {
+                if ($report_type eq "by language") {
+                    next unless %{$rhaa_Filters_by_Language->{$1}};
+                    # above test necessary to avoid trying to sum reports
+                    # of reports (which have no language breakdown).
+                    $found_language = 1;
+                    $rhh_count->{$1   }{'nFiles' } +=  1;
+                    $rhh_count->{$1   }{'blank'  } += $2;
+                    $rhh_count->{$1   }{'comment'} += $3;
+                    $rhh_count->{$1   }{'code'   } += $4;
+                    $rhh_count->{$1   }{'scaled' } += $6 if $opt_3;
+                } else {
+                    $rhh_count->{$file}{'nFiles' } +=  1;
+                    $rhh_count->{$file}{'blank'  } += $2;
+                    $rhh_count->{$file}{'comment'} += $3;
+                    $rhh_count->{$file}{'code'   } += $4;
+                    $rhh_count->{$file}{'scaled' } += $6 if $opt_3;
+                }
+            }
+        }
+    }
+    print "<- combine_results\n" if $opt_v > 2;
+    return $found_language;
+} # 1}}}
+sub diff_report     {                        # {{{1
+    # returns an array of lines containing the results
+    print "-> diff_report\n" if $opt_v > 2;
+
+    if ($opt_xml or $opt_yaml) {
+        print "<- diff_report\n" if $opt_v > 2;
+        return diff_xml_yaml_report(@_) 
+    } elsif ($opt_csv) {
+        print "<- diff_report\n" if $opt_v > 2;
+        return diff_csv_report(@_) 
+    }
+
+    my ($version    , # in
+        $elapsed_sec, # in
+        $report_type, # in  "by language" | "by report file" | "by file"
+        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}
+        $rh_scale   , # in
+       ) = @_;
+
+#use Data::Dumper;
+#print "diff_report: ", Dumper($rhhh_count), "\n";
+    my @results       = ();
+
+    my $languages     = ();
+    my %sum           = (); # sum{nFiles|blank|comment|code}{same|modified|added|removed}
+    my $max_len       = 0;
+    foreach my $language (keys %{$rhhh_count}) {
+        foreach my $V (qw(nFiles blank comment code)) {
+            foreach my $S (qw(added same modified removed)) {
+                $rhhh_count->{$language}{$V}{$S} = 0 unless
+                    defined $rhhh_count->{$language}{$V}{$S};
+                $sum{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};
+            }
+        }
+        $max_len      = length($language) if length($language) > $max_len;
+    }
+    my $column_1_offset = 0;
+       $column_1_offset = $max_len - 17 if $max_len > 17;
+    $elapsed_sec = 0.5 unless $elapsed_sec;
+
+    my $spacing_0 = 23;
+    my $spacing_1 = 13;
+    my $spacing_2 =  9;
+    my $spacing_3 = 17;
+    if (!$opt_3) {
+        $spacing_1 = 19;
+        $spacing_2 = 14;
+        $spacing_3 = 28;
+    }
+    $spacing_0 += $column_1_offset;
+    $spacing_1 += $column_1_offset;
+    $spacing_3 += $column_1_offset;
+    my %Format = (
+        '1' => { 'xml' => 'name="%s" ',
+                 'txt' => "\%-${spacing_0}s ",
+               },
+        '2' => { 'xml' => 'name="%s" ',
+                 'txt' => "\%-${spacing_3}s ",
+               },
+        '3' => { 'xml' => 'files_count="%d" ',
+                 'txt' => '%5d ',
+               },
+        '4' => { 'xml' => 'blank="%d" comment="%d" code="%d" ',
+                 'txt' => "\%${spacing_2}d \%${spacing_2}d \%${spacing_2}d",
+               },
+        '5' => { 'xml' => 'factor="%.2f" scaled="%.2f" ',
+                 'txt' => ' x %6.2f = %14.2f',
+               },
+    );
+    my $Style = "txt";
+       $Style = "xml" if $opt_xml ;
+       $Style = "xml" if $opt_yaml;  # not a typo; just set to anything but txt
+       $Style = "xml" if $opt_csv ;  # not a typo; just set to anything but txt
+
+    my $hyphen_line = sprintf "%s", '-' x (79 + $column_1_offset);
+       $hyphen_line = sprintf "%s", '-' x (68 + $column_1_offset) 
+            if (!$opt_3) and (68 + $column_1_offset) > 79;
+    my $data_line  = "";
+    my $first_column;
+    my $BY_LANGUAGE = 0;
+    my $BY_FILE     = 0;
+    if      ($report_type eq "by language") {
+        $first_column = "Language";
+        $BY_LANGUAGE  = 1;
+    } elsif ($report_type eq "by file")     {
+        $first_column = "File";
+        $BY_FILE      = 1;
+    } else {
+        $first_column = "Report File";
+    }
+
+    my $header_line  = sprintf "%s v %s", $URL, $version;
+    my $sum_files    = 1;
+    my $sum_lines    = 1;
+       $header_line .= sprintf("  T=%.2f s (%.1f files/s, %.1f lines/s)",
+                        $elapsed_sec           ,
+                        $sum_files/$elapsed_sec,
+                        $sum_lines/$elapsed_sec) unless $opt_sum_reports;
+    if ($Style eq "txt") {
+        push @results, output_header($header_line, $hyphen_line, $BY_FILE);
+    } elsif ($Style eq "csv") {
+        die "csv";
+    }
+
+    # column headers
+    if (!$opt_3 and $BY_FILE) {
+        my $spacing_n = $spacing_1 - 11;
+        $data_line  = sprintf "%-${spacing_n}s" , $first_column;
+    } else {
+        $data_line  = sprintf "%-${spacing_1}s ", $first_column;
+    }
+    if ($BY_FILE) {
+        $data_line .= sprintf "%${spacing_2}s"   , ""     ;
+    } else {
+        $data_line .= sprintf "%${spacing_2}s "  , "files";
+    }
+    $data_line .= sprintf "%${spacing_2}s %${spacing_2}s %${spacing_2}s",
+        "blank"         ,
+        "comment"       ,
+        "code";
+
+    if ($Style eq "txt") {
+        push @results, $data_line;
+        push @results, $hyphen_line;
+    }
+
+####foreach my $lang_or_file (keys %{$rhhh_count}) {
+####    $rhhh_count->{$lang_or_file}{'code'} = 0 unless 
+####        defined $rhhh_count->{$lang_or_file}{'code'};
+####}
+    foreach my $lang_or_file (sort {
+                                 $rhhh_count->{$b}{'code'} <=>
+                                 $rhhh_count->{$a}{'code'}
+                               }
+                          keys %{$rhhh_count}) {
+
+        if ($BY_FILE) {
+            push @results, rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
+        } else {
+            push @results, $lang_or_file;
+        }
+        foreach my $S (qw(same modified added removed)) {
+            my $indent = $spacing_1 - 2;
+            my $line .= sprintf " %-${indent}s", $S;
+            if ($BY_FILE) {
+                $line .= sprintf "   ";
+            } else {
+                $line .= sprintf "  %${spacing_2}s", $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
+            }
+            $line .= sprintf " %${spacing_2}s %${spacing_2}s %${spacing_2}s",
+                $rhhh_count->{$lang_or_file}{'blank'}{$S}   ,
+                $rhhh_count->{$lang_or_file}{'comment'}{$S} ,
+                $rhhh_count->{$lang_or_file}{'code'}{$S}    ;
+            push @results, $line;
+        }
+    }
+    push @results, "-" x 79;
+    push @results, "SUM:";
+    foreach my $S (qw(same modified added removed)) {
+        my $indent = $spacing_1 - 2;
+        my $line .= sprintf " %-${indent}s", $S;
+            if ($BY_FILE) {
+                $line .= sprintf "   ";
+            } else {
+                $line .= sprintf "  %${spacing_2}s", $sum{'nFiles'}{$S};
+            }
+        $line .= sprintf " %${spacing_2}s %${spacing_2}s %${spacing_2}s",
+            $sum{'blank'}{$S}   ,
+            $sum{'comment'}{$S} ,
+            $sum{'code'}{$S}    ;
+        push @results, $line;
+    }
+    push @results, "-" x 79;
+    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;
+    print "<- diff_report\n" if $opt_v > 2;
+
+    return @results;
+} # 1}}}
+sub xml_or_yaml_header {                     # {{{1
+    my ($URL, $version, $elapsed_sec, $sum_files, $sum_lines, $by_file) = @_;
+    print "-> xml_or_yaml_header\n" if $opt_v > 2;
+    my $header      = "";
+    my $file_rate   = $sum_files/$elapsed_sec;
+    my $line_rate   = $sum_lines/$elapsed_sec;
+    my $type        = ""; 
+       $type        = "diff_" if $opt_diff;
+    my $report_file = "";
+    if ($opt_report_file) {
+        if ($opt_sum_reports) {
+            if ($by_file) {
+                $report_file = "  <report_file>$opt_report_file.file</report_file>"
+            } else {
+                $report_file = "  <report_file>$opt_report_file.lang</report_file>"
+            }
+        } else {
+            $report_file = "  <report_file>$opt_report_file</report_file>"
+        }
+    }
+    if ($opt_xml) {
+        $header = "<?xml version=\"1.0\"?>";
+        $header .= "\n<?xml-stylesheet type=\"text/xsl\" href=\"" . $opt_xsl . "\"?>" if $opt_xsl;
+        $header .= "<${type}results>
+<header>
+  <cloc_url>$URL</cloc_url>
+  <cloc_version>$version</cloc_version>
+  <elapsed_seconds>$elapsed_sec</elapsed_seconds>
+  <n_files>$sum_files</n_files>
+  <n_lines>$sum_lines</n_lines>
+  <files_per_second>$file_rate</files_per_second>
+  <lines_per_second>$line_rate</lines_per_second>";
+        $header .= "\n$report_file"
+            if $opt_report_file;
+        $header .= "\n</header>";
+    } elsif ($opt_yaml) {
+        $header = "---\n# $URL
+header :
+  cloc_url           : http://cloc.sourceforge.net
+  cloc_version       : $version
+  elapsed_seconds    : $elapsed_sec
+  n_files            : $sum_files
+  n_lines            : $sum_lines
+  files_per_second   : $file_rate
+  lines_per_second   : $line_rate";
+        if ($opt_report_file) {
+            if ($opt_sum_reports) {
+                if ($by_file) {
+                    $header .= "\n  report_file        : $opt_report_file.file"
+                } else {
+                    $header .= "\n  report_file        : $opt_report_file.lang"
+                }
+            } else {
+                $header .= "\n  report_file        : $opt_report_file";
+            }
+        }
+    }
+    print "<- xml_or_yaml_header\n" if $opt_v > 2;
+    return $header;
+} # 1}}}
+sub diff_xml_yaml_report {                   # {{{1
+    # returns an array of lines containing the results
+    my ($version    , # in
+        $elapsed_sec, # in
+        $report_type, # in  "by language" | "by report file" | "by file"
+        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}
+        $rh_scale   , # in
+       ) = @_;
+    print "-> diff_xml_yaml_report\n" if $opt_v > 2;
+
+#print "diff_report: ", Dumper($rhhh_count), "\n";
+    my @results       = ();
+    
+    my $languages     = ();
+    my %sum           = (); # sum{nFiles|blank|comment|code}{same|modified|added|removed}
+
+    my $sum_files = 0;
+    my $sum_lines = 0;
+    foreach my $language (keys %{$rhhh_count}) {
+        foreach my $V (qw(nFiles blank comment code)) {
+            foreach my $S (qw(added same modified removed)) {
+                $rhhh_count->{$language}{$V}{$S} = 0 unless
+                    defined $rhhh_count->{$language}{$V}{$S};
+                $sum{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};
+                if ($V eq "nFiles") {
+                    $sum_files += $rhhh_count->{$language}{$V}{$S};
+                } else {
+                    $sum_lines += $rhhh_count->{$language}{$V}{$S};
+                }
+            }
+        }
+    }
+    $elapsed_sec = 0.5 unless $elapsed_sec;
+
+    my $data_line   = "";
+    my $BY_LANGUAGE = 0;
+    my $BY_FILE     = 0;
+    if      ($report_type eq "by language") {
+        $BY_LANGUAGE  = 1;
+    } elsif ($report_type eq "by file")     {
+        $BY_FILE      = 1;
+    }
+
+    if (!$ALREADY_SHOWED_HEADER) {
+        push @results,
+              xml_or_yaml_header($URL, $version, $elapsed_sec, 
+                                 $sum_files, $sum_lines, $BY_FILE);
+        $ALREADY_SHOWED_HEADER = 1;
+    }
+
+    foreach my $S (qw(same modified added removed)) {
+        if ($opt_xml) {
+            push @results, "  <$S>";
+        } elsif ($opt_yaml) {
+            push @results, "$S :";
+        }
+########foreach my $lang_or_file (keys %{$rhhh_count}) {
+########    $rhhh_count->{$lang_or_file}{'code'} = 0 unless 
+########        defined $rhhh_count->{$lang_or_file}{'code'};
+########}
+        foreach my $lang_or_file (sort {
+                                     $rhhh_count->{$b}{'code'} <=>
+                                     $rhhh_count->{$a}{'code'}
+                                   }
+                              keys %{$rhhh_count}) {
+            my $L = "";
+            if ($opt_xml) {
+                if ($BY_FILE) {
+                    $L .= sprintf "    <file name=\"%s\" files_count=\"1\" ", 
+                            rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
+                } else {
+                    $L .= sprintf "    <language name=\"%s\" files_count=\"%d\" ",
+                            $lang_or_file ,
+                            $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
+                }
+                foreach my $T (qw(blank comment code)) {
+                    $L .= sprintf "%s=\"%d\" ", 
+                            $T, $rhhh_count->{$lang_or_file}{$T}{$S};
+                }
+                push @results, $L . "/>";
+            } elsif ($opt_yaml) {
+                if ($BY_FILE) {
+                    push @results, sprintf "  - file : %s", 
+                                   rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
+                    push @results, sprintf "    files_count : 1", 
+                } else {
+                    push @results, sprintf "  - language : %s", $lang_or_file;
+                    push @results, sprintf "    files_count : %d", 
+                            $rhhh_count->{$lang_or_file}{'nFiles'}{$S};
+                }
+                foreach my $T (qw(blank comment code)) {
+                    push @results, sprintf "    %s : %d", 
+                            $T, $rhhh_count->{$lang_or_file}{$T}{$S};
+                }
+            }
+        }
+
+        if ($opt_xml) {
+            my $L = sprintf "    <total sum_files=\"%d\" ", $sum{'nFiles'}{$S};
+            foreach my $V (qw(blank comment code)) {
+                $L .= sprintf "%s=\"%d\" ", $V, $sum{$V}{$S};
+            }
+            push @results, $L . "/>";
+            push @results, "  </$S>";
+        } elsif ($opt_yaml) {
+            push @results, sprintf "%s_total :\n    sum_files : %d", 
+                                $S, $sum{'nFiles'}{$S};
+            foreach my $V (qw(blank comment code)) {
+                push @results, sprintf "    %s : %d", $V, $sum{$V}{$S};
+            }
+        }
+    }
+
+    if ($opt_xml) {
+        push @results, "</diff_results>";
+    }
+    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;
+    print "<- diff_xml_yaml_report\n" if $opt_v > 2;
+    return @results;
+} # 1}}}
+sub diff_csv_report {                        # {{{1
+    # returns an array of lines containing the results
+    my ($version    , # in
+        $elapsed_sec, # in
+        $report_type, # in  "by language" | "by report file" | "by file"
+        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}
+        $rh_scale   , # in  unused
+       ) = @_;
+    print "-> diff_csv_report\n" if $opt_v > 2;
+
+#use Data::Dumper;
+#print "diff_csv_report: ", Dumper($rhhh_count), "\n";
+#die;
+    my @results       = ();
+    my $languages     = ();
+
+    my $data_line   = "";
+    my $BY_LANGUAGE = 0;
+    my $BY_FILE     = 0;
+    if      ($report_type eq "by language") {
+        $BY_LANGUAGE  = 1;
+    } elsif ($report_type eq "by file")     {
+        $BY_FILE      = 1;
+    }
+    my $DELIM = ",";
+       $DELIM = $opt_csv_delimiter if defined $opt_csv_delimiter;
+
+    $elapsed_sec = 0.5 unless $elapsed_sec;
+
+    my $line = "Language${DELIM} ";
+       $line = "File${DELIM} " if $BY_FILE;
+    foreach my $item (qw(files blank comment code)) {
+        next if $BY_FILE and $item eq 'files';
+        foreach my $symbol ( '==', '!=', '+', '-', ) {
+            $line .= "$symbol $item${DELIM} ";
+        }
+    }
+    $line .= "\"$URL v $version T=$elapsed_sec s\"";
+    push @results, $line;
+
+    foreach my $lang_or_file (keys %{$rhhh_count}) {
+        $rhhh_count->{$lang_or_file}{'code'}{'added'} = 0 unless 
+            defined $rhhh_count->{$lang_or_file}{'code'};
+    }
+    foreach my $lang_or_file (sort {
+                                 $rhhh_count->{$b}{'code'} <=>
+                                 $rhhh_count->{$a}{'code'}
+                               }
+                          keys %{$rhhh_count}) {
+        if ($BY_FILE) {
+            $line = rm_leading_tempdir($lang_or_file, \%TEMP_DIR) . "$DELIM ";
+        } else {
+            $line = $lang_or_file . "${DELIM} ";
+        }
+        foreach my $item (qw(nFiles blank comment code)) {
+            next if $BY_FILE and $item eq 'nFiles';
+            foreach my $symbol (qw(same modified added removed)) {
+                if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {
+                    $line .= "$rhhh_count->{$lang_or_file}{$item}{$symbol}${DELIM} ";
+                } else {
+                    $line .= "0${DELIM} ";
+                }
+            }
+        }
+        push @results, $line;
+    }
+
+    print "<- diff_csv_report\n" if $opt_v > 2;
+    return @results;
+} # 1}}}
+sub rm_leading_tempdir {                     # {{{1
+    my ($in_file, $rh_temp_dirs, ) = @_;
+    my $clean_filename = $in_file;
+    foreach my $temp_d (keys %{$rh_temp_dirs}) {
+        if ($ON_WINDOWS) {
+        # \ -> / necessary to allow the next if test's
+        # m{} to work in the presence of spaces in file names
+            $temp_d         =~ s{\\}{/}g;
+            $clean_filename =~ s{\\}{/}g;
+        }
+        if ($clean_filename =~ m{^$temp_d/}) {
+            $clean_filename =~ s{^$temp_d/}{};
+            last;
+        }
+    }
+    $clean_filename =~ s{/}{\\}g if $ON_WINDOWS; # then go back from / to \
+    return $clean_filename;
+} # 1}}}
+sub generate_sql    {                        # {{{1
+    my ($elapsed_sec, # in
+        $rhh_count  , # in  count{TYPE}{lang|code|blank|comment|scaled}
+        $rh_scale   , # in
+       ) = @_;
+    print "-> generate_sql\n" if $opt_v > 2;
+
+    $opt_sql_project = cwd() unless defined $opt_sql_project;
+    $opt_sql_project =~ s{/}{\\}g if $ON_WINDOWS;
+
+    my $schema = "
+create table metadata (          -- $URL v $VERSION
+                timestamp text,    
+                Project   text,    
+                elapsed_s real);   
+create table t        (
+                Project   text   ,  
+                Language  text   ,  
+                File      text   ,  
+                nBlank    integer,  
+                nComment  integer,  
+                nCode     integer,  
+                nScaled   real   ); 
+";
+    $opt_sql = "-" if $opt_sql eq "1";
+
+    my $open_mode = ">";
+       $open_mode = ">>" if $opt_sql_append;
+
+    my $fh = new IO::File; # $opt_sql, "w";
+    if (!$fh->open("${open_mode}${opt_sql}")) {
+        die "Unable to write to $opt_sql  $!\n";
+    }
+    print $fh $schema unless defined $opt_sql_append;
+
+    print $fh "begin transaction;\n";
+    printf $fh "insert into metadata values('%s', '%s', %f);\n",
+                strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
+                $opt_sql_project, $elapsed_sec;
+
+    my $nIns = 0;
+    foreach my $file (keys %{$rhh_count}) {
+        my $language = $rhh_count->{$file}{'lang'};
+        my $clean_filename = $file;
+        # If necessary (that is, if the input contained an
+        # archive file [.tar.gz, etc]), strip the temporary
+        # directory name which was used to expand the archive
+        # from the file name.
+
+        $clean_filename = rm_leading_tempdir($clean_filename, \%TEMP_DIR);
+        printf $fh "insert into t values('%s', '%s', '%s', %d, %d, %d, %f);\n",
+                    $opt_sql_project           ,
+                    $language                  ,
+                    $clean_filename            ,
+                    $rhh_count->{$file}{'blank'},
+                    $rhh_count->{$file}{'comment'},
+                    $rhh_count->{$file}{'code'}   ,
+                    $rhh_count->{$file}{'code'}*$rh_scale->{$language};
+        ++$nIns;
+        if (!($nIns % 10_000)) {
+            print $fh "commit;\n";
+            print $fh "begin transaction;\n";
+        }
+    }
+    print $fh "commit;\n";
+
+    $fh->close unless $opt_sql eq "-"; # don't try to close STDOUT
+    print "<- generate_sql\n" if $opt_v > 2;
+
+    # sample query:
+    #
+    #   select project, language, 
+    #          sum(nCode)     as Code, 
+    #          sum(nComment)  as Comments, 
+    #          sum(nBlank)    as Blank,  
+    #          sum(nCode)+sum(nComment)+sum(nBlank) as All_Lines,
+    #          100.0*sum(nComment)/(sum(nCode)+sum(nComment)) as Comment_Pct
+    #          from t group by Project, Language order by Project, Code desc;
+    #
+} # 1}}}
+sub output_header   {                        # {{{1
+    my ($header_line, 
+        $hyphen_line,
+        $BY_FILE    ,)    = @_;
+    print "-> output_header\n" if $opt_v > 2;
+    my @R = ();
+    if      ($opt_xml) {
+        if (!$ALREADY_SHOWED_XML_SECTION) {
+            push @R, "<?xml version=\"1.0\"?>";
+            push @R, '<?xml-stylesheet type="text/xsl" href="' .
+                            $opt_xsl . '"?>' if $opt_xsl;
+            push @R, "<results>";
+            push @R, "<header>$header_line</header>";
+            $ALREADY_SHOWED_XML_SECTION = 1;
+        }
+        if ($BY_FILE) {
+            push @R, "<files>";
+        } else {
+            push @R, "<languages>";
+        }
+    } elsif ($opt_yaml) {
+        push @R, "---\n# $header_line";
+    } elsif ($opt_csv) {
+        # append the header to the end of the column headers
+        # to keep the output a bit cleaner from a spreadsheet
+        # perspective
+    } else {
+        if ($ALREADY_SHOWED_HEADER) {
+            push @R, "";
+        } else {
+            push @R, $header_line;
+            $ALREADY_SHOWED_HEADER = 1;
+        }
+        push @R, $hyphen_line;
+    }
+    print "<- output_header\n" if $opt_v > 2;
+    return @R;
+} # 1}}}
+sub generate_report {                        # {{{1
+    # returns an array of lines containing the results
+    my ($version    , # in
+        $elapsed_sec, # in
+        $report_type, # in  "by language" | "by report file" | "by file"
+        $rhh_count  , # in  count{TYPE}{nFiles|code|blank|comment|scaled}
+        $rh_scale   , # in
+       ) = @_;
+
+    print "-> generate_report\n" if $opt_v > 2;
+    my $DELIM = ",";
+       $DELIM = $opt_csv_delimiter if defined $opt_csv_delimiter;
+
+    my @results       = ();
+    
+    my $languages     = ();
+
+    my $sum_files     = 0;
+    my $sum_code      = 0;
+    my $sum_blank     = 0;
+    my $sum_comment   = 0;
+    my $max_len       = 0;
+    foreach my $language (keys %{$rhh_count}) {
+        $sum_files   += $rhh_count->{$language}{'nFiles'} ;
+        $sum_blank   += $rhh_count->{$language}{'blank'}  ;
+        $sum_comment += $rhh_count->{$language}{'comment'};
+        $sum_code    += $rhh_count->{$language}{'code'}   ;
+        $max_len      = length($language) if length($language) > $max_len;
+    }
+    my $column_1_offset = 0;
+       $column_1_offset = $max_len - 17 if $max_len > 17;
+    my $sum_lines = $sum_blank + $sum_comment + $sum_code;
+    $elapsed_sec = 0.5 unless $elapsed_sec;
+
+    my $spacing_0 = 23;
+    my $spacing_1 = 13;
+    my $spacing_2 =  9;
+    my $spacing_3 = 17;
+    if (!$opt_3) {
+        $spacing_1 = 19;
+        $spacing_2 = 14;
+        $spacing_3 = 28;
+    }
+    $spacing_0 += $column_1_offset;
+    $spacing_1 += $column_1_offset;
+    $spacing_3 += $column_1_offset;
+    my %Format = (
+        '1' => { 'xml' => 'name="%s" ',
+                 'txt' => "\%-${spacing_0}s ",
+               },
+        '2' => { 'xml' => 'name="%s" ',
+                 'txt' => "\%-${spacing_3}s ",
+               },
+        '3' => { 'xml' => 'files_count="%d" ',
+                 'txt' => '%5d ',
+               },
+        '4' => { 'xml' => 'blank="%d" comment="%d" code="%d" ',
+                 'txt' => "\%${spacing_2}d \%${spacing_2}d \%${spacing_2}d",
+               },
+        '5' => { 'xml' => 'factor="%.2f" scaled="%.2f" ',
+                 'txt' => ' x %6.2f = %14.2f',
+               },
+    );
+    my $Style = "txt";
+       $Style = "xml" if $opt_xml ;
+       $Style = "xml" if $opt_yaml;  # not a typo; just set to anything but txt
+       $Style = "xml" if $opt_csv ;  # not a typo; just set to anything but txt
+
+    my $hyphen_line = sprintf "%s", '-' x (79 + $column_1_offset);
+       $hyphen_line = sprintf "%s", '-' x (68 + $column_1_offset) 
+            if (!$opt_3) and (68 + $column_1_offset) > 79;
+    my $data_line  = "";
+    my $first_column;
+    my $BY_LANGUAGE = 0;
+    my $BY_FILE     = 0;
+    if      ($report_type eq "by language") {
+        $first_column = "Language";
+        $BY_LANGUAGE  = 1;
+    } elsif ($report_type eq "by file")     {
+        $first_column = "File";
+        $BY_FILE      = 1;
+    } elsif ($report_type eq "by report file")     {
+        $first_column = "File";
+        $BY_FILE      = 1;
+    } else {
+        $first_column = "Report File";
+    }
+
+    my $header_line  = sprintf "%s v %s", $URL, $version;
+       $header_line .= sprintf("  T=%.2f s (%.1f files/s, %.1f lines/s)",
+                        $elapsed_sec           ,
+                        $sum_files/$elapsed_sec,
+                        $sum_lines/$elapsed_sec) unless $opt_sum_reports;
+    if ($opt_xml or $opt_yaml) {
+        if (!$ALREADY_SHOWED_HEADER) {
+            push @results, xml_or_yaml_header($URL, $version, $elapsed_sec, 
+                                              $sum_files, $sum_lines, $BY_FILE);
+            $ALREADY_SHOWED_HEADER = 1 unless $opt_sum_reports;
+            # --sum-reports yields two xml or yaml files, one by
+            # language and one by report file, each of which needs a header
+        }
+        if ($opt_xml) {
+            if ($BY_FILE) {
+                push @results, "<files>";
+            } else {
+                push @results, "<languages>";
+            }
+        }
+    } else {
+        push @results, output_header($header_line, $hyphen_line, $BY_FILE);
+    }
+
+    if ($Style eq "txt") {
+        # column headers
+        if (!$opt_3 and $BY_FILE) {
+            my $spacing_n = $spacing_1 - 11;
+            $data_line  = sprintf "%-${spacing_n}s ", $first_column;
+        } else {
+            $data_line  = sprintf "%-${spacing_1}s ", $first_column;
+        }
+        if ($BY_FILE) {
+            $data_line .= sprintf "%${spacing_2}s "  , " "    ;
+        } else {
+            $data_line .= sprintf "%${spacing_2}s "  , "files";
+        }
+        $data_line .= sprintf "%${spacing_2}s %${spacing_2}s %${spacing_2}s",
+            "blank"         ,
+            "comment"       ,
+            "code";
+        $data_line .= sprintf " %8s   %14s",
+            "scale"         ,
+            "3rd gen. equiv"
+              if $opt_3;
+        push @results, $data_line;
+        push @results, $hyphen_line;
+    }
+    if ($opt_csv) {
+        my $header2;
+        if ($BY_FILE) {
+            $header2 = "language${DELIM}filename";
+        } else {
+            $header2 = "files${DELIM}language";
+        }
+        $header2 .= "${DELIM}blank${DELIM}comment${DELIM}code";
+        $header2 .= "${DELIM}scale${DELIM}3rd gen. equiv" if $opt_3;
+        $header2 .= ${DELIM} . '"' . $header_line . '"';
+        push @results, $header2;
+    }
+
+    my $sum_scaled = 0;
+####foreach my $lang_or_file (keys %{$rhh_count}) {
+####    $rhh_count->{$lang_or_file}{'code'} = 0 unless 
+####        defined $rhh_count->{$lang_or_file}{'code'};
+####}
+    foreach my $lang_or_file (sort {
+                                 $rhh_count->{$b}{'code'} <=>
+                                 $rhh_count->{$a}{'code'}
+                               }
+                          keys %{$rhh_count}) {
+        next if $lang_or_file eq "by report file";
+        my ($factor, $scaled);
+        if ($BY_LANGUAGE or $BY_FILE) {
+            $factor = 1;
+            if ($BY_LANGUAGE) {
+                if (defined $rh_scale->{$lang_or_file}) {
+                    $factor = $rh_scale->{$lang_or_file};
+                } else {
+                    warn "No scale factor for $lang_or_file; using 1.00";
+                }
+            } else { # by individual code file
+                if ($report_type ne "by report file") {
+                    next unless defined $rhh_count->{$lang_or_file}{'lang'};
+                    next unless defined $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};
+                    $factor = $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};
+                }
+            }
+            $scaled = $factor*$rhh_count->{$lang_or_file}{'code'};
+        } else {
+            if (!defined $rhh_count->{$lang_or_file}{'scaled'}) {
+                $opt_3 = 0;
+                # If we're summing together files previously generated
+                # with --no3 then rhh_count->{$lang_or_file}{'scaled'}
+                # this variable will be undefined.  That should only
+                # happen when summing together by file however.
+            } elsif ($BY_LANGUAGE) {
+                warn "Missing scaled language info for $lang_or_file\n";
+            }
+            if ($opt_3) {
+                $scaled =         $rhh_count->{$lang_or_file}{'scaled'};
+                $factor = $scaled/$rhh_count->{$lang_or_file}{'code'};
+            }
+        }
+
+        if ($BY_FILE) {
+            my $clean_filename = rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
+            $data_line  = sprintf $Format{'1'}{$Style}, $clean_filename;
+        } else {
+            $data_line  = sprintf $Format{'2'}{$Style}, $lang_or_file;
+        }
+        $data_line .= sprintf $Format{3}{$Style}  , 
+                        $rhh_count->{$lang_or_file}{'nFiles'} unless $BY_FILE;
+        $data_line .= sprintf $Format{4}{$Style}  , 
+            $rhh_count->{$lang_or_file}{'blank'}  ,
+            $rhh_count->{$lang_or_file}{'comment'},
+            $rhh_count->{$lang_or_file}{'code'}   ;
+        $data_line .= sprintf $Format{5}{$Style}  ,
+            $factor                               ,
+            $scaled if $opt_3;
+        $sum_scaled  += $scaled if $opt_3;
+
+        if ($opt_xml) {
+            if (defined $rhh_count->{$lang_or_file}{'lang'}) {
+                my $lang = $rhh_count->{$lang_or_file}{'lang'};
+                if (!defined $languages->{$lang}) {
+                    $languages->{$lang} = $lang;
+                }
+                $data_line.=' language="' . $lang . '" ';
+            }
+            if ($BY_FILE) {
+                push @results, "  <file " . $data_line . "/>";
+            } else {
+                push @results, "  <language " . $data_line . "/>";
+            }
+        } elsif ($opt_yaml) {
+            push @results,$lang_or_file . ":";
+            push @results,"  nFiles: "  .$rhh_count->{$lang_or_file}{'nFiles'} 
+                unless $BY_FILE;
+            push @results,"  blank: "   .$rhh_count->{$lang_or_file}{'blank'}  ;
+            push @results,"  comment: " .$rhh_count->{$lang_or_file}{'comment'};
+            push @results,"  code: "    .$rhh_count->{$lang_or_file}{'code'}   ;
+            push @results,"  language: ".$rhh_count->{$lang_or_file}{'lang'} 
+                if $BY_FILE;
+            if ($opt_3) {
+                push @results, "  scaled: " . $scaled;
+                push @results, "  factor: " . $factor;
+            }
+        } elsif ($opt_csv) {
+            my $extra_3 = "";
+               $extra_3 = "${DELIM}$factor${DELIM}$scaled" if $opt_3;
+            my $first_column = undef;
+            my $clean_name   = $lang_or_file;
+            if ($BY_FILE) { 
+                $first_column = $rhh_count->{$lang_or_file}{'lang'};
+                $clean_name   = rm_leading_tempdir($lang_or_file, \%TEMP_DIR);
+            } else {
+                $first_column = $rhh_count->{$lang_or_file}{'nFiles'};
+            } 
+            my $str = $first_column                         . ${DELIM} .
+                      $clean_name                           . ${DELIM} .
+                      $rhh_count->{$lang_or_file}{'blank'}  . ${DELIM} .
+                      $rhh_count->{$lang_or_file}{'comment'}. ${DELIM} .
+                      $rhh_count->{$lang_or_file}{'code'}   .
+                      $extra_3;
+            push @results, $str;
+        } else {
+            push @results, $data_line;
+        }
+    }
+
+    my $avg_scale = 1;  # weighted average of scale factors
+       $avg_scale = sprintf("%.2f", $sum_scaled / $sum_code) 
+            if $sum_code and $opt_3;
+
+    if ($opt_xml) {
+        $data_line = "";
+        if (!$BY_FILE) {
+            $data_line .= sprintf "sum_files=\"%d\" ", $sum_files;
+        }
+        $data_line .= sprintf $Format{'4'}{$Style},
+            $sum_blank   ,
+            $sum_comment ,
+            $sum_code    ;
+        $data_line .= sprintf $Format{'5'}{$Style},
+            $avg_scale   ,
+            $sum_scaled  if $opt_3;
+        push @results, "  <total " . $data_line . "/>";
+
+        if ($BY_FILE) {
+            push @results, "</files>";
+        } else {
+            foreach my $language (keys %{$languages}) {
+                push @results, '  <language name="' . $language . '"/>';
+            }
+            push @results, "</languages>";
+        }
+
+        if (!$opt_by_file_by_lang or $ALREADY_SHOWED_XML_SECTION) {
+    	    push @results, "</results>";
+        } else {
+            $ALREADY_SHOWED_XML_SECTION = 1;
+        }
+    } elsif ($opt_yaml) {
+        push @results, "SUM:";
+        push @results, "  blank: "  . $sum_blank  ;
+        push @results, "  code: "   . $sum_code   ;
+        push @results, "  comment: ". $sum_comment;
+        push @results, "  nFiles: " . $sum_files  ;
+        if ($opt_3) {
+            push @results, "  scaled: " . $sum_scaled;
+            push @results, "  factor: " . $avg_scale ;
+        }
+    } elsif ($opt_csv) {
+        # do nothing
+    } else {
+
+        if ($BY_FILE) {
+            $data_line  = sprintf "%-${spacing_0}s ", "SUM:"  ;
+        } else {
+            $data_line  = sprintf "%-${spacing_1}s ", "SUM:"  ;
+            $data_line .= sprintf "%${spacing_2}d ", $sum_files;
+        }
+        $data_line .= sprintf $Format{'4'}{$Style},
+            $sum_blank   ,
+            $sum_comment ,
+            $sum_code    ;
+        $data_line .= sprintf $Format{'5'}{$Style},
+            $avg_scale   ,
+            $sum_scaled if $opt_3;
+        push @results, $hyphen_line if $sum_files > 1 or $opt_sum_one;
+        push @results, $data_line   if $sum_files > 1 or $opt_sum_one;
+        push @results, $hyphen_line;
+    }
+    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;
+    print "<- generate_report\n" if $opt_v > 2;
+    return @results;
+} # 1}}}
+sub print_errors {                           # {{{1
+    my ($rh_Error_Codes, # in
+        $raa_errors    , # in
+       ) = @_;
+
+    print "-> print_errors\n" if $opt_v > 2;
+    my %error_string = reverse(%{$rh_Error_Codes});
+    my $nErrors      = scalar @{$raa_errors};
+    warn sprintf "\n%d error%s:\n", plural_form(scalar @Errors);
+    for (my $i = 0; $i < $nErrors; $i++) {
+        warn sprintf "%s:  %s\n", 
+                     $error_string{ $raa_errors->[$i][0] },
+                     $raa_errors->[$i][1] ;
+    }
+    print "<- print_errors\n" if $opt_v > 2;
+
+} # 1}}}
+sub write_lang_def {                         # {{{1
+    my ($file                     ,
+        $rh_Language_by_Extension , # in
+        $rh_Language_by_Script    , # in
+        $rh_Language_by_File      , # in
+        $rhaa_Filters_by_Language , # in
+        $rh_Not_Code_Extension    , # in
+        $rh_Not_Code_Filename     , # in
+        $rh_Scale_Factor          , # in
+        $rh_EOL_Continuation_re   , # in
+       ) = @_;
+
+    print "-> write_lang_def($file)\n" if $opt_v > 2;
+    my $OUT = new IO::File $file, "w";
+    die "Unable to write to $file\n" unless defined $OUT;
+
+    foreach my $language (sort keys %{$rhaa_Filters_by_Language}) {
+        next if $language eq "MATLAB/Objective C/MUMPS" or
+                $language eq "PHP/Pascal"               or
+                $language eq "Lisp/OpenCL";
+        printf $OUT "%s\n", $language;
+        foreach my $filter (@{$rhaa_Filters_by_Language->{$language}}) {
+            printf $OUT "    filter %s", $filter->[0];
+            printf $OUT " %s", $filter->[1] if defined $filter->[1];
+            print  $OUT "\n";
+        }
+        foreach my $ext (sort keys %{$rh_Language_by_Extension}) {
+            if ($language eq $rh_Language_by_Extension->{$ext}) {
+                printf $OUT "    extension %s\n", $ext;
+            }
+        }
+        foreach my $filename (sort keys %{$rh_Language_by_File}) {
+            if ($language eq $rh_Language_by_File->{$filename}) {
+                printf $OUT "    filename %s\n", $filename;
+            }
+        }
+        foreach my $script_exe (sort keys %{$rh_Language_by_Script}) {
+            if ($language eq $rh_Language_by_Script->{$script_exe}) {
+                printf $OUT "    script_exe %s\n", $script_exe;
+            }
+        }
+        printf $OUT "    3rd_gen_scale %.2f\n", $rh_Scale_Factor->{$language};
+        if (defined $rh_EOL_Continuation_re->{$language}) {
+            printf $OUT "    end_of_line_continuation %s\n", 
+                $rh_EOL_Continuation_re->{$language};
+        }
+    }
+
+    $OUT->close;
+    print "<- write_lang_def\n" if $opt_v > 2;
+} # 1}}}
+sub read_lang_def {                          # {{{1
+    my ($file                     ,
+        $rh_Language_by_Extension , # out
+        $rh_Language_by_Script    , # out
+        $rh_Language_by_File      , # out
+        $rhaa_Filters_by_Language , # out
+        $rh_Not_Code_Extension    , # out
+        $rh_Not_Code_Filename     , # out
+        $rh_Scale_Factor          , # out
+        $rh_EOL_Continuation_re   , # out
+        $rh_EOL_abc,
+       ) = @_;
+
+
+    print "-> read_lang_def($file)\n" if $opt_v > 2;
+    my $IN = new IO::File $file, "r";
+    die "Unable to read $file.\n" unless defined $IN;
+
+    my $language = "";
+    while (<$IN>) {
+        next if /^\s*#/ or /^\s*$/;
+
+        if (/^(\w+.*?)\s*$/) {
+            $language = $1;
+            next;
+        }
+        die "Missing computer language name, line $. of $file\n"
+            unless $language;
+
+        if      (/^    filter\s+(\w+)\s*$/) {
+            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]
+
+        } elsif (/^    filter\s+(\w+)\s+(.*?)\s*$/) {
+            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]
+
+        } elsif (/^    extension\s+(\S+)\s*$/) {
+            if (defined $rh_Language_by_Extension->{$1}) {
+                die "File extension collision:  $1 ",
+                    "maps to languages '$rh_Language_by_Extension->{$1}' ",
+                    "and '$language'\n" ,
+                    "Edit $file and remove $1 from one of these two ",
+                    "language definitions.\n";
+            }
+            $rh_Language_by_Extension->{$1} = $language;
+
+        } elsif (/^    filename\s+(\S+)\s*$/) {
+            $rh_Language_by_File->{$1} = $language;
+
+        } elsif (/^    script_exe\s+(\S+)\s*$/) {
+            $rh_Language_by_Script->{$1} = $language;
+
+        } elsif (/^    3rd_gen_scale\s+(\S+)\s*$/) {
+            $rh_Scale_Factor->{$language} = $1;
+
+        } elsif (/^    end_of_line_continuation\s+(\S+)\s*$/) {
+            $rh_EOL_Continuation_re->{$language} = $1;
+
+        } else {
+            die "Unexpected data line $. of $file:\n$_\n";
+        }
+
+    }
+    $IN->close;
+    print "<- read_lang_def\n" if $opt_v > 2;
+} # 1}}}
+sub merge_lang_def {                         # {{{1
+    my ($file                     ,
+        $rh_Language_by_Extension , # in/out
+        $rh_Language_by_Script    , # in/out
+        $rh_Language_by_File      , # in/out
+        $rhaa_Filters_by_Language , # in/out
+        $rh_Not_Code_Extension    , # in/out
+        $rh_Not_Code_Filename     , # in/out
+        $rh_Scale_Factor          , # in/out
+        $rh_EOL_Continuation_re   , # in/out
+        $rh_EOL_abc,
+       ) = @_;
+
+
+    print "-> merge_lang_def($file)\n" if $opt_v > 2;
+    my $IN = new IO::File $file, "r";
+    die "Unable to read $file.\n" unless defined $IN;
+
+    my $language        = "";  
+    my $already_know_it = undef;
+    while (<$IN>) {
+        next if /^\s*#/ or /^\s*$/;
+
+        if (/^(\w+.*?)\s*$/) {
+            $language = $1;
+            $already_know_it = defined $rh_Scale_Factor->{$language};
+            next;
+        }
+        die "Missing computer language name, line $. of $file\n"
+            unless $language;
+
+        if      (/^    filter\s+(\w+)\s*$/) {
+            next if $already_know_it;
+            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]
+
+        } elsif (/^    filter\s+(\w+)\s+(.*?)\s*$/) {
+            next if $already_know_it;
+            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]
+
+        } elsif (/^    extension\s+(\S+)\s*$/) {
+            next if $already_know_it;
+            if (defined $rh_Language_by_Extension->{$1}) {
+                die "File extension collision:  $1 ",
+                    "maps to languages '$rh_Language_by_Extension->{$1}' ",
+                    "and '$language'\n" ,
+                    "Edit $file and remove $1 from one of these two ",
+                    "language definitions.\n";
+            }
+            $rh_Language_by_Extension->{$1} = $language;
+
+        } elsif (/^    filename\s+(\S+)\s*$/) {
+            next if $already_know_it;
+            $rh_Language_by_File->{$1} = $language;
+
+        } elsif (/^    script_exe\s+(\S+)\s*$/) {
+            next if $already_know_it;
+            $rh_Language_by_Script->{$1} = $language;
+
+        } elsif (/^    3rd_gen_scale\s+(\S+)\s*$/) {
+            next if $already_know_it;
+            $rh_Scale_Factor->{$language} = $1;
+
+        } elsif (/^    end_of_line_continuation\s+(\S+)\s*$/) {
+            next if $already_know_it;
+            $rh_EOL_Continuation_re->{$language} = $1;
+
+        } else {
+            die "Unexpected data line $. of $file:\n$_\n";
+        }
+
+    }
+    $IN->close;
+    print "<- merge_lang_def\n" if $opt_v > 2;
+} # 1}}}
+sub print_extension_info {                   # {{{1
+    my ($extension,) = @_;
+    if ($extension) {  # show information on this extension
+        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
+            # Language_by_Extension{f}    = 'Fortran 77' 
+            printf "%-12s -> %s\n", $ext, $Language_by_Extension{$ext}
+                if $ext =~ m{$extension}i;
+        }
+    } else {           # show information on all  extensions
+        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
+            # Language_by_Extension{f}    = 'Fortran 77' 
+            printf "%-12s -> %s\n", $ext, $Language_by_Extension{$ext};
+        }
+    }
+} # 1}}}
+sub print_language_info {                    # {{{1
+    my ($language,) = @_;
+    my %extensions = (); # the subset matched by the given $language value
+    if ($language) {  # show information on this language
+        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
+            # Language_by_Extension{f}    = 'Fortran 77' 
+            push @{$extensions{$Language_by_Extension{$ext}} }, $ext
+                if $Language_by_Extension{$ext} =~ m{$language}i;
+        }
+    } else {          # show information on all  languages
+        foreach my $ext (sort {lc $a cmp lc $b } keys %Language_by_Extension) {
+            # Language_by_Extension{f}    = 'Fortran 77' 
+            push @{$extensions{$Language_by_Extension{$ext}} }, $ext
+        }
+    }
+
+    # add exceptions (one file extension mapping to multiple languages)
+    if (!$language or 
+        $language =~ /^(Objective C|MATLAB|MUMPS)$/i) {
+        push @{$extensions{'Objective C'}}, "m";
+        push @{$extensions{'MATLAB'}}     , "m";
+        push @{$extensions{'MUMPS'}}      , "m";
+        delete $extensions{'MATLAB/Objective C/MUMPS'};
+    } elsif ($language =~ /^(Lisp|OpenCL)$/i) {
+        push @{$extensions{'Lisp'}}  , "cl";
+        push @{$extensions{'OpenCL'}}, "cl";
+        delete $extensions{'Lisp/OpenCL'};
+    } elsif ($language =~ /^(Ant)$/i) {
+        push @{$extensions{'Ant'}}  , "build.xml";
+        delete $extensions{'Ant/XML'};
+    }
+
+    if (%extensions) {
+        foreach my $lang (sort {lc $a cmp lc $b } keys %extensions) {
+            printf "%-26s (%s)\n", $lang, join(", ", @{$extensions{$lang}});
+        }
+    }
+} # 1}}}
+sub make_file_list {                         # {{{1
+    my ($ra_arg_list,  # in   file and/or directory names to examine
+        $rh_Err     ,  # in   hash of error codes
+        $raa_errors ,  # out  errors encountered
+        $rh_ignored ,  # out  files not recognized as computer languages
+        ) = @_;
+    print "-> make_file_list(@{$ra_arg_list})\n" if $opt_v > 2;
+
+    my ($fh, $filename);
+    if ($opt_categorized) {
+        $filename = $opt_categorized;
+        $fh = new IO::File $filename, "+>";  # open for read/write
+        die "Unable to write to $filename:  $!\n" unless defined $fh;
+    } elsif ($opt_sdir) {
+        # write to the user-defined scratch directory
+        $filename = $opt_sdir . '/cloc_file_list.txt';
+        $fh = new IO::File $filename, "+>";  # open for read/write
+        die "Unable to write to $filename:  $!\n" unless defined $fh;
+    } else {
+        # let File::Temp create a suitable temporary file
+        ($fh, $filename) = tempfile(UNLINK => 1);  # delete file on exit
+        print "Using temp file list [$filename]\n" if $opt_v;
+    }
+
+    my @dir_list = ();
+    foreach my $file_or_dir (@{$ra_arg_list}) {
+#print "make_file_list file_or_dir=$file_or_dir\n";
+        my $size_in_bytes = 0;
+        if (!-r $file_or_dir) {
+            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file_or_dir];
+            next;
+        }
+        if (is_file($file_or_dir)) {
+            if (!(-s $file_or_dir)) {   # 0 sized file, named pipe, socket 
+                $rh_ignored->{$file_or_dir} = 'zero sized file';
+                next;
+            } elsif (-B $file_or_dir and !$opt_read_binary_files) { 
+                # avoid binary files unless user insists on reading them
+                if ($opt_unicode) {
+                    # only ignore if not a Unicode file w/trivial 
+                    # ASCII transliteration
+                    if (!unicode_file($file_or_dir)) {
+                        $rh_ignored->{$file_or_dir} = 'binary file';
+                        next;
+                    }
+                } else {
+                    $rh_ignored->{$file_or_dir} = 'binary file';
+                    next;
+                }
+            }
+            push @file_list, "$file_or_dir";
+        } elsif (is_dir($file_or_dir)) {
+            push @dir_list, $file_or_dir;
+        } else {
+            push @{$raa_errors}, [$rh_Err->{'Neither file nor directory'} , $file_or_dir];
+            $rh_ignored->{$file_or_dir} = 'not file, not directory';
+        }
+    }
+    foreach my $dir (@dir_list) {
+#print "make_file_list dir=$dir\n";
+        # populates global variable @file_list
+        find({wanted => \&files, follow => $opt_follow_links }, $dir);  
+    }
+    $nFiles_Found = scalar @file_list;
+    printf "%8d text file%s.\n", plural_form($nFiles_Found) unless $opt_quiet;
+    write_file($opt_found, sort @file_list) if $opt_found;
+
+    my $nFiles_Categorized = 0;
+    foreach my $file (@file_list) {
+        printf "classifying $file\n" if $opt_v > 2;
+
+        my $basename = basename $file;
+        if ($Not_Code_Filename{$basename}) {
+            $rh_ignored->{$file} = "listed in " . '$' .
+                "Not_Code_Filename{$basename}";
+            next;
+        } elsif ($basename =~ m{~$}) {
+            $rh_ignored->{$file} = "temporary editor file";
+            next;
+        }
+
+        my $size_in_bytes = (stat $file)[7];
+        my $language      = "";
+        if ($All_One_Language) {
+            # user over-rode auto-language detection by using
+            # --force-lang with just a language name (no extension)
+            $language      = $All_One_Language;
+        } else {
+            $language      = classify_file($file      ,
+                                           $rh_Err    ,
+                                           $raa_errors,
+                                           $rh_ignored);
+        }
+die  "make_file_list($file) undef size" unless defined $size_in_bytes;
+die  "make_file_list($file) undef lang" unless defined $language;
+        printf $fh "%d,%s,%s\n", $size_in_bytes, $language, $file;
+        ++$nFiles_Categorized;
+        #printf "classified %d files\n", $nFiles_Categorized 
+        #    unless (!$opt_progress_rate or 
+        #            ($nFiles_Categorized % $opt_progress_rate));
+    }
+    printf "classified %d files\r", $nFiles_Categorized 
+        if !$opt_quiet and $nFiles_Categorized > 1;
+
+    print "<- make_file_list()\n" if $opt_v > 2;
+
+    return $fh;   # handle to the file containing the list of files to process
+}  # 1}}}
+sub remove_duplicate_files {                 # {{{1
+    my ($fh                   , # in 
+        $rh_Language          , # out
+        $rh_unique_source_file, # out
+        $rh_Err               , # in
+        $raa_errors           , # out  errors encountered
+        $rh_ignored           , # out
+        ) = @_;
+
+    # Check for duplicate files by comparing file sizes.
+    # Where files are equally sized, compare their MD5 checksums.
+    print "-> remove_duplicate_files\n" if $opt_v > 2;
+
+    my $n = 0;
+    my %files_by_size = (); # files_by_size{ # bytes } = [ list of files ]
+    seek($fh, 0, 0); # rewind to beginning of the temp file
+    while (<$fh>) {
+        ++$n;
+        my ($size_in_bytes, $language, $file) = split(/,/, $_, 3);
+        chomp($file);
+        $rh_Language->{$file} = $language;
+        push @{$files_by_size{$size_in_bytes}}, $file;
+        if ($opt_skip_uniqueness) {
+            $rh_unique_source_file->{$file} = 1;
+        }
+    }
+    return if $opt_skip_uniqueness;
+    if ($opt_progress_rate and ($n > $opt_progress_rate)) {
+        printf "Duplicate file check %d files (%d known unique)\r", 
+            $n, scalar keys %files_by_size;
+    }
+    $n = 0;
+    foreach my $bytes (sort {$a <=> $b} keys %files_by_size) {
+        ++$n;
+        printf "Unique: %8d files                                          \r",
+            $n unless (!$opt_progress_rate or ($n % $opt_progress_rate));
+        if (scalar @{$files_by_size{$bytes}} == 1) {
+            # only one file is this big; must be unique
+            $rh_unique_source_file->{$files_by_size{$bytes}[0]} = 1;
+            next;
+        } else {
+#print "equally sized files: ",join(", ", @{$files_by_size{$bytes}}), "\n";
+            # Files in the list @{$files_by_size{$bytes} all are
+            # $bytes long.  Sort the list by file basename.
+            my @sorted_bn = ();
+            my %BN = map { basename($_) => $_ } @{$files_by_size{$bytes}};
+            foreach my $F (sort keys %BN) {
+                push @sorted_bn, $BN{$F};
+            }
+            foreach my $F (different_files(\@sorted_bn  ,
+                                            $rh_Err     ,
+                                            $raa_errors ,
+                                            $rh_ignored ) ) {
+                $rh_unique_source_file->{$F} = 1;
+            }
+        }
+    }
+    print "<- remove_duplicate_files\n" if $opt_v > 2;
+} # 1}}}
+sub files {                                  # {{{1
+    # invoked by File::Find's find()   Populates global variables,
+    # @file_list, %Ignored
+    if ($opt_exclude_dir or $opt_exclude_list_file) {
+        my $return = 0;
+        foreach my $skip_dir (keys %Exclude_Dir) {
+            # File::Find::dir used to always start with / but
+            # newer versions (1.13) no longer do; have to correct for this
+            my $dir = $File::Find::dir;
+               $dir = "./$dir" unless $dir =~ m{^/};
+            if ($dir =~ m{/\Q$skip_dir\E(/|$)} ) {
+                $Ignored{$File::Find::name} = "--exclude-dir=$skip_dir";
+                $return = 1;
+                last;
+            }
+        }
+        return if $return;
+    }
+    my $Dir = cwd(); # not $File::Find::dir which just gives relative path
+	if ($opt_match_f    ) {	return unless /$opt_match_f/;     }
+    if ($opt_not_match_f) {	return if     /$opt_not_match_f/; }
+	if ($opt_match_d    ) {	return unless $Dir =~ m{$opt_match_d}     }
+    if ($opt_not_match_d) {	return if     $Dir =~ m{$opt_not_match_d} }
+
+    my $nBytes = -s     $_ ;
+    if (!$nBytes) {
+        $Ignored{$File::Find::name} = 'zero sized file';
+        printf "files(%s)  zero size\n", $File::Find::name if $opt_v > 5;
+    }
+    return unless $nBytes  ; # attempting other tests w/pipe or socket will hang
+    if ($nBytes > $opt_max_file_size*1024**2) {
+        $Ignored{$File::Find::name} = "file size of " .
+            $nBytes/1024**2 . " MB exceeds max file size of " .
+            "$opt_max_file_size MB";
+        printf "file(%s)  exceeds $opt_max_file_size MB\n", 
+            $File::Find::name if $opt_v > 5;
+        return;
+    }
+    my $is_dir = is_dir($_);
+    my $is_bin = -B     $_ ;
+    printf "files(%s)  size=%d is_dir=%d  -B=%d\n",
+        $File::Find::name, $nBytes, $is_dir, $is_bin if $opt_v > 5;
+    $is_bin = 0 if $opt_unicode and unicode_file($_);
+    $is_bin = 0 if $opt_read_binary_files;
+    return if $is_dir or $is_bin;
+    ++$nFiles_Found;
+    printf "%8d files\r", $nFiles_Found 
+        unless (!$opt_progress_rate or ($nFiles_Found % $opt_progress_rate));
+    push @file_list, $File::Find::name;
+} # 1}}}
+sub archive_files {                          # {{{1
+    # invoked by File::Find's find()  Populates global variable @binary_archive
+    foreach my $ext (keys %Known_Binary_Archives) {
+        push @binary_archive, $File::Find::name 
+            if $File::Find::name =~ m{$ext$};
+    }
+} # 1}}}
+sub is_file {                                # {{{1
+    # portable method to test if item is a file
+    # (-f doesn't work in ActiveState Perl on Windows)
+    my $item = shift @_;
+
+    if ($ON_WINDOWS) {
+        my $mode = (stat $item)[2];
+           $mode = 0 unless $mode;
+        if ($mode & 0100000) { return 1; } 
+        else                 { return 0; }
+    } else {
+        return (-f $item);  # works on Unix, Linux, CygWin, z/OS
+    }
+} # 1}}}
+sub is_dir {                                 # {{{1
+    # portable method to test if item is a directory
+    # (-d doesn't work in ActiveState Perl on Windows)
+    my $item = shift @_;
+
+    if ($ON_WINDOWS) {
+        my $mode = (stat $item)[2];
+           $mode = 0 unless $mode;
+        if ($mode & 0040000) { return 1; } 
+        else                 { return 0; }
+    } else {
+        return (-d $item);  # works on Unix, Linux, CygWin, z/OS
+    }
+} # 1}}}
+sub is_excluded {                            # {{{1
+    my ($file       , # in
+        $excluded   , # in   hash of excluded directories
+       ) = @_;
+    my($filename, $filepath, $suffix) = fileparse($file);
+    foreach my $path (sort keys %{$excluded}) {
+        return 1 if ($filepath =~ m{^$path/}i);
+    }
+} # 1}}}
+sub classify_file {                          # {{{1
+    my ($full_file   , # in
+        $rh_Err      , # in   hash of error codes
+        $raa_errors  , # out
+        $rh_ignored  , # out
+       ) = @_;
+
+    print "-> classify_file($full_file)\n" if $opt_v > 2;
+    my $language = "(unknown)";
+
+    if (basename($full_file) eq "-" && defined $opt_stdin_name) {
+       $full_file = $opt_stdin_name;
+    }
+
+    my $look_at_first_line = 0;
+    my $file = basename $full_file; 
+    if ($opt_autoconf and $file =~ /\.in$/) {
+       $file =~ s/\.in$//;
+    }
+    return $language if $Not_Code_Filename{$file}; # (unknown)
+    return $language if $file =~ m{~$}; # a temp edit file (unknown)
+    if (defined $Language_by_File{$file}) {
+        if      ($Language_by_File{$file} eq "Ant/XML") {
+            return Ant_or_XML(  $full_file, $rh_Err, $raa_errors);
+        } elsif ($Language_by_File{$file} eq "Maven/XML") {
+            return Maven_or_XML($full_file, $rh_Err, $raa_errors);
+        } else {
+            return $Language_by_File{$file};
+        }
+    }
+
+    if ($file =~ /\.(\w+)$/) { # has an extension
+      print "$full_file extension=[$1]\n" if $opt_v > 2;
+      my $extension = $1;
+         # Windows file names are case insensitive so map 
+         # all extensions to lowercase there.
+         $extension = lc $extension if $ON_WINDOWS;  
+      my @extension_list = ( $extension );
+      if ($file =~ /\.(\w+\.\w+)$/) { # has a double extension
+          my $extension = $1;
+          $extension = lc $extension if $ON_WINDOWS;  
+          unshift @extension_list, $extension;  # examine double ext first
+      }
+      foreach my $extension (@extension_list) {
+        if ($Not_Code_Extension{$extension} and 
+           !$Forced_Extension{$extension}) {
+           # If .1 (for example) is an extention that would ordinarily be
+           # ignored but the user has insisted this be counted with the
+           # --force-lang option, then go ahead and count it.
+            $rh_ignored->{$full_file} = 
+                'listed in $Not_Code_Extension{' . $extension . '}';
+            return $language;
+        }
+        if (defined $Language_by_Extension{$extension}) {
+            if ($Language_by_Extension{$extension} eq
+                'MATLAB/Objective C/MUMPS') {
+                my $lang_M_or_O = "";
+                matlab_or_objective_C($full_file , 
+                                      $rh_Err    ,
+                                      $raa_errors,
+                                     \$lang_M_or_O);
+                if ($lang_M_or_O) {
+                    return $lang_M_or_O;
+                } else { # an error happened in matlab_or_objective_C()
+                    $rh_ignored->{$full_file} = 
+                        'failure in matlab_or_objective_C()';
+                    return $language; # (unknown)
+                }
+            } elsif ($Language_by_Extension{$extension} eq 'PHP/Pascal') {
+                if (really_is_php($full_file)) {
+                    return 'PHP';
+                } elsif (really_is_incpascal($full_file)) {
+                    return 'Pascal';
+                } else {
+                    return $language; # (unknown)
+                }
+            } elsif ($Language_by_Extension{$extension} eq 'Lisp/OpenCL') {
+                return Lisp_or_OpenCL($full_file, $rh_Err, $raa_errors);
+            } elsif ($Language_by_Extension{$extension} eq 'Smarty') {
+                # Smarty extension .tpl is generic; make sure the
+                # file at least roughly resembles PHP.  Alternatively,
+                # if the user forces the issue, do the count.
+                my $force_smarty = 0;
+                foreach (@opt_force_lang) {
+                    if (lc($_) eq "smarty,tpl") {
+                        $force_smarty = 1; 
+                        last;
+                    }
+                }
+                if (really_is_php($full_file) or $force_smarty) {
+                    return 'Smarty';
+                } else {
+                    return $language; # (unknown)
+                }
+            } else {
+                return $Language_by_Extension{$extension};
+            }
+        } else { # has an unmapped file extension
+            $look_at_first_line = 1;
+        }
+      }
+    } elsif (defined $Language_by_File{lc $file}) {
+        return $Language_by_File{lc $file};
+    } elsif ($opt_lang_no_ext and 
+             defined $Filters_by_Language{$opt_lang_no_ext}) {
+        return $opt_lang_no_ext;
+    } else {  # no file extension
+        $look_at_first_line = 1;
+    }
+
+    if ($look_at_first_line) {
+        # maybe it is a shell/Perl/Python/Ruby/etc script that
+        # starts with pound bang:
+        #   #!/usr/bin/perl
+        #   #!/usr/bin/env perl
+        my $script_language = peek_at_first_line($full_file , 
+                                                 $rh_Err    , 
+                                                 $raa_errors);
+        if (!$script_language) {
+            $rh_ignored->{$full_file} = "language unknown (#2)";
+            # returns (unknown)
+        }
+        if (defined $Language_by_Script{$script_language}) {
+            if (defined $Filters_by_Language{
+                            $Language_by_Script{$script_language}}) {
+                $language = $Language_by_Script{$script_language};
+            } else {
+                $rh_ignored->{$full_file} = 
+                    "undefined:  Filters_by_Language{" . 
+                    $Language_by_Script{$script_language} .
+                    "} for scripting language $script_language";
+                # returns (unknown)
+            }
+        } else {
+            $rh_ignored->{$full_file} = "language unknown (#3)";
+            # returns (unknown)
+        }
+    }
+    print "<- classify_file($full_file)\n" if $opt_v > 2;
+    return $language;
+} # 1}}}
+sub peek_at_first_line {                     # {{{1
+    my ($file        , # in
+        $rh_Err      , # in   hash of error codes
+        $raa_errors  , # out
+       ) = @_;
+
+    print "-> peek_at_first_line($file)\n" if $opt_v > 2;
+
+    my $script_language = "";
+    if (!-r $file) {
+        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
+        return $script_language;
+    }
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
+        print "<- peek_at_first_line($file)\n" if $opt_v > 2;
+        return $script_language;
+    }
+    chomp(my $first_line = <$IN>);
+    if (defined $first_line) {
+#print "peek_at_first_line of [$file] first_line=[$first_line]\n";
+        if ($first_line =~ /^#\!\s*(\S.*?)$/) {
+#print "peek_at_first_line 1=[$1]\n";
+            my @pound_bang = split(' ', $1);
+#print "peek_at_first_line basename 0=[", basename($pound_bang[0]), "]\n";
+            if (basename($pound_bang[0]) eq "env" and 
+                scalar @pound_bang > 1) {
+                $script_language = $pound_bang[1];
+#print "peek_at_first_line pound_bang A $pound_bang[1]\n";
+            } else {
+                $script_language = basename $pound_bang[0];
+#print "peek_at_first_line pound_bang B $script_language\n";
+            }
+        }
+    }
+    $IN->close;
+    print "<- peek_at_first_line($file)\n" if $opt_v > 2;
+    return $script_language;
+} # 1}}}
+sub different_files {                        # {{{1
+    # See which of the given files are unique by computing each file's MD5
+    # sum.  Return the subset of files which are unique.
+    my ($ra_files    , # in
+        $rh_Err      , # in
+        $raa_errors  , # out
+        $rh_ignored  , # out
+       ) = @_;
+
+    print "-> different_files(@{$ra_files})\n" if $opt_v > 2;
+    my %file_hash = ();  # file_hash{md5 hash} = [ file1, file2, ... ]
+    foreach my $F (@{$ra_files}) {
+        next if is_dir($F);  # needed for Windows
+        my $IN = new IO::File $F, "r";
+        if (!defined $IN) {
+            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F];
+            $rh_ignored->{$F} = 'cannot read';
+        } else {
+            if ($HAVE_Digest_MD5) {
+                binmode $IN;
+                my $MD5 = Digest::MD5->new->addfile($IN)->hexdigest;
+#print "$F, $MD5\n";
+                push @{$file_hash{$MD5}}, $F;
+            } else {
+                # all files treated unique
+                push @{$file_hash{$F}}, $F;
+            }
+            $IN->close;
+        }
+    }
+
+    # Loop over file sets having identical MD5 sums.  Within
+    # each set, pick the file that most resembles known source 
+    # code.
+    my @unique = ();
+    for my $md5 (sort keys %file_hash) {
+        my $i_best = 0;
+        for (my $i = 1; $i < scalar(@{$file_hash{$md5}}); $i++) {
+            my $F = $file_hash{$md5}[$i];
+            my (@nul_a, %nul_h);
+            my $language = classify_file($F, $rh_Err, 
+                                        # don't save these errors; pointless
+                                        \@nul_a, \%nul_h);
+            $i_best = $i if $language ne "(unknown)";
+        }
+        # keep the best one found and identify the rest as ignored
+        for (my $i = 0; $i < scalar(@{$file_hash{$md5}}); $i++) {
+            if ($i == $i_best) {
+                push @unique, $file_hash{$md5}[$i_best];
+            } else {
+                $rh_ignored->{$file_hash{$md5}[$i]} = "duplicate of " .
+                    $file_hash{$md5}[$i_best];
+            }
+        }
+
+    }
+    print "<- different_files(@unique)\n" if $opt_v > 2;
+    return @unique;
+} # 1}}}
+sub call_counter {                           # {{{1
+    my ($file     , # in
+        $language , # in
+        $ra_Errors, # out
+       ) = @_;
+
+    # Logic:  pass the file through the following filters:
+    #         1. remove blank lines
+    #         2. remove comments using each filter defined for this language
+    #            (example:  SQL has two, remove_starts_with(--) and 
+    #             remove_c_comments() )
+    #         3. compute comment lines as 
+    #               total lines - blank lines - lines left over after all
+    #                   comment filters have been applied
+
+    print "-> call_counter($file, $language)\n" if $opt_v > 2;
+#print "call_counter:  ", Dumper(@routines), "\n";
+
+    my @lines = ();
+    my $ascii = "";
+    if (-B $file and $opt_unicode) {
+        # was binary so must be unicode
+
+        $/ = undef;
+        my $IN = new IO::File $file, "r";
+        my $bin_text = <$IN>;
+        $IN->close;
+        $/ = "\n";
+
+        $ascii = unicode_to_ascii( $bin_text );
+        @lines = split("\n", $ascii );
+        foreach (@lines) { $_ = "$_\n"; }
+
+    } else {
+        # regular text file
+        @lines = read_file($file);
+        $ascii = join('', @lines);
+    }
+
+    my @original_lines = @lines;
+    my $total_lines    = scalar @lines;
+
+    print_lines($file, "Original file:", \@lines) if $opt_print_filter_stages;
+    @lines = rm_blanks(\@lines, $language, \%EOL_Continuation_re); # remove blank lines
+    my $blank_lines = $total_lines - scalar @lines;
+    print_lines($file, "Blank lines removed:", \@lines) 
+        if $opt_print_filter_stages;
+
+    @lines = rm_comments(\@lines, $language, $file,
+                               \%EOL_Continuation_re);
+
+    my $comment_lines = $total_lines - $blank_lines - scalar  @lines;
+    if ($opt_strip_comments) {
+        my $stripped_file = "";
+        if ($opt_original_dir) {
+            $stripped_file =          $file . ".$opt_strip_comments";
+        } else {
+            $stripped_file = basename $file . ".$opt_strip_comments";
+        }
+        write_file($stripped_file, @lines);
+    }
+    if ($opt_html and !$opt_diff) {
+        chomp(@original_lines);  # includes blank lines, comments
+        chomp(@lines);           # no blank lines, no comments
+
+        my (@diff_L, @diff_R, %count);
+
+        # remove blank lines to get better quality diffs; count
+        # blank lines separately
+        my @original_lines_minus_white = ();
+        # however must keep track of how many blank lines were removed and
+        # where they were removed so that the HTML display can include it
+        my %blank_line  = ();
+        my $insert_line = 0;
+        foreach (@original_lines) {
+            if (/^\s*$/) {
+               ++$count{blank}{same};
+               ++$blank_line{ $insert_line };
+            } else {
+                ++$insert_line;
+                push @original_lines_minus_white, $_;
+            }
+        }
+
+        array_diff( $file                       ,   # in
+                   \@original_lines_minus_white ,   # in
+                   \@lines                      ,   # in
+                   "comment"                    ,   # in
+                   \@diff_L, \@diff_R,          ,   # out
+                    $ra_Errors);                    # in/out
+        write_comments_to_html($file, \@diff_L, \@diff_R, \%blank_line);
+#print Dumper("count", \%count);
+    }
+
+    print "<- call_counter($total_lines, $blank_lines, $comment_lines)\n" 
+        if $opt_v > 2;
+    return ($total_lines, $blank_lines, $comment_lines);
+} # 1}}}
+sub windows_glob {                           # {{{1
+    # Windows doesn't expand wildcards.  Use code from Sean M. Burke's 
+    # Win32::Autoglob module to do this.
+    return map {;
+        ( defined($_) and m/[\*\?]/ ) ? sort(glob($_)) : $_
+          } @_; 
+} # 1}}}
+sub write_file {                             # {{{1
+    my ($file  , # in
+        @lines , # in
+       ) = @_;
+
+#print "write_file 1 [$file]\n";
+    # Do ~ expansion (by Tim LaBerge, fixes bug 2787984)
+    my $preglob_filename = $file;
+#print "write_file 2 [$preglob_filename]\n";
+    if ($ON_WINDOWS) {
+        $file = (windows_glob($file))[0];
+    } else {
+        $file = File::Glob::glob($file);
+    }
+#print "write_file 3 [$file]\n";
+    $file = $preglob_filename unless $file;
+#print "write_file 4 [$file]\n";
+
+    print "-> write_file($file)\n" if $opt_v > 2;
+
+    # Create the destination directory if it doesn't already exist.
+    my $abs_file_path = File::Spec->rel2abs( $file );
+    my ($volume, $directories, $filename) = File::Spec->splitpath( $abs_file_path );
+    mkpath($volume . $directories, 1, 0777);
+    
+    my $OUT = new IO::File $file, "w";
+    if (defined $OUT) {
+        chomp(@lines);
+        print $OUT join("\n", @lines), "\n";
+        $OUT->close;
+    } else {
+        warn "Unable to write to $file\n";
+    }
+    print "Wrote $file" unless $opt_quiet;
+    print ", $CLOC_XSL" if $opt_xsl and $opt_xsl eq $CLOC_XSL;
+    print "\n" unless $opt_quiet;
+    
+    print "<- write_file\n" if $opt_v > 2;
+} # 1}}}
+sub read_file  {                             # {{{1
+    my ($file, ) = @_;
+
+    print "-> read_file($file)\n" if $opt_v > 2;
+    my @lines = ();
+    my $IN = new IO::File $file, "r";
+    if (defined $IN) {
+        @lines = <$IN>;
+        $IN->close;
+        if ($lines[$#lines]) {  # test necessary for zero content files
+                                # (superfluous?)
+            # Some files don't end with a new line.  Force this:
+            $lines[$#lines] .= "\n" unless $lines[$#lines] =~ m/\n$/;
+        }
+    } else {
+        warn "Unable to read $file\n";
+    }
+    print "<- read_file\n" if $opt_v > 2;
+    return @lines;
+} # 1}}}
+sub rm_blanks {                              # {{{1
+    my ($ra_in    ,
+        $language ,
+        $rh_EOL_continuation_re) = @_;
+    print "-> rm_blanks(language=$language)\n" if $opt_v > 2;
+#print "rm_blanks: language = [$language]\n";
+    my @out = ();
+    if ($language eq "COBOL") {
+        @out = remove_cobol_blanks($ra_in);
+    } else {
+        # removes blank lines
+        if (defined $rh_EOL_continuation_re->{$language}) {
+            @out = remove_matches_2re($ra_in, '^\s*$', 
+                                      $rh_EOL_continuation_re->{$language}); 
+        } else {
+            @out = remove_matches($ra_in, '^\s*$');
+        }
+    }
+    print "<- rm_blanks(language=$language)\n" if $opt_v > 2;
+    return @out;
+} # 1}}}
+sub rm_comments {                            # {{{1
+    my ($ra_lines , # in, must be free of blank lines
+        $language , # in
+        $file     , # in (some language counters, eg Haskell, need 
+                    #     access to the original file)
+        $rh_EOL_continuation_re , # in
+       ) = @_;
+    print "-> rm_comments(file=$file)\n" if $opt_v > 2;
+    my @routines       = @{$Filters_by_Language{$language}};
+    my @lines          = @{$ra_lines};
+    my @original_lines = @{$ra_lines};
+
+    foreach my $call_string (@routines) {
+        my $subroutine = $call_string->[0];
+        if (! defined &{$subroutine}) {
+            warn "rm_comments undefined subroutine $subroutine for $file\n";
+            next;
+        }
+        print "rm_comments file=$file sub=$subroutine\n" if $opt_v > 1;
+        my @args  = @{$call_string};
+        shift @args; # drop the subroutine name
+        if (@args and $args[0] eq '>filename<') {
+            shift   @args;
+            unshift @args, $file;
+        }
+
+        no strict 'refs';
+        @lines = &{$subroutine}(\@lines, @args);   # apply filter...
+
+        print_lines($file, "After $subroutine(@args)", \@lines) 
+            if $opt_print_filter_stages;
+        # then remove blank lines which are created by comment removal
+        if (defined $rh_EOL_continuation_re->{$language}) {
+            @lines = remove_matches_2re(\@lines, '^\s*$',
+                                        $rh_EOL_continuation_re->{$language});
+        } else {
+            @lines = remove_matches(\@lines, '^\s*$');
+        }
+        
+        print_lines($file, "post $subroutine(@args) blank cleanup:", \@lines) 
+            if $opt_print_filter_stages;
+    }
+    # Exception for scripting languages:  treat the first #! line as code.
+    # Will need to add it back in if it was removed earlier.
+    if ($Script_Language{$language} and 
+        $original_lines[0] =~ /^#!/ and
+        (scalar(@lines) == 0 or 
+         $lines[0] ne $original_lines[0])) {
+        unshift @lines, $original_lines[0];  # add the first line back
+    }
+    print "<- rm_comments\n" if $opt_v > 2;
+    return @lines;
+} # 1}}}
+sub remove_f77_comments {                    # {{{1
+    my ($ra_lines, ) = @_;
+    print "-> remove_f77_comments\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    foreach (@{$ra_lines}) {
+        next if m{^[*cC]};
+        next if m{^\s*!};
+        push @save_lines, $_;
+    }
+
+    print "<- remove_f77_comments\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_f90_comments {                    # {{{1
+    # derived from SLOCCount
+    my ($ra_lines, ) = @_;
+    print "-> remove_f90_comments\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    foreach (@{$ra_lines}) {
+        # a comment is              m/^\s*!/
+        # an empty line is          m/^\s*$/
+        # a HPF statement is        m/^\s*!hpf\$/i
+        # an Open MP statement is   m/^\s*!omp\$/i
+        if (! m/^(\s*!|\s*$)/ || m/^\s*!(hpf|omp)\$/i) {
+            push @save_lines, $_;
+        }
+    }
+
+    print "<- remove_f90_comments\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_matches {                         # {{{1
+    my ($ra_lines, # in
+        $pattern , # in   Perl regular expression (case insensitive)
+       ) = @_;
+    print "-> remove_matches(pattern=$pattern)\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    foreach (@{$ra_lines}) {
+#chomp; print "remove_matches [$pattern] [$_]\n";
+        next if m{$pattern}i;
+        push @save_lines, $_;
+    }
+
+    print "<- remove_matches\n" if $opt_v > 2;
+#print "remove_matches returning\n   ", join("\n   ", @save_lines), "\n";
+    return @save_lines;
+} # 1}}}
+sub remove_matches_2re {                     # {{{1
+    my ($ra_lines, # in
+        $pattern1, # in Perl regex 1 (case insensitive) to match
+        $pattern2, # in Perl regex 2 (case insensitive) to not match prev line
+       ) = @_;
+    print "-> remove_matches_2re(pattern=$pattern1,$pattern2)\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {
+#print "remove_matches_2re [$pattern1] [$pattern2] [$ra_lines->[$i]]\n";
+        if ($i) {
+#print "remove_matches_2re prev=[$ra_lines->[$i-1]] this=[$ra_lines->[$i]]\n";
+            next if ($ra_lines->[$i]   =~ m{$pattern1}i) and 
+                    ($ra_lines->[$i-1] !~ m{$pattern2}i);
+        } else {
+            # on first line
+            next if $ra_lines->[$i]   =~  m{$pattern1}i;
+        }
+        push @save_lines, $ra_lines->[$i];
+    }
+
+    print "<- remove_matches_2re\n" if $opt_v > 2;
+#print "remove_matches_2re returning\n   ", join("\n   ", @save_lines), "\n";
+    return @save_lines;
+} # 1}}}
+sub remove_inline {                          # {{{1
+    my ($ra_lines, # in
+        $pattern , # in   Perl regular expression (case insensitive)
+       ) = @_;
+    print "-> remove_inline(pattern=$pattern)\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    unless ($opt_inline) {
+        return @{$ra_lines};
+    }
+    my $nLines_affected = 0;
+    foreach (@{$ra_lines}) {
+#chomp; print "remove_inline [$pattern] [$_]\n";
+        if (m{$pattern}i) {
+            ++$nLines_affected;
+            s{$pattern}{}i;
+        }
+        push @save_lines, $_;
+    }
+
+    print "<- remove_inline\n" if $opt_v > 2;
+#print "remove_inline returning\n   ", join("\n   ", @save_lines), "\n";
+    return @save_lines;
+} # 1}}}
+sub remove_above {                           # {{{1
+    my ($ra_lines, $marker, ) = @_;
+    print "-> remove_above(marker=$marker)\n" if $opt_v > 2;
+
+    # Make two passes through the code:
+    # 1. check if the marker exists
+    # 2. remove anything above the marker if it exists,
+    #    do nothing if the marker does not exist
+
+    # Pass 1
+    my $found_marker = 0;
+    for (my $line_number  = 1;
+            $line_number <= scalar @{$ra_lines};
+            $line_number++) {
+        if ($ra_lines->[$line_number-1] =~ m{$marker}) {
+            $found_marker = $line_number;
+            last;
+        }
+    }
+
+    # Pass 2 only if needed
+    my @save_lines = ();
+    if ($found_marker) {
+        my $n = 1;
+        foreach (@{$ra_lines}) {
+            push @save_lines, $_
+                if $n >= $found_marker;
+            ++$n;
+        }
+    } else { # marker wasn't found; save all lines
+        foreach (@{$ra_lines}) {
+            push @save_lines, $_;
+        }
+    }
+
+    print "<- remove_above\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_below {                           # {{{1
+    my ($ra_lines, $marker, ) = @_;
+    print "-> remove_below(marker=$marker)\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    foreach (@{$ra_lines}) {
+        last if m{$marker};
+        push @save_lines, $_;
+    }
+
+    print "<- remove_below\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_below_above {                     # {{{1
+    my ($ra_lines, $marker_below, $marker_above, ) = @_;
+    # delete lines delimited by start and end line markers such
+    # as Perl POD documentation
+    print "-> remove_below_above(markerB=$marker_below, A=$marker_above)\n" 
+        if $opt_v > 2;
+
+    my @save_lines = ();
+    my $between    = 0;
+    foreach (@{$ra_lines}) {
+        if (!$between and m{$marker_below}) {
+            $between    = 1;
+            next;
+        }
+        if ($between and m{$marker_above}) {
+            $between    = 0;
+            next;
+        }
+        next if $between;
+        push @save_lines, $_;
+    }
+
+    print "<- remove_below_above\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_between {                         # {{{1
+    my ($ra_lines, $marker, ) = @_;
+    # $marker must contain one of the balanced pairs understood
+    # by Regexp::Common::balanced, namely
+    # '{}'  '()'  '[]'  or  '<>'
+
+    print "-> remove_between(marker=$marker)\n" if $opt_v > 2;
+    my %acceptable = ('{}'=>1,  '()'=>1,  '[]'=>1,  '<>'=>1, );
+    die "remove_between:  invalid delimiter '$marker'\n",
+        "the delimiter must be one of these four pairs:\n",
+        "{}  ()  []  <>\n" unless
+        $acceptable{$marker};
+
+    Install_Regexp_Common() unless $HAVE_Rexexp_Common;
+
+    my $all_lines = join("", @{$ra_lines});
+
+    no strict 'vars';
+    # otherwise get:
+    #  Global symbol "%RE" requires explicit package name at cloc line xx.
+    if ($all_lines =~ m/$RE{balanced}{-parens => $marker}/) {
+        no warnings; 
+        $all_lines =~ s/$1//g;
+    }
+
+    print "<- remove_between\n" if $opt_v > 2;
+    return split("\n", $all_lines);
+} # 1}}}
+sub remove_between_general {                 # {{{1
+    my ($ra_lines, $start_marker, $end_marker, ) = @_;
+    # Start and end markers may be any length strings.
+
+    print "-> remove_between_general(start=$start_marker, end=$end_marker)\n"
+        if $opt_v > 2;
+
+    my $all_lines = join("", @{$ra_lines});
+
+    my @save_lines = ();
+    my $in_comment = 0;
+    foreach (@{$ra_lines}) {
+
+        next if /^\s*$/;
+        s/\Q$start_marker\E.*?\Q$end_marker\E//g;  # strip one-line comments
+        next if /^\s*$/;
+        if ($in_comment) {
+            if (/\Q$end_marker\E/) {
+                s/^.*?\Q$end_marker\E//;
+                $in_comment = 0;
+            }
+        }
+        next if /^\s*$/;
+        $in_comment = 1 if /^(.*?)\Q$start_marker\E/;
+        next if defined $1 and $1 =~ /^\s*$/;
+        next if ($in_comment);
+        push @save_lines, $_;
+    }
+
+    print "<- remove_between_general\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_cobol_blanks {                    # {{{1
+    # subroutines derived from SLOCCount
+    my ($ra_lines, ) = @_;
+
+    my $free_format = 0;  # Support "free format" source code.
+    my @save_lines  = ();
+  
+    foreach (@{$ra_lines}) {
+        next if m/^\s*$/;
+        my $line = expand($_);  # convert tabs to equivalent spaces
+        $free_format = 1 if $line =~ m/^......\$.*SET.*SOURCEFORMAT.*FREE/i;
+        if ($free_format) {
+            push @save_lines, $_;
+        } else {
+            # Greg Toth:
+            #  (1) Treat lines with any alphanum in cols 1-6 and 
+            #      blanks in cols 7 through 71 as blank line, and
+            #  (2) Treat lines with any alphanum in cols 1-6 and 
+            #      slash (/) in col 7 as blank line (this is a 
+            #      page eject directive). 
+            push @save_lines, $_ unless m/^\d{6}\s*$/             or 
+                                        ($line =~ m/^.{6}\s{66}/) or 
+                                        ($line =~ m/^......\//);
+        }
+    }
+    return @save_lines;
+} # 1}}}
+sub remove_cobol_comments {                  # {{{1
+    # subroutines derived from SLOCCount
+    my ($ra_lines, ) = @_;
+
+    my $free_format = 0;  # Support "free format" source code.
+    my @save_lines  = ();
+  
+    foreach (@{$ra_lines}) {
+        if (m/^......\$.*SET.*SOURCEFORMAT.*FREE/i) {$free_format = 1;}
+        if ($free_format) {
+            push @save_lines, $_ unless m{^\s*\*};
+        } else {
+            push @save_lines, $_ unless m{^......\*} or m{^\*};
+        }
+    }
+    return @save_lines;
+} # 1}}}
+sub remove_jcl_comments {                    # {{{1
+    my ($ra_lines, ) = @_;
+
+    print "-> remove_jcl_comments\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    my $in_comment = 0;
+    foreach (@{$ra_lines}) {
+        next if /^\s*$/;
+        next if m{^\s*//\*};
+        last if m{^\s*//\s*$};
+        push @save_lines, $_;
+    }
+
+    print "<- remove_jcl_comments\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_jsp_comments {                    # {{{1
+    #  JSP comment is   <%--  body of comment   --%>
+    my ($ra_lines, ) = @_;
+
+    print "-> remove_jsp_comments\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    my $in_comment = 0;
+    foreach (@{$ra_lines}) {
+
+        next if /^\s*$/;
+        s/<\%\-\-.*?\-\-\%>//g;  # strip one-line comments
+        next if /^\s*$/;
+        if ($in_comment) {
+            if (/\-\-\%>/) {
+                s/^.*?\-\-\%>//;
+                $in_comment = 0;
+            }
+        }
+        next if /^\s*$/;
+        $in_comment = 1 if /^(.*?)<\%\-\-/;
+        next if defined $1 and $1 =~ /^\s*$/;
+        next if ($in_comment);
+        push @save_lines, $_;
+    }
+
+    print "<- remove_jsp_comments\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub remove_html_comments {                   # {{{1
+    #  HTML comment is   <!--  body of comment   -->
+    #  Need to use my own routine until the HTML comment regex in
+    #  the Regexp::Common module can handle  <!--  --  -->
+    my ($ra_lines, ) = @_;
+
+    print "-> remove_html_comments\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    my $in_comment = 0;
+    foreach (@{$ra_lines}) {
+
+        next if /^\s*$/;
+        s/<!\-\-.*?\-\->//g;  # strip one-line comments
+        next if /^\s*$/;
+        if ($in_comment) {
+            if (/\-\->/) {
+                s/^.*?\-\->//;
+                $in_comment = 0;
+            }
+        }
+        next if /^\s*$/;
+        $in_comment = 1 if /^(.*?)<!\-\-/;
+        next if defined $1 and $1 =~ /^\s*$/;
+        next if ($in_comment);
+        push @save_lines, $_;
+    }
+
+    print "<- remove_html_comments\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub add_newlines {                           # {{{1
+    my ($ra_lines, ) = @_;
+    print "-> add_newlines \n" if $opt_v > 2;
+
+    my @save_lines = ();
+    foreach (@{$ra_lines}) {
+
+        push @save_lines, "$_\n";
+    }
+
+    print "<- add_newlines \n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub docstring_to_C {                         # {{{1
+    my ($ra_lines, ) = @_;
+    # Converts Python docstrings to C comments.
+
+    print "-> docstring_to_C()\n" if $opt_v > 2;
+
+    my $in_docstring = 0;
+    foreach (@{$ra_lines}) {
+        while (/"""/) {
+            if (!$in_docstring) {
+                s{"""}{/*};
+                $in_docstring = 1;
+            } else {
+                s{"""}{*/};
+                $in_docstring = 0;
+            }
+        }
+    }
+
+    print "<- docstring_to_C\n" if $opt_v > 2;
+    return @{$ra_lines};
+} # 1}}}
+sub powershell_to_C {                        # {{{1
+    my ($ra_lines, ) = @_;
+    # Converts PowerShell block comment markers to C comments.
+
+    print "-> powershell_to_C()\n" if $opt_v > 2;
+
+    my $in_docstring = 0;
+    foreach (@{$ra_lines}) {
+        s{<#}{/*}g;
+        s{#>}{*/}g;
+    }
+
+    print "<- powershell_to_C\n" if $opt_v > 2;
+    return @{$ra_lines};
+} # 1}}}
+sub smarty_to_C {                            # {{{1
+    my ($ra_lines, ) = @_;
+    # Converts Smarty comments to C comments.
+
+    print "-> smarty_to_C()\n" if $opt_v > 2;
+
+    foreach (@{$ra_lines}) {
+        s[{\*][/*]g;
+        s[\*}][*/]g;
+    }
+
+    print "<- smarty_to_C\n" if $opt_v > 2;
+    return @{$ra_lines};
+} # 1}}}
+sub determine_lit_type {                     # {{{1
+  my ($file) = @_;
+
+  open (FILE, $file);
+  while (<FILE>) {
+    if (m/^\\begin{code}/) { close FILE; return 2; }
+    if (m/^>\s/) { close FILE; return 1; }
+  }
+
+  return 0;
+} # 1}}}
+sub remove_haskell_comments {                # {{{1
+    # Bulk of code taken from SLOCCount's haskell_count script.
+    # Strips out {- .. -} and -- comments and counts the rest.
+    # Pragmas, {-#...}, are counted as SLOC.
+    # BUG: Doesn't handle strings with embedded block comment markers gracefully.
+    #      In practice, that shouldn't be a problem.
+    my ($ra_lines, $file, ) = @_;
+
+    print "-> remove_haskell_comments\n" if $opt_v > 2;
+
+    my @save_lines = ();
+    my $in_comment = 0;
+    my $incomment  = 0;
+    my ($literate, $inlitblock) = (0,0);
+  
+    $literate = 1 if $file =~ /\.lhs$/;
+    if($literate) { $literate = determine_lit_type($file) }
+
+    foreach (@{$ra_lines}) {
+        if ($literate == 1) {
+            if (!s/^>//) { s/.*//; }
+        } elsif ($literate == 2) {
+            if ($inlitblock) {
+                if (m/^\\end{code}/) { s/.*//; $inlitblock = 0; }
+            } elsif (!$inlitblock) {
+                if (m/^\\begin{code}/) { s/.*//; $inlitblock = 1; }
+                else { s/.*//; }
+            }
+        }
+
+        if ($incomment) {
+            if (m/\-\}/) { s/^.*?\-\}//;  $incomment = 0;}
+            else { s/.*//; }
+        }
+        if (!$incomment) {
+            s/--.*//;
+            s!{-[^#].*?-}!!g;
+            if (m/{-/ && (!m/{-#/)) {
+              s/{-.*//;
+              $incomment = 1;
+            }
+        }
+        if (m/\S/) { push @save_lines, $_; }
+    }
+#   if ($incomment) {print "ERROR: ended in comment in $ARGV\n";}
+
+    print "<- remove_haskell_comments\n" if $opt_v > 2;
+    return @save_lines;
+} # 1}}}
+sub print_lines {                            # {{{1
+    my ($file     , # in
+        $title    , # in
+        $ra_lines , # in
+       ) = @_;
+    printf "->%-30s %s\n", $file, $title;
+    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {
+        printf "%5d | %s", $i+1, $ra_lines->[$i];
+        print "\n" unless $ra_lines->[$i] =~ m{\n$}
+    }
+} # 1}}}
+sub set_constants {                          # {{{1
+    my ($rh_Language_by_Extension , # out
+        $rh_Language_by_Script    , # out
+        $rh_Language_by_File      , # out
+        $rhaa_Filters_by_Language , # out
+        $rh_Not_Code_Extension    , # out
+        $rh_Not_Code_Filename     , # out
+        $rh_Scale_Factor          , # out
+        $rh_Known_Binary_Archives , # out
+        $rh_EOL_continuation_re   , # out
+       ) = @_;
+# 1}}}
+%{$rh_Language_by_Extension} = (             # {{{1
+            'abap'        => 'ABAP'                  ,
+            'ac'          => 'm4'                    ,
+            'ada'         => 'Ada'                   ,
+            'adb'         => 'Ada'                   ,
+            'ads'         => 'Ada'                   ,
+            'adso'        => 'ADSO/IDSM'             ,
+            'ahk'         => 'AutoHotkey'            ,
+            'am'          => 'make'                  ,
+            'ample'       => 'AMPLE'                 ,
+            'as'          => 'ActionScript'          ,
+            'dofile'      => 'AMPLE'                 ,
+            'startup'     => 'AMPLE'                 ,
+            'asa'         => 'ASP'                   ,
+            'asax'        => 'ASP.Net'               ,
+            'ascx'        => 'ASP.Net'               ,
+            'asm'         => 'Assembly'              ,
+            'asmx'        => 'ASP.Net'               ,
+            'asp'         => 'ASP'                   ,
+            'aspx'        => 'ASP.Net'               ,
+            'master'      => 'ASP.Net'               ,
+            'sitemap'     => 'ASP.Net'               ,
+            'cshtml'      => 'Razor'                 ,
+            'awk'         => 'awk'                   ,
+            'bash'        => 'Bourne Again Shell'    ,
+            'bas'         => 'Visual Basic'          ,
+            'bat'         => 'DOS Batch'             ,
+            'BAT'         => 'DOS Batch'             ,
+            'build.xml'   => 'Ant'                   ,
+            'cbl'         => 'COBOL'                 ,
+            'CBL'         => 'COBOL'                 ,
+            'c'           => 'C'                     ,
+            'C'           => 'C++'                   ,
+            'cc'          => 'C++'                   ,
+            'ccs'         => 'CCS'                   ,
+            'cfc'         => 'ColdFusion CFScript'   ,
+            'cfm'         => 'ColdFusion'            ,
+            'cl'          => 'Lisp/OpenCL'           ,
+            'clj'         => 'Clojure'               ,
+            'cljs'        => 'ClojureScript'         ,
+            'cls'         => 'Visual Basic'          , # also Apex Class
+            'CMakeLists.txt' => 'CMake'              ,
+            'cmake'       => 'CMake'                 ,
+            'cob'         => 'COBOL'                 ,
+            'COB'         => 'COBOL'                 ,
+            'coffee'      => 'CoffeeScript'          ,
+            'component'   => 'Visualforce Component' ,
+            'config'      => 'ASP.Net'               ,
+            'cpp'         => 'C++'                   ,
+            'cs'          => 'C#'                    ,
+            'csh'         => 'C Shell'               ,
+            'css'         => "CSS"                   ,
+            'ctl'         => 'Visual Basic'          ,
+            'cxx'         => 'C++'                   ,
+            'd'           => 'D'                     ,
+            'da'          => 'DAL'                   ,
+            'dart'        => 'Dart'                  ,
+            'def'         => 'Teamcenter def'        ,
+            'dmap'        => 'NASTRAN DMAP'          ,
+            'dpr'         => 'Pascal'                ,
+            'dsr'         => 'Visual Basic'          ,
+            'dtd'         => 'DTD'                   ,
+            'ec'          => 'C'                     ,
+            'el'          => 'Lisp'                  ,
+            'erl'         => 'Erlang'                ,
+            'exp'         => 'Expect'                ,
+            'f77'         => 'Fortran 77'            ,
+            'F77'         => 'Fortran 77'            ,
+            'f90'         => 'Fortran 90'            ,
+            'F90'         => 'Fortran 90'            ,
+            'f95'         => 'Fortran 95'            ,
+            'F95'         => 'Fortran 95'            ,
+            'f'           => 'Fortran 77'            ,
+            'F'           => 'Fortran 77'            ,
+            'fmt'         => 'Oracle Forms'          ,
+            'focexec'     => 'Focus'                 ,
+            'frm'         => 'Visual Basic'          ,
+            'gnumakefile' => 'make'                  ,
+            'Gnumakefile' => 'make'                  ,
+            'go'          => 'Go'                    ,
+            'groovy'      => 'Groovy'                ,
+            'gant'        => 'Groovy'                ,
+            'h'           => 'C/C++ Header'          ,
+            'H'           => 'C/C++ Header'          ,
+            'hh'          => 'C/C++ Header'          ,
+            'hpp'         => 'C/C++ Header'          ,
+            'hrl'         => 'Erlang'                ,
+            'hs'          => 'Haskell'               , 
+            'htm'         => 'HTML'                  ,
+            'html'        => 'HTML'                  ,
+            'i3'          => 'Modula3'               ,
+            'idl'         => 'IDL'                   ,
+            'ism'         => 'InstallShield'         ,
+            'pro'         => 'IDL'                   ,
+            'ig'          => 'Modula3'               ,
+            'il'          => 'SKILL'                 ,
+            'ils'         => 'SKILL++'               ,
+            'inc'         => 'PHP/Pascal'            , # might be PHP or Pascal
+            'ino'         => 'Arduino Sketch'        ,
+            'pde'         => 'Arduino Sketch'        , # pre 1.0
+            'itk'         => 'Tcl/Tk'                ,
+            'java'        => 'Java'                  ,
+            'jcl'         => 'JCL'                   , # IBM Job Control Lang.
+            'jl'          => 'Lisp'                  ,
+            'js'          => 'Javascript'            ,
+            'jsf'         => 'JavaServer Faces'      ,
+            'xhtml'       => 'JavaServer Faces'      ,
+            'jsp'         => 'JSP'                   , # Java server pages
+            'ksc'         => 'Kermit'                ,
+            'ksh'         => 'Korn Shell'            ,
+            'lhs'         => 'Haskell'               ,
+            'l'           => 'lex'                   ,
+            'less'        => 'LESS'                  ,
+            'lsp'         => 'Lisp'                  ,
+            'lisp'        => 'Lisp'                  ,
+            'lua'         => 'Lua'                   ,
+            'm3'          => 'Modula3'               ,
+            'm4'          => 'm4'                    ,
+            'makefile'    => 'make'                  ,
+            'Makefile'    => 'make'                  ,
+            'met'         => 'Teamcenter met'        ,
+            'mg'          => 'Modula3'               , 
+#           'mli'         => 'ML'                    , # ML not implemented
+#           'ml'          => 'ML'                    , 
+            'ml'          => 'OCaml'                 , 
+            'mli'         => 'OCaml'                 , 
+            'mly'         => 'OCaml'                 , 
+            'mll'         => 'OCaml'                 , 
+            'm'           => 'MATLAB/Objective C/MUMPS' ,
+            'mm'          => 'Objective C++'         ,
+            'wdproj'      => 'MSBuild scripts'       ,
+            'csproj'      => 'MSBuild scripts'       ,
+            'mps'         => 'MUMPS'                 ,
+            'mth'         => 'Teamcenter mth'        ,
+            'oscript'     => 'LiveLink OScript'      ,
+            'pad'         => 'Ada'                   , # Oracle Ada preprocessor
+            'page'        => 'Visualforce Page'      ,
+            'pas'         => 'Pascal'                ,
+            'pcc'         => 'C++'                   , # Oracle C++ preprocessor
+            'perl'        => 'Perl'                  ,
+            'pfo'         => 'Fortran 77'            ,
+            'pgc'         => 'C'                     , # Postgres embedded C/C++
+            'php3'        => 'PHP'                   ,
+            'php4'        => 'PHP'                   ,
+            'php5'        => 'PHP'                   ,
+            'php'         => 'PHP'                   ,
+            'pig'         => 'Pig Latin'             ,
+            'plh'         => 'Perl'                  ,
+            'pl'          => 'Perl'                  ,
+            'PL'          => 'Perl'                  ,
+            'plx'         => 'Perl'                  ,
+            'pm'          => 'Perl'                  ,
+            'pom.xml'     => 'Maven'                 ,
+            'pom'         => 'Maven'                 ,
+            'p'           => 'Pascal'                ,
+            'pp'          => 'Pascal'                ,
+            'psql'        => 'SQL'                   ,
+            'py'          => 'Python'                ,
+            'pyx'         => 'Cython'                ,
+            'qml'         => 'QML'                   ,
+            'rb'          => 'Ruby'                  ,
+         #  'resx'        => 'ASP.Net'               ,
+            'rex'         => 'Oracle Reports'        ,
+            'rexx'        => 'Rexx'                  ,
+            'rhtml'       => 'Ruby HTML'             ,
+            'rs'          => 'Rust'                  ,
+            's'           => 'Assembly'              ,
+            'S'           => 'Assembly'              ,
+            'scala'       => 'Scala'                 ,
+            'sbl'         => 'Softbridge Basic'      ,
+            'SBL'         => 'Softbridge Basic'      ,
+            'sc'          => 'Lisp'                  ,
+            'scm'         => 'Lisp'                  ,
+            'sed'         => 'sed'                   ,
+            'ses'         => 'Patran Command Language'   ,
+            'pcl'         => 'Patran Command Language'   ,
+            'ps1'         => 'PowerShell'            ,
+            'sass'        => 'SASS'                  ,
+            'scss'        => 'SASS'                  ,
+            'sh'          => 'Bourne Shell'          ,
+            'smarty'      => 'Smarty'                ,
+            'sql'         => 'SQL'                   ,
+            'SQL'         => 'SQL'                   ,
+            'sproc.sql'   => 'SQL Stored Procedure'  ,
+            'spoc.sql'    => 'SQL Stored Procedure'  ,
+            'spc.sql'     => 'SQL Stored Procedure'  ,
+            'udf.sql'     => 'SQL Stored Procedure'  ,
+            'data.sql'    => 'SQL Data'              ,
+            'v'           => 'Verilog-SystemVerilog' ,
+            'sv'          => 'Verilog-SystemVerilog' ,
+            'svh'         => 'Verilog-SystemVerilog' ,
+            'tcl'         => 'Tcl/Tk'                ,
+            'tcsh'        => 'C Shell'               ,
+            'tk'          => 'Tcl/Tk'                ,
+            'tpl'         => 'Smarty'                ,
+            'trigger'     => 'Apex Trigger'          ,
+            'vala'        => 'Vala'                  ,
+            'vapi'        => 'Vala Header'           ,
+            'vhd'         => 'VHDL'                  ,
+            'VHD'         => 'VHDL'                  ,
+            'vhdl'        => 'VHDL'                  ,
+            'VHDL'        => 'VHDL'                  ,
+            'vba'         => 'Visual Basic'          ,
+            'VBA'         => 'Visual Basic'          ,
+         #  'vbp'         => 'Visual Basic'          , # .vbp - autogenerated
+            'vb'          => 'Visual Basic'          ,
+            'VB'          => 'Visual Basic'          ,
+         #  'vbw'         => 'Visual Basic'          , # .vbw - autogenerated
+            'vbs'         => 'Visual Basic'          ,
+            'VBS'         => 'Visual Basic'          ,
+            'webinfo'     => 'ASP.Net'               ,
+            'xml'         => 'XML'                   ,
+            'XML'         => 'XML'                   ,
+            'mxml'        => 'MXML'                  ,
+            'build'       => 'NAnt scripts'          ,
+            'vim'         => 'vim script'            ,
+            'xaml'        => 'XAML'                  ,
+            'xsd'         => 'XSD'                   ,
+            'XSD'         => 'XSD'                   ,
+            'xslt'        => 'XSLT'                  ,
+            'XSLT'        => 'XSLT'                  ,
+            'xsl'         => 'XSLT'                  ,
+            'XSL'         => 'XSLT'                  ,
+            'y'           => 'yacc'                  ,
+            'yaml'        => 'YAML'                  ,
+            'yml'         => 'YAML'                  ,
+            );
+# 1}}}
+%{$rh_Language_by_Script}    = (             # {{{1
+            'awk'      => 'awk'                   ,
+            'bash'     => 'Bourne Again Shell'    ,
+            'bc'       => 'bc'                    ,# calculator
+            'csh'      => 'C Shell'               ,
+            'dmd'      => 'D'                     ,
+            'idl'      => 'IDL'                   ,
+            'kermit'   => 'Kermit'                ,
+            'ksh'      => 'Korn Shell'            ,
+            'lua'      => 'Lua'                   ,
+            'make'     => 'make'                  ,
+            'octave'   => 'Octave'                ,
+            'perl5'    => 'Perl'                  ,
+            'perl'     => 'Perl'                  ,
+            'ruby'     => 'Ruby'                  ,
+            'sed'      => 'sed'                   ,
+            'sh'       => 'Bourne Shell'          ,
+            'tcl'      => 'Tcl/Tk'                ,
+            'tclsh'    => 'Tcl/Tk'                ,
+            'tcsh'     => 'C Shell'               ,
+            'wish'     => 'Tcl/Tk'                ,
+            );
+# 1}}}
+%{$rh_Language_by_File}      = (             # {{{1
+            'Makefile'       => 'make'               ,
+            'makefile'       => 'make'               ,
+            'gnumakefile'    => 'make'               ,
+            'Gnumakefile'    => 'make'               ,
+            'CMakeLists.txt' => 'CMake'              ,
+            'build.xml'      => 'Ant/XML'            ,
+            'pom.xml'        => 'Maven/XML'          ,
+            );
+# 1}}}
+%{$rhaa_Filters_by_Language} = (             # {{{1
+    'ABAP'               => [   [ 'remove_matches'      , '^\*'    ], ],
+    'ActionScript'       => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+
+    'ASP'                => [   [ 'remove_matches'      , '^\s*\47'], ],  # \47 = '
+    'ASP.Net'            => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'Ada'                => [   [ 'remove_matches'      , '^\s*--' ], ],
+    'ADSO/IDSM'          => [   [ 'remove_matches'      , '^\s*\*[\+\!]' ], ],
+    'AMPLE'              => [   [ 'remove_matches'      , '^\s*//' ], ],
+    'Ant/XML'            => [
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                            ],
+    'Ant'                => [
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                            ],
+    'Apex Trigger'       => [
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ],
+                            ],
+    'Arduino Sketch'     => [   # same as C
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ],
+                            ], 
+    'Assembly'           => [  
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'remove_matches'      , '^\s*;'  ],
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'remove_inline'       , ';.*$'   ],
+                            ],
+    'AutoHotkey'         => [   
+                                [ 'remove_matches'      , '^\s*;'  ],
+                                [ 'remove_inline'       , ';.*$'   ],
+                            ],
+    'awk'                => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'bc'                 => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'C'                  => [   
+                                [ 'remove_matches'      , '^\s*//' ], # C99
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ], # C99
+                            ], 
+    'C++'                => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'C/C++ Header'       => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Clojure'            => [   [ 'remove_matches'      , '^\s*;'  ], ],
+    'ClojureScript'      => [   [ 'remove_matches'      , '^\s*;'  ], ],
+    'CMake'              => [   
+                                [ 'remove_matches'      , '^\s*#'  ],
+                                [ 'remove_inline'       , '#.*$'   ], 
+                            ],
+    'Cython'             => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'docstring_to_C'                 ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'C#'                 => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'CCS'                => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'CSS'                => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'COBOL'              => [   [ 'remove_cobol_comments',         ], ],
+    'CoffeeScript'       => [   
+                                [ 'remove_matches'      , '^\s*#'  ],
+                                [ 'remove_inline'       , '#.*$'   ], 
+                            ],
+    'ColdFusion'         => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'ColdFusion CFScript'=> [
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Crystal Reports'    => [   [ 'remove_matches'      , '^\s*//' ], ],
+    'D'                  => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_between_general', '/+', '+/' ],
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'DAL'                => [   [ 'remove_between'      , '[]',    ], ],
+    'Dart'               => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'NASTRAN DMAP'       => [   
+                                [ 'remove_matches'      , '^\s*\$' ], 
+                                [ 'remove_inline'       , '\$.*$'  ], 
+                            ],
+    'DOS Batch'          => [   [ 'remove_matches'      , '^\s*rem', ], ],
+    'DTD'                => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'Erlang'             => [   
+                                [ 'remove_matches'      , '^\s*%'  ], 
+                                [ 'remove_inline'       , '%.*$'   ],
+                            ],
+    'Expect'             => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Focus'              => [   [ 'remove_matches'      , '^\s*\-\*'  ], ],
+    'Fortran 77'         => [   
+                                [ 'remove_f77_comments' ,          ], 
+                                [ 'remove_inline'       , '\!.*$'  ],
+                            ],
+    'Fortran 90'         => [   
+                                [ 'remove_f77_comments' ,          ],
+                                [ 'remove_f90_comments' ,          ], 
+                                [ 'remove_inline'       , '\!.*$'  ],
+                            ],
+    'Fortran 95'         => [   
+                                [ 'remove_f77_comments' ,          ],
+                                [ 'remove_f90_comments' ,          ], 
+                                [ 'remove_inline'       , '\!.*$'  ],
+                            ],
+    'Go'                 => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'Groovy'             => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'HTML'               => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'Haskell'            => [   [ 'remove_haskell_comments', '>filename<' ], ],
+    'IDL'                => [   [ 'remove_matches'      , '^\s*;'  ], ],
+    'InstallShield'      => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'JSP'                => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ],
+                                [ 'remove_jsp_comments' ,          ], 
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'add_newlines'        ,          ],
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'JavaServer Faces'   => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Java'               => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Javascript'         => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'JCL'                => [   [ 'remove_jcl_comments' ,          ], ],
+    'LESS'               => [
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Lisp'               => [   [ 'remove_matches'      , '^\s*;'  ], ],
+    'Lisp/OpenCL'        => [ [ 'die' ,          ], ], # never called
+    'LiveLink OScript'   => [   [ 'remove_matches'      , '^\s*//' ], ],
+#   'Lua'                => [   [ 'call_regexp_common'  , 'lua'    ], ],
+    'Lua'                => [   [ 'remove_matches'      , '^\s*\-\-' ], ],
+    'make'               => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'MATLAB'             => [   
+                                [ 'remove_matches'      , '^\s*%'  ], 
+                                [ 'remove_inline'       , '%.*$'   ],
+                            ], 
+    'Maven/XML'          => [
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                            ],
+    'Maven'              => [
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                            ],
+    'Modula3'            => [   [ 'call_regexp_common'  , 'Pascal' ], ],
+        # Modula 3 comments are (* ... *) so applying the Pascal filter
+        # which also treats { ... } as a comment is not really correct.
+    'Objective C'        => [   
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ], 
+    'Objective C++'      => [   
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ], 
+    'OCaml'              => [   
+                                [ 'call_regexp_common'  , 'Pascal' ], 
+                            ],
+    'OpenCL'             => [   
+                                [ 'remove_matches'      , '^\s*//' ], # C99
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ], # C99
+                            ],
+    'PHP/Pascal'               => [ [ 'die' ,          ], ], # never called
+    'MATLAB/Objective C/MUMPS' => [ [ 'die' ,          ], ], # never called
+    'MUMPS'              => [   [ 'remove_matches'      , '^\s*;'  ], ], 
+    'Octave'             => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Oracle Forms'       => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'Oracle Reports'     => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'Pascal'             => [   
+                                [ 'call_regexp_common'  , 'Pascal' ], 
+                                [ 'remove_matches'      , '^\s*//' ],
+                            ],
+    'Patran Command Language'=> [   
+                                [ 'remove_matches'      , '^\s*#'   ], 
+                                [ 'remove_matches'      , '^\s*\$#' ], 
+                                [ 'call_regexp_common'  , 'C'       ],
+                            ],
+    'Perl'               => [   [ 'remove_below'        , '^__(END|DATA)__'],
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_below_above'  , '^=head1', '^=cut'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Pig Latin'          => [   
+                                [ 'remove_matches'      , '^\s*--' ],
+                                [ 'remove_inline'       , '--.*$'  ],
+                                [ 'call_regexp_common'  , 'C'       ],
+                            ],
+    'PowerShell'         => [ 
+                                [ 'powershell_to_C'                ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Python'             => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'docstring_to_C'                 ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'PHP'                => [   
+                                [ 'remove_matches'      , '^\s*#'  ],
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                                [ 'remove_inline'       , '//.*$'  ],
+                            ],
+    'QML'                => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Razor'              => [
+                                [ 'remove_matches'      , '^\s*//' ],
+                                [ 'remove_between_general', '@*', '*@' ],
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '//.*$'  ],
+                            ], 
+    'Rexx'               => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'Ruby'               => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_below_above'  , '^=begin', '^=end' ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Ruby HTML'          => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'Rust'               => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'SASS'               => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Scala'              => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'SKILL'              => [   
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_matches'      , '^\s*;'  ],
+                            ],
+    'SKILL++'            => [   
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_matches'      , '^\s*;'  ],
+                            ],
+    'SQL'                => [   
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_matches'      , '^\s*--' ],
+                                [ 'remove_inline'       , '--.*$'  ],
+                            ],
+    'SQL Stored Procedure'=> [   
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_matches'      , '^\s*--' ],
+                                [ 'remove_inline'       , '--.*$'  ],
+                            ],
+    'SQL Data'           => [   
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_matches'      , '^\s*--' ],
+                                [ 'remove_inline'       , '--.*$'  ],
+                            ],
+    'sed'                => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Smarty'             => [   
+                                [ 'smarty_to_C'                    ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ], 
+    'Bourne Again Shell' => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Bourne Shell'       => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'm4'                 => [   [ 'remove_matches'      , '^dnl '  ], ], 
+    'C Shell'            => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Kermit'             => [  
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_matches'      , '^\s*;'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Korn Shell'         => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Tcl/Tk'             => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ],
+                            ], 
+    'Teamcenter def'     => [   [ 'remove_matches'      , '^\s*#'  ], ], 
+    'Teamcenter met'     => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'Teamcenter mth'     => [   [ 'remove_matches'      , '^\s*#'  ], ], 
+    'Softbridge Basic'   => [   [ 'remove_above'        , '^\s*Attribute\s+VB_Name\s+=' ],               
+                                [ 'remove_matches'      , '^\s*Attribute\s+'],
+                                [ 'remove_matches'      , '^\s*\47'], ],  # \47 = '
+    # http://www.altium.com/files/learningguides/TR0114%20VHDL%20Language%20Reference.pdf
+    'Vala'               => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Vala Header'        => [   
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'Verilog-SystemVerilog' => [
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                                [ 'call_regexp_common'  , 'C'      ],
+                            ],
+    'VHDL'               => [   
+                                [ 'remove_matches'      , '^\s*--' ],
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_inline'       , '--.*$'  ],
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'vim script'         => [   
+                                [ 'remove_matches'      , '^\s*"'  ], 
+                                [ 'remove_inline'       , '".*$'   ], 
+                            ],
+    'Visual Basic'       => [   [ 'remove_above'        , '^\s*Attribute\s+VB_Name\s+=' ],               
+                                [ 'remove_matches'      , '^\s*Attribute\s+'],
+                                [ 'remove_matches'      , '^\s*\47'], ],  # \47 = '
+    'Visualforce Component' => [
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                            ],
+    'Visualforce Page'   => [
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                            ],
+    'yacc'               => [   
+                                [ 'call_regexp_common'  , 'C'      ], 
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'remove_inline'       , '//.*$'  ], 
+                            ],
+    'YAML'               => [   
+                                [ 'remove_matches'      , '^\s*#'  ], 
+                                [ 'remove_inline'       , '#.*$'   ], 
+                            ],
+    'lex'                => [   [ 'call_regexp_common'  , 'C'      ], ],
+    'XAML'               => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'MXML'               => [   
+                                [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], 
+                                [ 'remove_matches'      , '^\s*//' ], 
+                                [ 'add_newlines'        ,          ], 
+                                [ 'call_regexp_common'  , 'C'      ], 
+                            ],
+    'XML'                => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'XSD'                => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'XSLT'               => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'NAnt scripts'       => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    'MSBuild scripts'    => [   [ 'remove_html_comments',          ],
+                                [ 'call_regexp_common'  , 'HTML'   ], ],
+    );
+# 1}}}
+%{$rh_EOL_continuation_re} = (               # {{{1
+    'ActionScript'       =>     '\\\\$'         ,
+    'Assembly'           =>     '\\\\$'         ,
+    'ASP'                =>     '\\\\$'         ,
+    'ASP.Net'            =>     '\\\\$'         ,
+    'Ada'                =>     '\\\\$'         ,
+    'awk'                =>     '\\\\$'         ,
+    'bc'                 =>     '\\\\$'         ,
+    'C'                  =>     '\\\\$'         ,
+    'C++'                =>     '\\\\$'         ,
+    'C/C++ Header'       =>     '\\\\$'         ,
+    'CMake'              =>     '\\\\$'         ,
+    'Cython'             =>     '\\\\$'         ,
+    'C#'                 =>     '\\\\$'         ,
+    'D'                  =>     '\\\\$'         ,
+    'Dart'               =>     '\\\\$'         ,
+    'Expect'             =>     '\\\\$'         ,
+    'Go'                 =>     '\\\\$'         ,
+    'Java'               =>     '\\\\$'         ,
+    'Javascript'         =>     '\\\\$'         ,
+    'LESS'               =>     '\\\\$'         ,
+    'Lua'                =>     '\\\\$'         ,
+    'make'               =>     '\\\\$'         ,
+    'MATLAB'             =>     '\.\.\.\s*$'    ,
+    'MXML'               =>     '\\\\$'         ,
+    'Objective C'        =>     '\\\\$'         ,
+    'Objective C++'      =>     '\\\\$'         ,
+    'OCaml'              =>     '\\\\$'         ,
+    'Octave'             =>     '\.\.\.\s*$'    ,
+    'Patran Command Language'=> '\\\\$'         ,
+    'PowerShell'         =>     '\\\\$'         ,
+    'Python'             =>     '\\\\$'         ,
+    'Ruby'               =>     '\\\\$'         ,
+    'sed'                =>     '\\\\$'         ,
+    'Bourne Again Shell' =>     '\\\\$'         ,
+    'Bourne Shell'       =>     '\\\\$'         ,
+    'C Shell'            =>     '\\\\$'         ,
+    'Kermit'             =>     '\\\\$'         ,
+    'Korn Shell'         =>     '\\\\$'         ,
+    'Tcl/Tk'             =>     '\\\\$'         ,
+    'lex'                =>     '\\\\$'         ,
+    'Vala'               =>     '\\\\$'         ,
+    'Vala Header'        =>     '\\\\$'         ,
+    );
+# 1}}}
+%{$rh_Not_Code_Extension}    = (             # {{{1
+   '1'       => 1,  # Man pages (documentation):
+   '2'       => 1,
+   '3'       => 1,
+   '4'       => 1,
+   '5'       => 1,
+   '6'       => 1,
+   '7'       => 1,
+   '8'       => 1,
+   '9'       => 1,
+   'a'       => 1,  # Static object code.
+   'ad'      => 1,  # X application default resource file.
+   'afm'     => 1,  # font metrics
+   'arc'     => 1,  # arc(1) archive
+   'arj'     => 1,  # arj(1) archive
+   'au'      => 1,  # Audio sound filearj(1) archive
+   'bak'     => 1,  # Backup files - we only want to count the "real" files.
+   'bdf'     => 1,
+   'bmp'     => 1,
+   'bz2'     => 1,  # bzip2(1) compressed file
+   'csv'     => 1,  # comma separated values
+   'desktop' => 1,
+   'dic'     => 1,
+   'doc'     => 1,
+   'elc'     => 1,
+   'eps'     => 1,
+   'fig'     => 1,
+   'gif'     => 1,
+   'gz'      => 1,
+   'hdf'     => 1,  # hierarchical data format
+   'in'      => 1,  # Debatable.
+   'jpg'     => 1,
+   'kdelnk'  => 1,
+   'man'     => 1,
+   'mf'      => 1,
+   'mp3'     => 1,
+   'n'       => 1,
+   'o'       => 1,  # Object code is generated from source code.
+   'pbm'     => 1,
+   'pdf'     => 1,
+   'pfb'     => 1,
+   'png'     => 1,
+   'po'      => 1,
+   'ps'      => 1,  # Postscript is _USUALLY_ generated automatically.
+   'sgm'     => 1,
+   'sgml'    => 1,
+   'so'      => 1,  # Dynamically-loaded object code.
+   'Tag'     => 1,
+   'tex'     => 1,
+   'text'    => 1,
+   'tfm'     => 1,
+   'tgz'     => 1,  # gzipped tarball
+   'tiff'    => 1,
+   'txt'     => 1, 
+   'vf'      => 1,
+   'wav'     => 1,
+   'xbm'     => 1,
+   'xpm'     => 1,
+   'Y'       => 1,  # file compressed with "Yabba"
+   'Z'       => 1,  # file compressed with "compress"
+   'zip'     => 1,  # zip archive
+); # 1}}}
+%{$rh_Not_Code_Filename}     = (             # {{{1
+   'AUTHORS'     => 1,
+   'BUGS'        => 1,
+   'BUGS'        => 1,
+   'Changelog'   => 1,
+   'ChangeLog'   => 1,
+   'ChangeLog'   => 1,
+   'Changes'     => 1,
+   'CHANGES'     => 1,
+   'COPYING'     => 1,
+   'COPYING'     => 1,
+   '.cvsignore'  => 1,
+   'Entries'     => 1,
+   'FAQ'         => 1,
+   'iconfig.h'   => 1, # Skip "iconfig.h" files; they're used in Imakefiles.
+   'INSTALL'     => 1,
+   'MAINTAINERS' => 1,
+   'MD5SUMS'     => 1,
+   'NEWS'        => 1,
+   'readme'      => 1,
+   'Readme'      => 1,
+   'README'      => 1,
+   'README.tk'   => 1, # used in kdemultimedia, it's confusing.
+   'Repository'  => 1,
+   'Root'        => 1, # CVS
+   'TODO'        => 1,
+);
+# 1}}}
+%{$rh_Scale_Factor}          = (             # {{{1
+    '1032/af'                      =>   5.00,
+    '1st generation default'       =>   0.25,
+    '2nd generation default'       =>   0.75,
+    '3rd generation default'       =>   1.00,
+    '4th generation default'       =>   4.00,
+    '5th generation default'       =>  16.00,
+    'aas macro'                    =>   0.88,
+    'abap/4'                       =>   5.00,
+    'ABAP'                         =>   5.00,
+    'accel'                        =>   4.21,
+    'access'                       =>   2.11,
+    'ActionScript'                 =>   1.36,
+    'actor'                        =>   3.81,
+    'acumen'                       =>   2.86,
+    'Ada'                          =>   0.52,
+    'Ada 83'                       =>   1.13,
+    'Ada 95'                       =>   1.63,
+    'adr/dl'                       =>   2.00,
+    'adr/ideal/pdl'                =>   4.00,
+    'ads/batch'                    =>   4.00,
+    'ads/online'                   =>   4.00,
+    'ADSO/IDSM'                    =>   3.00,
+    'advantage'                    =>   2.11,
+    'ai shell default'             =>   1.63,
+    'ai shells'                    =>   1.63,
+    'algol 68'                     =>   0.75,
+    'algol w'                      =>   0.75,
+    'ambush'                       =>   2.50,
+    'aml'                          =>   1.63,
+    'AMPLE'                        =>   2.00,
+    'Ant/XML'                      =>   1.90,
+    'Ant'                          =>   1.90,
+    'amppl ii'                     =>   1.25,
+    'ansi basic'                   =>   1.25,
+    'ansi cobol 74'                =>   0.75,
+    'ansi cobol 85'                =>   0.88,
+    'SQL'                          =>   6.15,
+    'SQL Stored Procedure'         =>   6.15,
+    'SQL Data'                     =>   1.00,
+    'answer/db'                    =>   6.15,
+    'apl 360/370'                  =>   2.50,
+    'apl default'                  =>   2.50,
+    'apl*plus'                     =>   2.50,
+    'applesoft basic'              =>   0.63,
+    'application builder'          =>   4.00,
+    'application manager'          =>   2.22,
+    'aps'                          =>   0.96,
+    'aps'                          =>   4.71,
+    'apt'                          =>   1.13,
+    'aptools'                      =>   4.00,
+    'arc'                          =>   1.63,
+    'ariel'                        =>   0.75,
+    'arity'                        =>   1.63,
+    'arity prolog'                 =>   1.25,
+    'art'                          =>   1.63,
+    'art enterprise'               =>   1.74,
+    'artemis'                      =>   2.00,
+    'artim'                        =>   1.74,
+    'as/set'                       =>   4.21,
+    'asi/inquiry'                  =>   6.15,
+    'ask windows'                  =>   1.74,
+'asa'                         =>   1.29,
+'ASP'                         =>   1.29,
+'ASP.Net'                     =>   1.29,
+'aspx'                        =>   1.29,
+#'resx'                        =>   1.29,
+'asax'                        =>   1.29,
+'ascx'                        =>   1.29,
+'asmx'                        =>   1.29,
+'config'                      =>   1.29,
+'webinfo'                     =>   1.29,
+'CCS'                         =>   5.33,
+
+    'Apex Trigger'                 =>   1.4 ,
+#   'assembler (basic)'            =>   0.25,
+    'Arduino Sketch'               =>   1.00,
+    'Assembly'                     =>   0.25,
+
+    'Assembly (macro)'             =>   0.51,
+    'associative default'          =>   1.25,
+    'autocoder'                    =>   0.25,
+    'AutoHotkey'                   =>   1.29,
+    'awk'                          =>   3.81,
+    'aztec c'                      =>   0.63,
+    'balm'                         =>   0.75,
+    'base sas'                     =>   1.51,
+    'basic'                        =>   0.75,
+    'basic a'                      =>   0.63,
+#   'basic assembly'               =>   0.25,
+    'bc'                           =>   1.50,
+    'berkeley pascal'              =>   0.88,
+    'better basic'                 =>   0.88,
+    'bliss'                        =>   0.75,
+    'bmsgen'                       =>   2.22,
+    'boeingcalc'                   =>  13.33,
+    'bteq'                         =>   6.15,
+
+    'C'                            =>   0.77,
+
+    'c set 2'                      =>   0.88,
+
+    'C#'                           =>   1.36,
+
+    'C++'                          =>   1.51,
+
+    'c86plus'                      =>   0.63,
+    'cadbfast'                     =>   2.00,
+    'caearl'                       =>   2.86,
+    'cast'                         =>   1.63,
+    'cbasic'                       =>   0.88,
+    'cdadl'                        =>   4.00,
+    'cellsim'                      =>   1.74,
+    'ColdFusion'                   =>   4.00,
+    'ColdFusion CFScript'          =>   4.00,
+    'chili'                        =>   0.75,
+    'chill'                        =>   0.75,
+    'cics'                         =>   1.74,
+    'clarion'                      =>   1.38,
+    'clascal'                      =>   1.00,
+    'cli'                          =>   2.50,
+    'clipper'                      =>   2.05,
+    'clipper db'                   =>   2.00,
+    'clos'                         =>   3.81,
+    'Clojure'                      =>   1.25,
+    'ClojureScript'                =>   1.25,
+    'clout'                        =>   2.00,
+    'CMake'                        =>   1.00,
+    'cms2'                         =>   0.75,
+    'cmsgen'                       =>   4.21,
+    'COBOL'                        =>   1.04,
+    'COBOL ii'                     =>   0.75,
+    'COBOL/400'                    =>   0.88,
+    'cobra'                        =>   4.00,
+    'codecenter'                   =>   2.22,
+    'cofac'                        =>   2.22,
+    'CoffeeScript'                 =>   2.00,
+    'cogen'                        =>   2.22,
+    'cognos'                       =>   2.22,
+    'cogo'                         =>   1.13,
+    'comal'                        =>   1.00,
+    'comit ii'                     =>   1.25,
+    'common lisp'                  =>   1.25,
+    'concurrent pascal'            =>   1.00,
+    'conniver'                     =>   1.25,
+    'cool:gen/ief'                 =>   2.58,
+    'coral 66'                     =>   0.75,
+    'corvet'                       =>   4.21,
+    'corvision'                    =>   5.33,
+    'cpl'                          =>   0.50,
+    'Crystal Reports'              =>   4.00,
+    'csl'                          =>   1.63,
+    'csp'                          =>   1.51,
+    'cssl'                         =>   1.74,
+    
+'CSS' => 1.0,
+    
+    'culprit'                      =>   1.57,
+    'cxpert'                       =>   1.63,
+    'cygnet'                       =>   4.21,
+    'D'                            =>   1.70,
+    'DAL'                          =>   1.50,
+    'Dart'                         =>   2.00,
+    'data base default'            =>   2.00,
+    'dataflex'                     =>   2.00,
+    'datatrieve'                   =>   4.00,
+    'dbase iii'                    =>   2.00,
+    'dbase iv'                     =>   1.54,
+    'dcl'                          =>   0.38,
+    'decision support default'     =>   2.22,
+    'decrally'                     =>   2.00,
+    'delphi'                       =>   2.76,
+    'dl/1'                         =>   2.00,
+    'NASTRAN DMAP'                 =>   2.35,
+    'dna4'                         =>   4.21,
+    'DOS Batch'                    =>   0.63,
+    'dsp assembly'                 =>   0.50,
+    'dtabl'                        =>   1.74,
+    'dtipt'                        =>   1.74,
+    'dyana'                        =>   1.13,
+    'dynamoiii'                    =>   1.74,
+    'easel'                        =>   2.76,
+    'easy'                         =>   1.63,
+    'easytrieve+'                  =>   2.35,
+    'eclipse'                      =>   1.63,
+    'eda/sql'                      =>   6.67,
+    'edscheme 3.4'                 =>   1.51,
+    'eiffel'                       =>   3.81,
+    'enform'                       =>   1.74,
+    'englishbased default'         =>   1.51,
+    'ensemble'                     =>   2.76,
+    'epos'                         =>   4.00,
+    'Erlang'                       =>   2.11,
+    'esf'                          =>   2.00,
+    'espadvisor'                   =>   1.63,
+    'espl/i'                       =>   1.13,
+    'euclid'                       =>   0.75,
+    'excel'                        =>   1.74,
+    'excel 12'                     =>  13.33,
+    'excel 34'                     =>  13.33,
+    'excel 5'                      =>  13.33,
+    'express'                      =>   2.22,
+    'exsys'                        =>   1.63,
+    'extended common lisp'         =>   1.43,
+    'eznomad'                      =>   2.22,
+    'facets'                       =>   4.00,
+    'factorylink iv'               =>   2.76,
+    'fame'                         =>   2.22,
+    'filemaker pro'                =>   2.22,
+    'flavors'                      =>   2.76,
+    'flex'                         =>   1.74,
+    'flexgen'                      =>   2.76,
+    'Focus'                        =>   1.90,
+    'foil'                         =>   1.51,
+    'forte'                        =>   4.44,
+    'forth'                        =>   1.25,
+    'Fortran 66'                   =>   0.63,
+    'Fortran 77'                   =>   0.75,
+    'Fortran 90'                   =>   1.00,
+    'Fortran 95'                   =>   1.13,
+    'Fortran II'                   =>   0.63,
+    'foundation'                   =>   2.76,
+    'foxpro'                       =>   2.29,
+    'foxpro 1'                     =>   2.00,
+    'foxpro 2.5'                   =>   2.35,
+    'framework'                    =>  13.33,
+    'g2'                           =>   1.63,
+    'gamma'                        =>   5.00,
+    'genascript'                   =>   2.96,
+    'gener/ol'                     =>   6.15,
+    'genexus'                      =>   5.33,
+    'genifer'                      =>   4.21,
+    'geode 2.0'                    =>   5.00,
+    'gfa basic'                    =>   2.35,
+    'gml'                          =>   1.74,
+    'golden common lisp'           =>   1.25,
+    'gpss'                         =>   1.74,
+    'guest'                        =>   2.86,
+    'guru'                         =>   1.63,
+    'Go'                           =>   2.50,
+    'Groovy'                       =>   4.10,
+    'gw basic'                     =>   0.82,
+    'Haskell'                      =>   2.11,
+    'high c'                       =>   0.63,
+    'hlevel'                       =>   1.38,
+    'hp basic'                     =>   0.63,
+
+'HTML'          => 1.90 ,
+'XML'           => 1.90 ,
+'MXML'          => 1.90 ,
+'XSLT'          => 1.90 ,
+'DTD'           => 1.90 ,
+'XSD'           => 1.90 ,
+'NAnt scripts'    => 1.90 ,
+'MSBuild scripts' => 1.90 , 
+
+    'HTML 2'                       =>   5.00,
+    'HTML 3'                       =>   5.33,
+    'huron'                        =>   5.00,
+    'ibm adf i'                    =>   4.00,
+    'ibm adf ii'                   =>   4.44,
+    'ibm advanced basic'           =>   0.82,
+    'ibm cics/vs'                  =>   2.00,
+    'ibm compiled basic'           =>   0.88,
+    'ibm vs cobol'                 =>   0.75,
+    'ibm vs cobol ii'              =>   0.88,
+    'ices'                         =>   1.13,
+    'icon'                         =>   1.00,
+    'ideal'                        =>   1.54,
+    'idms'                         =>   2.00,
+    'ief'                          =>   5.71,
+    'ief/cool:gen'                 =>   2.58,
+    'iew'                          =>   5.71,
+    'ifps/plus'                    =>   2.50,
+    'imprs'                        =>   2.00,
+    'informix'                     =>   2.58,
+    'ingres'                       =>   2.00,
+    'inquire'                      =>   6.15,
+    'insight2'                     =>   1.63,
+    'install/1'                    =>   5.00,
+    'InstallShield'                =>   1.90,
+    'intellect'                    =>   1.51,
+    'interlisp'                    =>   1.38,
+    'interpreted basic'            =>   0.75,
+    'interpreted c'                =>   0.63,
+    'iqlisp'                       =>   1.38,
+    'iqrp'                         =>   6.15,
+    'j2ee'                         =>   1.60,
+    'janus'                        =>   1.13,
+    'Java'                         =>   1.36,
+    'Javascript'                   =>   1.48,
+    'JavaServer Faces'             =>   1.5 ,
+    'JSP'                          =>   1.48,
+    'JCL'                          =>   1.67,
+    'joss'                         =>   0.75,
+    'jovial'                       =>   0.75,
+    'jsp'                          =>   1.36,
+    'kappa'                        =>   2.00,
+    'kbms'                         =>   1.63,
+    'kcl'                          =>   1.25,
+    'kee'                          =>   1.63,
+    'keyplus'                      =>   2.00,
+    'kl'                           =>   1.25,
+    'klo'                          =>   1.25,
+    'knowol'                       =>   1.63,
+    'krl'                          =>   1.38,
+    'Kermit'                       =>   2.00,
+    'Korn Shell'                   =>   3.81,
+    'ladder logic'                 =>   2.22,
+    'lambit/l'                     =>   1.25,
+    'lattice c'                    =>   0.63,
+    'LESS'                         =>   1.50,
+    'liana'                        =>   0.63,
+    'lilith'                       =>   1.13,
+    'linc ii'                      =>   5.71,
+    'Lisp'                         =>   1.25,
+    'LiveLink OScript'             =>   3.5 ,
+    'loglisp'                      =>   1.38,
+    'loops'                        =>   3.81,
+    'lotus 123 dos'                =>  13.33,
+    'lotus macros'                 =>   0.75,
+    'lotus notes'                  =>   3.64,
+    'lucid 3d'                     =>  13.33,
+    'lyric'                        =>   1.51,
+    'm4'                           =>   1.00,
+    'm'                            =>   5.00,
+    'macforth'                     =>   1.25,
+    'mach1'                        =>   2.00,
+    'machine language'             =>   0.13,
+    'maestro'                      =>   5.00,
+    'magec'                        =>   5.00,
+    'magik'                        =>   3.81,
+    'Lake'                         =>   3.81,
+    'make'                         =>   2.50,
+    'mantis'                       =>   2.96,
+    'mapper'                       =>   0.99,
+    'mark iv'                      =>   2.00,
+    'mark v'                       =>   2.22,
+    'mathcad'                      =>  16.00,
+    'Maven'                        =>   1.90,
+    'mdl'                          =>   2.22,
+    'mentor'                       =>   1.51,
+    'mesa'                         =>   0.75,
+    'microfocus cobol'             =>   1.00,
+    'microforth'                   =>   1.25,
+    'microsoft c'                  =>   0.63,
+    'microstep'                    =>   4.00,
+    'miranda'                      =>   2.00,
+    'model 204'                    =>   2.11,
+    'modula 2'                     =>   1.00,
+    'mosaic'                       =>  13.33,
+    # 'ms c ++ v. 7'                 =>   1.51,
+    'ms compiled basic'            =>   0.88,
+    'msl'                          =>   1.25,
+    'mulisp'                       =>   1.25,
+    'MUMPS'                        =>   4.21,
+    'Nastran'                      =>   1.13,
+    'natural'                      =>   1.54,
+    'natural 1'                    =>   1.51,
+    'natural 2'                    =>   1.74,
+    'natural construct'            =>   3.20,
+    'natural language'             =>   0.03,
+    'netron/cap'                   =>   4.21,
+    'nexpert'                      =>   1.63,
+    'nial'                         =>   1.63,
+    'nomad2'                       =>   2.00,
+    'nonprocedural default'        =>   2.22,
+    'notes vip'                    =>   2.22,
+    'nroff'                        =>   1.51,
+    'object assembler'             =>   1.25,
+    'object lisp'                  =>   2.76,
+    'object logo'                  =>   2.76,
+    'object pascal'                =>   2.76,
+    'object star'                  =>   5.00,
+    'Objective C'                  =>   2.96,
+    'Objective C++'                =>   2.96,
+    'objectoriented default'       =>   2.76,
+    'objectview'                   =>   3.20,
+    'OCaml'                        =>   3.00,
+    'ogl'                          =>   1.00,
+    'omnis 7'                      =>   2.00,
+    'oodl'                         =>   2.76,
+    'ops'                          =>   1.74,
+    'ops5'                         =>   1.38,
+    'oracle'                       =>   2.76,
+    'Oracle Reports'               =>   2.76,
+    'Oracle Forms'                 =>   2.67,
+    'Oracle Developer/2000'        =>   3.48,
+    'oscar'                        =>   0.75,
+    'pacbase'                      =>   1.67,
+    'pace'                         =>   2.00,
+    'paradox/pal'                  =>   2.22,
+    'Pascal'                       =>   0.88,
+    'Patran Command Language'      =>   2.50,
+    'pc focus'                     =>   2.22,
+    'pdl millenium'                =>   3.81,
+    'pdp11 ade'                    =>   1.51,
+    'peoplesoft'                   =>   2.50,
+    'Perl'                         =>   4.00,
+    'persistance object builder'   =>   3.81,
+    'Pig Latin'                    =>   1.00,
+    'pilot'                        =>   1.51,
+    'pl/1'                         =>   1.38,
+    'pl/m'                         =>   1.13,
+    'pl/s'                         =>   0.88,
+    'pl/sql'                       =>   2.58,
+    'planit'                       =>   1.51,
+    'planner'                      =>   1.25,
+    'planperfect 1'                =>  11.43,
+    'plato'                        =>   1.51,
+    'polyforth'                    =>   1.25,
+    'pop'                          =>   1.38,
+    'poplog'                       =>   1.38,
+    'power basic'                  =>   1.63,
+    'powerbuilder'                 =>   3.33,
+    'powerhouse'                   =>   5.71,
+    'PowerShell'                   =>   3.00,
+    'ppl (plus)'                   =>   2.00,
+    'problemoriented default'      =>   1.13,
+    'proc'                         =>   2.96,
+    'procedural default'           =>   0.75,
+    'professional pascal'          =>   0.88,
+    'program generator default'    =>   5.00,
+    'progress v4'                  =>   2.22,
+    'proiv'                        =>   1.38,
+    'prolog'                       =>   1.25,
+    'prose'                        =>   0.75,
+    'proteus'                      =>   0.75,
+    'qbasic'                       =>   1.38,
+    'qbe'                          =>   6.15,
+    'qmf'                          =>   5.33,
+    'QML'                          =>   1.25,
+    'qnial'                        =>   1.63,
+    'quattro'                      =>  13.33,
+    'quattro pro'                  =>  13.33,
+    'query default'                =>   6.15,
+    'quick basic 1'                =>   1.25,
+    'quick basic 2'                =>   1.31,
+    'quick basic 3'                =>   1.38,
+    'quick c'                      =>   0.63,
+    'quickbuild'                   =>   2.86,
+    'quiz'                         =>   5.33,
+    'rally'                        =>   2.00,
+    'ramis ii'                     =>   2.00,
+    'rapidgen'                     =>   2.86,
+    'ratfor'                       =>   0.88,
+    'rdb'                          =>   2.00,
+    'realia'                       =>   1.74,
+    'realizer 1.0'                 =>   2.00,
+    'realizer 2.0'                 =>   2.22,
+    'relate/3000'                  =>   2.00,
+    'reuse default'                =>  16.00,
+    'Razor'                        =>   2.00,
+    'Rexx'                         =>   1.19,
+    'Rexx (mvs)'                   =>   1.00,
+    'Rexx (os/2)'                  =>   1.74,
+    'rm basic'                     =>   0.88,
+    'rm cobol'                     =>   0.75,
+    'rm fortran'                   =>   0.75,
+    'rpg i'                        =>   1.00,
+    'rpg ii'                       =>   1.63,
+    'rpg iii'                      =>   1.63,
+    'rtexpert 1.4'                 =>   1.38,
+    'Rust'                         =>   1.00,
+    'sabretalk'                    =>   0.90,
+    'sail'                         =>   0.75,
+    'sapiens'                      =>   5.00,
+    'sas'                          =>   1.95,
+    'savvy'                        =>   6.15,
+    'sbasic'                       =>   0.88,
+    'Scala'                        =>   4.10,
+    'sceptre'                      =>   1.13,
+    'scheme'                       =>   1.51,
+    'screen painter default'       =>  13.33,
+    'sequal'                       =>   6.67,
+    'Bourne Shell'                 =>   3.81,
+    'Bourne Again Shell'           =>   3.81,
+    'ksh'                          =>   3.81,
+    'C Shell'                      =>   3.81,
+    'siebel tools '                =>   6.15,
+    'SASS'                         =>   1.5 ,
+    'simplan'                      =>   2.22,
+    'simscript'                    =>   1.74,
+    'simula'                       =>   1.74,
+    'simula 67'                    =>   1.74,
+    'simulation default'           =>   1.74,
+    'SKILL'                        =>   2.00,
+    'SKILL++'                      =>   2.00,
+    'slogan'                       =>   0.98,
+    'smalltalk'                    =>   2.50,
+    'smalltalk 286'                =>   3.81,
+    'smalltalk 80'                 =>   3.81,
+    'smalltalk/v'                  =>   3.81,
+    'Smarty'                       =>   3.50,
+    'snap'                         =>   1.00,
+    'snobol24'                     =>   0.63,
+    'softscreen'                   =>   5.71,
+    'Softbridge Basic'             =>   2.76,
+    'solo'                         =>   1.38,
+    'speakeasy'                    =>   2.22,
+    'spinnaker ppl'                =>   2.22,
+    'splus'                        =>   2.50,
+    'spreadsheet default'          =>  13.33,
+    'sps'                          =>   0.25,
+    'spss'                         =>   2.50,
+    'SQL'                          =>   2.29,
+    'sqlwindows'                   =>   6.67,
+    'statistical default'          =>   2.50,
+    'strategem'                    =>   2.22,
+    'stress'                       =>   1.13,
+    'strongly typed default'       =>   0.88,
+    'style'                        =>   1.74,
+    'superbase 1.3'                =>   2.22,
+    'surpass'                      =>  13.33,
+    'sybase'                       =>   2.00,
+    'symantec c++'                 =>   2.76,
+    'symbolang'                    =>   1.25,
+    'synchroworks'                 =>   4.44,
+    'synon/2e'                     =>   4.21,
+    'systemw'                      =>   2.22,
+    'tandem access language'       =>   0.88,
+    'Tcl/Tk'                       =>   4.00,
+    'Teamcenter def'               =>   1.00,
+    'Teamcenter met'               =>   1.00,
+    'Teamcenter mth'               =>   1.00,
+    'telon'                        =>   5.00,
+    'tessaract'                    =>   2.00,
+    'the twin'                     =>  13.33,
+    'themis'                       =>   6.15,
+    'tiief'                        =>   5.71,
+    'topspeed c++'                 =>   2.76,
+    'transform'                    =>   5.33,
+    'translisp plus'               =>   1.43,
+    'treet'                        =>   1.25,
+    'treetran'                     =>   1.25,
+    'trs80 basic'                  =>   0.63,
+    'true basic'                   =>   1.25,
+    'turbo c'                      =>   0.63,
+    # 'turbo c++'                    =>   1.51,
+    'turbo expert'                 =>   1.63,
+    'turbo pascal >5'              =>   1.63,
+    'turbo pascal 14'              =>   1.00,
+    'turbo pascal 45'              =>   1.13,
+    'turbo prolog'                 =>   1.00,
+    'turing'                       =>   1.00,
+    'tutor'                        =>   1.51,
+    'twaice'                       =>   1.63,
+    'ucsd pascal'                  =>   0.88,
+    'ufo/ims'                      =>   2.22,
+    'uhelp'                        =>   2.50,
+    'uniface'                      =>   5.00,
+    # 'unix shell scripts'           =>   3.81,
+    'Vala'                         =>   1.50,
+    'Vala Header'                  =>   1.40,
+    'vax acms'                     =>   1.38,
+    'vax ade'                      =>   2.00,
+    'vbscript'                     =>   2.35,
+    'vectran'                      =>   0.75,
+    'Verilog-SystemVerilog'        =>   1.51,
+    'VHDL'                         =>   4.21,
+    'vim script'                   =>   3.00,
+    'visible c'                    =>   1.63,
+    'visible cobol'                =>   2.00,
+    'visicalc 1'                   =>   8.89,
+    'visual 4.0'                   =>   2.76,
+    'visual basic'                 =>   1.90,
+    'visual basic 1'               =>   1.74,
+    'visual basic 2'               =>   1.86,
+    'visual basic 3'               =>   2.00,
+    'visual basic 4'               =>   2.22,
+    'visual basic 5'               =>   2.76,
+    'Visual Basic'                 =>   2.76,
+    'visual basic dos'             =>   2.00,
+    'visual c++'                   =>   2.35,
+    'visual cobol'                 =>   4.00,
+    'visual objects'               =>   5.00,
+    'visualage'                    =>   3.81,
+    'Visualforce Component'        =>   1.9 ,
+    'Visualforce Page'             =>   1.9 ,
+    'visualgen'                    =>   4.44,
+    'vpf'                          =>   0.84,
+    'vsrexx'                       =>   2.50,
+    'vulcan'                       =>   1.25,
+    'vz programmer'                =>   2.22,
+    'warp x'                       =>   2.00,
+    'watcom c'                     =>   0.63,
+    'watcom c/386'                 =>   0.63,
+    'waterloo c'                   =>   0.63,
+    'waterloo pascal'              =>   0.88,
+    'watfiv'                       =>   0.94,
+    'watfor'                       =>   0.88,
+    'web scripts'                  =>   5.33,
+    'whip'                         =>   0.88,
+    'wizard'                       =>   2.86,
+    'xlisp'                        =>   1.25,
+    'XAML'                         =>   1.90,
+    'yacc'                         =>   1.51,
+    'yacc++'                       =>   1.51,
+    'YAML'                         =>   0.90,
+    'zbasic'                       =>   0.88,
+    'zim'                          =>   4.21,
+    'zlisp'                        =>   1.25,
+
+'Expect'  => 2.00,
+'C/C++ Header'  => 1.00, 
+'inc'     => 1.00,
+'lex'     => 1.00,
+'MATLAB'  => 4.00,
+'Maven/XML' => 2.5,
+'IDL'     => 3.80,
+'Octave'  => 4.00,
+'ML'      => 3.00,
+'Modula3' => 2.00,
+'PHP'     => 3.50,
+'Python'  => 4.20,
+'Cython'  => 3.80,
+'Ruby'    => 4.20,
+'Ruby HTML' => 4.00,
+'sed'     => 4.00,
+'Lua'     => 4.00,
+'OpenCL'  => 1.50,
+);
+# 1}}}
+%{$rh_Known_Binary_Archives} = (             # {{{1
+            '.tar'     => 1 ,
+            '.tar.Z'   => 1 ,
+            '.tar.gz'  => 1 ,
+            '.tar.bz2' => 1 ,
+            '.zip'     => 1 ,
+            '.Zip'     => 1 ,
+            '.ZIP'     => 1 ,
+            '.ear'     => 1 ,  # Java
+            '.war'     => 1 ,  # contained within .ear
+            '.xz'      => 1 ,
+            );
+# 1}}}
+} # end sub set_constants()
+sub Install_Regexp_Common {                  # {{{1
+    # Installs portions of Damian Conway's & Abigail's Regexp::Common
+    # module, v2.120, into a temporary directory for the duration of
+    # this run.
+
+    my %Regexp_Common_Contents = ();
+$Regexp_Common_Contents{'Common'} = <<'EOCommon'; # {{{2
+package Regexp::Common;
+
+use 5.00473;
+use strict;
+
+local $^W = 1;
+
+use vars qw /$VERSION %RE %sub_interface $AUTOLOAD/;
+
+($VERSION) = q $Revision: 2.120 $ =~ /([\d.]+)/;
+
+
+sub _croak {
+    require Carp;
+    goto &Carp::croak;
+}
+
+sub _carp {
+    require Carp;
+    goto &Carp::carp;
+}
+
+sub new {
+    my ($class, @data) = @_;
+    my %self;
+    tie %self, $class, @data;
+    return \%self;
+}
+
+sub TIEHASH {
+    my ($class, @data) = @_;
+    bless \@data, $class;
+}
+
+sub FETCH {
+    my ($self, $extra) = @_;
+    return bless ref($self)->new(@$self, $extra), ref($self);
+}
+
+# Modification for cloc:  only need a few modules from Regexp::Common.
+my %imports = map {$_ => "Regexp::Common::$_"}
+              qw /balanced comment delimited /;
+#my %imports = map {$_ => "Regexp::Common::$_"}
+#              qw /balanced CC     comment   delimited lingua list
+#                  net      number profanity SEN       URI    whitespace
+#                  zip/;
+
+sub import {
+    shift;  # Shift off the class.
+    tie %RE, __PACKAGE__;
+    {
+        no strict 'refs';
+        *{caller() . "::RE"} = \%RE;
+    }
+
+    my $saw_import;
+    my $no_defaults;
+    my %exclude;
+    foreach my $entry (grep {!/^RE_/} @_) {
+        if ($entry eq 'pattern') {
+            no strict 'refs';
+            *{caller() . "::pattern"} = \&pattern;
+            next;
+        }
+        # This used to prevent $; from being set. We still recognize it,
+        # but we won't do anything.
+        if ($entry eq 'clean') {
+            next;
+        }
+        if ($entry eq 'no_defaults') {
+            $no_defaults ++;
+            next;
+        }
+        if (my $module = $imports {$entry}) {
+            $saw_import ++;
+            eval "require $module;";
+            die $@ if $@;
+            next;
+        }
+        if ($entry =~ /^!(.*)/ && $imports {$1}) {
+            $exclude {$1} ++;
+            next;
+        }
+        # As a last resort, try to load the argument.
+        my $module = $entry =~ /^Regexp::Common/
+                            ? $entry
+                            : "Regexp::Common::" . $entry;
+        eval "require $module;";
+        die $@ if $@;
+    }
+
+    unless ($saw_import || $no_defaults) {
+        foreach my $module (values %imports) {
+            next if $exclude {$module};
+            eval "require $module;";
+            die $@ if $@;
+        }
+    }
+
+    my %exported;
+    foreach my $entry (grep {/^RE_/} @_) {
+        if ($entry =~ /^RE_(\w+_)?ALL$/) {
+            my $m  = defined $1 ? $1 : "";
+            my $re = qr /^RE_${m}.*$/;
+            while (my ($sub, $interface) = each %sub_interface) {
+                next if $exported {$sub};
+                next unless $sub =~ /$re/;
+                {
+                    no strict 'refs';
+                    *{caller() . "::$sub"} = $interface;
+                }
+                $exported {$sub} ++;
+            }
+        }
+        else {
+            next if $exported {$entry};
+            _croak "Can't export unknown subroutine &$entry"
+                unless $sub_interface {$entry};
+            {
+                no strict 'refs';
+                *{caller() . "::$entry"} = $sub_interface {$entry};
+            }
+            $exported {$entry} ++;
+        }
+    }
+}
+
+sub AUTOLOAD { _croak "Can't $AUTOLOAD" }
+
+sub DESTROY {}
+
+my %cache;
+
+my $fpat = qr/^(-\w+)/;
+
+sub _decache {
+        my @args = @{tied %{$_[0]}};
+        my @nonflags = grep {!/$fpat/} @args;
+        my $cache = get_cache(@nonflags);
+        _croak "Can't create unknown regex: \$RE{"
+            . join("}{",@args) . "}"
+                unless exists $cache->{__VAL__};
+        _croak "Perl $] does not support the pattern "
+            . "\$RE{" . join("}{",@args)
+            . "}.\nYou need Perl $cache->{__VAL__}{version} or later"
+                unless ($cache->{__VAL__}{version}||0) <= $];
+        my %flags = ( %{$cache->{__VAL__}{default}},
+                      map { /$fpat\Q$;\E(.*)/ ? ($1 => $2)
+                          : /$fpat/           ? ($1 => undef)
+                          :                     ()
+                          } @args);
+        $cache->{__VAL__}->_clone_with(\@args, \%flags);
+}
+
+use overload q{""} => \&_decache;
+
+
+sub get_cache {
+        my $cache = \%cache;
+        foreach (@_) {
+                $cache = $cache->{$_}
+                      || ($cache->{$_} = {});
+        }
+        return $cache;
+}
+
+sub croak_version {
+        my ($entry, @args) = @_;
+}
+
+sub pattern {
+        my %spec = @_;
+        _croak 'pattern() requires argument: name => [ @list ]'
+                unless $spec{name} && ref $spec{name} eq 'ARRAY';
+        _croak 'pattern() requires argument: create => $sub_ref_or_string'
+                unless $spec{create};
+
+        if (ref $spec{create} ne "CODE") {
+                my $fixed_str = "$spec{create}";
+                $spec{create} = sub { $fixed_str }
+        }
+
+        my @nonflags;
+        my %default;
+        foreach ( @{$spec{name}} ) {
+                if (/$fpat=(.*)/) {
+                        $default{$1} = $2;
+                }
+                elsif (/$fpat\s*$/) {
+                        $default{$1} = undef;
+                }
+                else {
+                        push @nonflags, $_;
+                }
+        }
+
+        my $entry = get_cache(@nonflags);
+
+        if ($entry->{__VAL__}) {
+                _carp "Overriding \$RE{"
+                   . join("}{",@nonflags)
+                   . "}";
+        }
+
+        $entry->{__VAL__} = bless {
+                                create  => $spec{create},
+                                match   => $spec{match} || \&generic_match,
+                                subs    => $spec{subs}  || \&generic_subs,
+                                version => $spec{version},
+                                default => \%default,
+                            }, 'Regexp::Common::Entry';
+
+        foreach (@nonflags) {s/\W/X/g}
+        my $subname = "RE_" . join ("_", @nonflags);
+        $sub_interface{$subname} = sub {
+                push @_ => undef if @_ % 2;
+                my %flags = @_;
+                my $pat = $spec{create}->($entry->{__VAL__},
+                               {%default, %flags}, \@nonflags);
+                if (exists $flags{-keep}) { $pat =~ s/\Q(?k:/(/g; }
+                else { $pat =~ s/\Q(?k:/(?:/g; }
+                return exists $flags {-i} ? qr /(?i:$pat)/ : qr/$pat/;
+        };
+
+        return 1;
+}
+
+sub generic_match {$_ [1] =~  /$_[0]/}
+sub generic_subs  {$_ [1] =~ s/$_[0]/$_[2]/}
+
+sub matches {
+        my ($self, $str) = @_;
+        my $entry = $self -> _decache;
+        $entry -> {match} -> ($entry, $str);
+}
+
+sub subs {
+        my ($self, $str, $newstr) = @_;
+        my $entry = $self -> _decache;
+        $entry -> {subs} -> ($entry, $str, $newstr);
+        return $str;
+}
+
+
+package Regexp::Common::Entry;
+# use Carp;
+
+local $^W = 1;
+
+use overload
+    q{""} => sub {
+        my ($self) = @_;
+        my $pat = $self->{create}->($self, $self->{flags}, $self->{args});
+        if (exists $self->{flags}{-keep}) {
+            $pat =~ s/\Q(?k:/(/g;
+        }
+        else {
+            $pat =~ s/\Q(?k:/(?:/g;
+        }
+        if (exists $self->{flags}{-i})   { $pat = "(?i)$pat" }
+        return $pat;
+    };
+
+sub _clone_with {
+    my ($self, $args, $flags) = @_;
+    bless { %$self, args=>$args, flags=>$flags }, ref $self;
+}
+# 
+#    Copyright (c) 2001 - 2005, Damian Conway and Abigail. All Rights
+#  Reserved. This module is free software. It may be used, redistributed
+#      and/or modified under the terms of the Perl Artistic License
+#            (see http://www.perl.com/perl/misc/Artistic.html)
+EOCommon
+# 2}}}
+$Regexp_Common_Contents{'Common/comment'} = <<'EOC';   # {{{2
+# $Id: comment.pm,v 2.116 2005/03/16 00:00:02 abigail Exp $
+
+package Regexp::Common::comment;
+
+use strict;
+local $^W = 1;
+
+use Regexp::Common qw /pattern clean no_defaults/;
+use vars qw /$VERSION/;
+
+($VERSION) = q $Revision: 2.116 $ =~ /[\d.]+/g;
+
+my @generic = (
+    {languages => [qw /ABC Forth/],
+     to_eol    => ['\\\\']},   # This is for just a *single* backslash.
+
+    {languages => [qw /Ada Alan Eiffel lua/],
+     to_eol    => ['--']},
+
+    {languages => [qw /Advisor/],
+     to_eol    => ['#|//']},
+
+    {languages => [qw /Advsys CQL Lisp LOGO M MUMPS REBOL Scheme
+                       SMITH zonefile/],
+     to_eol    => [';']},
+
+    {languages => ['Algol 60'],
+     from_to   => [[qw /comment ;/]]},
+
+    {languages => [qw {ALPACA B C C-- LPC PL/I}],
+     from_to   => [[qw {/* */}]]},
+
+    {languages => [qw /awk fvwm2 Icon mutt Perl Python QML R Ruby shell Tcl/],
+     to_eol    => ['#']},
+
+    {languages => [[BASIC => 'mvEnterprise']],
+     to_eol    => ['[*!]|REM']},
+
+    {languages => [qw /Befunge-98 Funge-98 Shelta/],
+     id        => [';']},
+
+    {languages => ['beta-Juliet', 'Crystal Report', 'Portia'],
+     to_eol    => ['//']},
+
+    {languages => ['BML'],
+     from_to   => [['<?_c', '_c?>']],
+    },
+
+    {languages => [qw /C++/, 'C#', qw /Cg ECMAScript FPL Java JavaScript/],
+     to_eol    => ['//'],
+     from_to   => [[qw {/* */}]]},
+
+    {languages => [qw /CLU LaTeX slrn TeX/],
+     to_eol    => ['%']},
+
+    {languages => [qw /False/],
+     from_to   => [[qw !{ }!]]},
+
+    {languages => [qw /Fortran/],
+     to_eol    => ['!']},
+
+    {languages => [qw /Haifu/],
+     id        => [',']},
+
+    {languages => [qw /ILLGOL/],
+     to_eol    => ['NB']},
+
+    {languages => [qw /INTERCAL/],
+     to_eol    => [q{(?:(?:PLEASE(?:\s+DO)?|DO)\s+)?(?:NOT|N'T)}]},
+
+    {languages => [qw /J/],
+     to_eol    => ['NB[.]']},
+
+    {languages => [qw /Nickle/],
+     to_eol    => ['#'],
+     from_to   => [[qw {/* */}]]},
+
+    {languages => [qw /Oberon/],
+     from_to   => [[qw /(* *)/]]},
+     
+    {languages => [[qw /Pascal Delphi/], [qw /Pascal Free/], [qw /Pascal GPC/]],
+     to_eol    => ['//'],
+     from_to   => [[qw !{ }!], [qw !(* *)!]]},
+
+    {languages => [[qw /Pascal Workshop/]],
+     id        => [qw /"/],
+     from_to   => [[qw !{ }!], [qw !(* *)!], [qw !/* */!]]},
+
+    {languages => [qw /PEARL/],
+     to_eol    => ['!'],
+     from_to   => [[qw {/* */}]]},
+
+    {languages => [qw /PHP/],
+     to_eol    => ['#', '//'],
+     from_to   => [[qw {/* */}]]},
+
+    {languages => [qw !PL/B!],
+     to_eol    => ['[.;]']},
+
+    {languages => [qw !PL/SQL!],
+     to_eol    => ['--'],
+     from_to   => [[qw {/* */}]]},
+
+    {languages => [qw /Q-BAL/],
+     to_eol    => ['`']},
+
+    {languages => [qw /Smalltalk/],
+     id        => ['"']},
+
+    {languages => [qw /SQL/],
+     to_eol    => ['-{2,}']},
+
+    {languages => [qw /troff/],
+     to_eol    => ['\\\"']},
+
+    {languages => [qw /vi/],
+     to_eol    => ['"']},
+
+    {languages => [qw /*W/],
+     from_to   => [[qw {|| !!}]]},
+);
+
+my @plain_or_nested = (
+   [Caml         =>  undef,       "(*"  => "*)"],
+   [Dylan        =>  "//",        "/*"  => "*/"],
+   [Haskell      =>  "-{2,}",     "{-"  => "-}"],
+   [Hugo         =>  "!(?!\\\\)", "!\\" => "\\!"],
+   [SLIDE        =>  "#",         "(*"  => "*)"],
+);
+
+#
+# Helper subs.
+#
+
+sub combine      {
+    local $_ = join "|", @_;
+    if (@_ > 1) {
+        s/\(\?k:/(?:/g;
+        $_ = "(?k:$_)";
+    }
+    $_
+}
+
+sub to_eol  ($)  {"(?k:(?k:$_[0])(?k:[^\\n]*)(?k:\\n))"}
+sub id      ($)  {"(?k:(?k:$_[0])(?k:[^$_[0]]*)(?k:$_[0]))"}  # One char only!
+sub from_to      {
+    local $^W = 1;
+    my ($begin, $end) = @_;
+
+    my $qb  = quotemeta $begin;
+    my $qe  = quotemeta $end;
+    my $fe  = quotemeta substr $end   => 0, 1;
+    my $te  = quotemeta substr $end   => 1;
+
+    "(?k:(?k:$qb)(?k:(?:[^$fe]+|$fe(?!$te))*)(?k:$qe))";
+}
+
+
+my $count = 0;
+sub nested {
+    local $^W = 1;
+    my ($begin, $end) = @_;
+
+    $count ++;
+    my $r = '(??{$Regexp::Common::comment ['. $count . ']})';
+
+    my $qb  = quotemeta $begin;
+    my $qe  = quotemeta $end;
+    my $fb  = quotemeta substr $begin => 0, 1;
+    my $fe  = quotemeta substr $end   => 0, 1;
+
+    my $tb  = quotemeta substr $begin => 1;
+    my $te  = quotemeta substr $end   => 1;
+
+    use re 'eval';
+
+    my $re;
+    if ($fb eq $fe) {
+        $re = qr /(?:$qb(?:(?>[^$fb]+)|$fb(?!$tb)(?!$te)|$r)*$qe)/;
+    }
+    else {
+        local $"      =  "|";
+        my   @clauses =  "(?>[^$fb$fe]+)";
+        push @clauses => "$fb(?!$tb)" if length $tb;
+        push @clauses => "$fe(?!$te)" if length $te;
+        push @clauses =>  $r;
+        $re           =   qr /(?:$qb(?:@clauses)*$qe)/;
+    }
+
+    $Regexp::Common::comment [$count] = qr/$re/;
+}
+
+#
+# Process data.
+#
+
+foreach my $info (@plain_or_nested) {
+    my ($language, $mark, $begin, $end) = @$info;
+    pattern name    => [comment => $language],
+            create  =>
+                sub {my $re     = nested $begin => $end;
+                     my $prefix = defined $mark ? $mark . "[^\n]*\n|" : "";
+                     exists $_ [1] -> {-keep} ? qr /($prefix$re)/
+                                              : qr  /$prefix$re/
+                },
+            version => 5.006,
+            ;
+}
+
+
+foreach my $group (@generic) {
+    my $pattern = combine +(map {to_eol   $_} @{$group -> {to_eol}}),
+                           (map {from_to @$_} @{$group -> {from_to}}),
+                           (map {id       $_} @{$group -> {id}}),
+                  ;
+    foreach my $language  (@{$group -> {languages}}) {
+        pattern name    => [comment => ref $language ? @$language : $language],
+                create  => $pattern,
+                ;
+    }
+}
+                
+
+    
+#
+# Other languages.
+#
+
+# http://www.pascal-central.com/docs/iso10206.txt
+pattern name    => [qw /comment Pascal/],
+        create  => '(?k:' . '(?k:[{]|[(][*])'
+                          . '(?k:[^}*]*(?:[*][^)][^}*]*)*)'
+                          . '(?k:[}]|[*][)])'
+                          . ')'
+        ;
+
+# http://www.templetons.com/brad/alice/language/
+pattern name    =>  [qw /comment Pascal Alice/],
+        create  =>  '(?k:(?k:[{])(?k:[^}\n]*)(?k:[}]))'
+        ;
+
+
+# http://westein.arb-phys.uni-dortmund.de/~wb/a68s.txt
+pattern name    => [qw (comment), 'Algol 68'],
+        create  => q {(?k:(?:#[^#]*#)|}                           .
+                   q {(?:\bco\b(?:[^c]+|\Bc|\bc(?!o\b))*\bco\b)|} .
+                   q {(?:\bcomment\b(?:[^c]+|\Bc|\bc(?!omment\b))*\bcomment\b))}
+        ;
+
+
+# See rules 91 and 92 of ISO 8879 (SGML).
+# Charles F. Goldfarb: "The SGML Handbook".
+# Oxford: Oxford University Press. 1990. ISBN 0-19-853737-9.
+# Ch. 10.3, pp 390.
+pattern name    => [qw (comment HTML)],
+        create  => q {(?k:(?k:<!)(?k:(?:--(?k:[^-]*(?:-[^-]+)*)--\s*)*)(?k:>))},
+        ;
+
+
+pattern name    => [qw /comment SQL MySQL/],
+        create  => q {(?k:(?:#|-- )[^\n]*\n|} .
+                   q {/\*(?:(?>[^*;"']+)|"[^"]*"|'[^']*'|\*(?!/))*(?:;|\*/))},
+        ;
+
+# Anything that isn't <>[]+-.,
+# http://home.wxs.nl/~faase009/Ha_BF.html
+pattern name    => [qw /comment Brainfuck/],
+        create  => '(?k:[^<>\[\]+\-.,]+)'
+        ;
+
+# Squeak is a variant of Smalltalk-80.
+# http://www.squeak.
+# http://mucow.com/squeak-qref.html
+pattern name    => [qw /comment Squeak/],
+        create  => '(?k:(?k:")(?k:[^"]*(?:""[^"]*)*)(?k:"))'
+        ;
+
+#
+# Scores of less than 5 or above 17....
+# http://www.cliff.biffle.org/esoterica/beatnik.html
+@Regexp::Common::comment::scores = (1,  3,  3,  2,  1,  4,  2,  4,  1,  8,
+                                    5,  1,  3,  1,  1,  3, 10,  1,  1,  1,
+                                    1,  4,  4,  8,  4, 10);
+pattern name    =>  [qw /comment Beatnik/],
+        create  =>  sub {
+            use re 'eval';
+            my ($s, $x);
+            my $re = qr {\b([A-Za-z]+)\b
+                         (?(?{($s, $x) = (0, lc $^N);
+                              $s += $Regexp::Common::comment::scores
+                                    [ord (chop $x) - ord ('a')] while length $x;
+                              $s  >= 5 && $s < 18})XXX|)}x;
+            $re;
+        },
+        version  => 5.008,
+        ;
+
+
+# http://www.cray.com/craydoc/manuals/007-3692-005/html-007-3692-005/
+#  (Goto table of contents/3.3 Source Form)
+# Fortran, in fixed format. Comments start with a C, c or * in the first
+# column, or a ! anywhere, but the sixth column. Then end with a newline.
+pattern name    =>  [qw /comment Fortran fixed/],
+        create  =>  '(?k:(?k:(?:^[Cc*]|(?<!^.....)!))(?k:[^\n]*)(?k:\n))'
+        ;
+
+
+# http://www.csis.ul.ie/cobol/Course/COBOLIntro.htm
+# Traditionally, comments in COBOL were indicated with an asteriks in
+# the seventh column. Modern compilers may be more lenient.
+pattern name    =>  [qw /comment COBOL/],
+        create  =>  '(?<=^......)(?k:(?k:[*])(?k:[^\n]*)(?k:\n))',
+        version =>  '5.008',
+        ;
+
+1;
+#
+#    Copyright (c) 2001 - 2003, Damian Conway. All Rights Reserved.
+#      This module is free software. It may be used, redistributed
+#     and/or modified under the terms of the Perl Artistic License
+#           (see http://www.perl.com/perl/misc/Artistic.html)
+EOC
+# 2}}}
+$Regexp_Common_Contents{'Common/balanced'} = <<'EOB';   # {{{2
+package Regexp::Common::balanced; {
+
+use strict;
+local $^W = 1;
+
+use vars qw /$VERSION/;
+($VERSION) = q $Revision: 2.101 $ =~ /[\d.]+/g;
+
+use Regexp::Common qw /pattern clean no_defaults/;
+
+my %closer = ( '{'=>'}', '('=>')', '['=>']', '<'=>'>' );
+my $count = -1;
+my %cache;
+
+sub nested {
+    local $^W = 1;
+    my ($start, $finish) = @_;
+
+    return $Regexp::Common::balanced [$cache {$start} {$finish}]
+            if exists $cache {$start} {$finish};
+
+    $count ++;
+    my $r = '(??{$Regexp::Common::balanced ['. $count . ']})';
+
+    my @starts   = map {s/\\(.)/$1/g; $_} grep {length}
+                        $start  =~ /([^|\\]+|\\.)+/gs;
+    my @finishes = map {s/\\(.)/$1/g; $_} grep {length}
+                        $finish =~ /([^|\\]+|\\.)+/gs;
+
+    push @finishes => ($finishes [-1]) x (@starts - @finishes);
+
+    my @re;
+    local $" = "|";
+    foreach my $begin (@starts) {
+        my $end = shift @finishes;
+
+        my $qb  = quotemeta $begin;
+        my $qe  = quotemeta $end;
+        my $fb  = quotemeta substr $begin => 0, 1;
+        my $fe  = quotemeta substr $end   => 0, 1;
+
+        my $tb  = quotemeta substr $begin => 1;
+        my $te  = quotemeta substr $end   => 1;
+
+        use re 'eval';
+
+        my $add;
+        if ($fb eq $fe) {
+            push @re =>
+                   qr /(?:$qb(?:(?>[^$fb]+)|$fb(?!$tb)(?!$te)|$r)*$qe)/;
+        }
+        else {
+            my   @clauses =  "(?>[^$fb$fe]+)";
+            push @clauses => "$fb(?!$tb)" if length $tb;
+            push @clauses => "$fe(?!$te)" if length $te;
+            push @clauses =>  $r;
+            push @re      =>  qr /(?:$qb(?:@clauses)*$qe)/;
+        }
+    }
+
+    $cache {$start} {$finish} = $count;
+    $Regexp::Common::balanced [$count] = qr/@re/;
+}
+
+
+pattern name    => [qw /balanced -parens=() -begin= -end=/],
+        create  => sub {
+            my $flag = $_[1];
+            unless (defined $flag -> {-begin} && length $flag -> {-begin} &&
+                    defined $flag -> {-end}   && length $flag -> {-end}) {
+                my @open  = grep {index ($flag->{-parens}, $_) >= 0}
+                             ('[','(','{','<');
+                my @close = map {$closer {$_}} @open;
+                $flag -> {-begin} = join "|" => @open;
+                $flag -> {-end}   = join "|" => @close;
+            }
+            my $pat = nested @$flag {qw /-begin -end/};
+            return exists $flag -> {-keep} ? qr /($pat)/ : $pat;
+        },
+        version => 5.006,
+        ;
+
+}
+
+1;
+#
+#     Copyright (c) 2001 - 2003, Damian Conway. All Rights Reserved.
+#       This module is free software. It may be used, redistributed
+#      and/or modified under the terms of the Perl Artistic License
+#            (see http://www.perl.com/perl/misc/Artistic.html)
+EOB
+# 2}}}
+$Regexp_Common_Contents{'Common/delimited'} = <<'EOD';   # {{{2
+# $Id: delimited.pm,v 2.104 2005/03/16 00:22:45 abigail Exp $
+
+package Regexp::Common::delimited;
+
+use strict;
+local $^W = 1;
+
+use Regexp::Common qw /pattern clean no_defaults/;
+use vars qw /$VERSION/;
+
+($VERSION) = q $Revision: 2.104 $ =~ /[\d.]+/g;
+
+sub gen_delimited {
+
+    my ($dels, $escs) = @_;
+    # return '(?:\S*)' unless $dels =~ /\S/;
+    if (length $escs) {
+        $escs .= substr ($escs, -1) x (length ($dels) - length ($escs));
+    }
+    my @pat = ();
+    my $i;
+    for ($i=0; $i < length $dels; $i++) {
+        my $del = quotemeta substr ($dels, $i, 1);
+        my $esc = length($escs) ? quotemeta substr ($escs, $i, 1) : "";
+        if ($del eq $esc) {
+            push @pat,
+                 "(?k:$del)(?k:[^$del]*(?:(?:$del$del)[^$del]*)*)(?k:$del)";
+        }
+        elsif (length $esc) {
+            push @pat,
+                 "(?k:$del)(?k:[^$esc$del]*(?:$esc.[^$esc$del]*)*)(?k:$del)";
+        }
+        else {
+            push @pat, "(?k:$del)(?k:[^$del]*)(?k:$del)";
+        }
+    }
+    my $pat = join '|', @pat;
+    return "(?k:$pat)";
+}
+
+sub _croak {
+    require Carp;
+    goto &Carp::croak;
+}
+
+pattern name   => [qw( delimited -delim= -esc=\\ )],
+        create => sub {my $flags = $_[1];
+                       _croak 'Must specify delimiter in $RE{delimited}'
+                             unless length $flags->{-delim};
+                       return gen_delimited (@{$flags}{-delim, -esc});
+                  },
+        ;
+
+pattern name   => [qw( quoted -esc=\\ )],
+        create => sub {my $flags = $_[1];
+                       return gen_delimited (q{"'`}, $flags -> {-esc});
+                  },
+        ;
+
+
+1;
+#
+#     Copyright (c) 2001 - 2003, Damian Conway. All Rights Reserved.
+#       This module is free software. It may be used, redistributed
+#      and/or modified under the terms of the Perl Artistic License
+#            (see http://www.perl.com/perl/misc/Artistic.html)
+EOD
+# 2}}}
+    my $problems        = 0;
+    $HAVE_Rexexp_Common = 0;
+    my $dir             = "";
+    if ($opt_sdir) {
+        ++$TEMP_OFF;
+        $dir = "$opt_sdir/$TEMP_OFF";
+        File::Path::rmtree($dir) if     is_dir($dir);
+        File::Path::mkpath($dir) unless is_dir($dir);
+    } else {
+        # let File::Temp create a suitable temporary directory
+        $dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
+        $TEMP_INST{ $dir } = "Regexp::Common";
+    }
+    print "Using temp dir [$dir] to install Regexp::Common\n" if $opt_v;
+    my $Regexp_dir        = "$dir/Regexp";
+    my $Regexp_Common_dir = "$dir/Regexp/Common";
+    mkdir $Regexp_dir       ;
+    mkdir $Regexp_Common_dir;
+
+    foreach my $module_file (keys %Regexp_Common_Contents) {
+        my $OUT = new IO::File "$dir/Regexp/${module_file}.pm", "w";
+        if (defined $OUT) {
+            print $OUT $Regexp_Common_Contents{$module_file};
+            $OUT->close;
+        } else {
+            warn "Failed to install Regexp::${module_file}.pm\n";
+            $problems = 1;
+        }
+    }
+
+    push @INC, $dir;
+    eval "use Regexp::Common qw /comment RE_comment_HTML balanced/";
+    $HAVE_Rexexp_Common = 1 unless $problems;
+} # 1}}}
+sub Install_Algorithm_Diff {                 # {{{1
+    # Installs Tye McQueen's Algorithm::Diff module, v1.1902, into a 
+    # temporary directory for the duration of this run.
+
+my $Algorithm_Diff_Contents = <<'EOAlgDiff'; # {{{2
+package Algorithm::Diff;
+# Skip to first "=head" line for documentation.
+use strict;
+
+use integer;    # see below in _replaceNextLargerWith() for mod to make
+                # if you don't use this
+use vars qw( $VERSION @EXPORT_OK );
+$VERSION = 1.19_02;
+#          ^ ^^ ^^-- Incremented at will
+#          | \+----- Incremented for non-trivial changes to features
+#          \-------- Incremented for fundamental changes
+require Exporter;
+*import    = \&Exporter::import;
+@EXPORT_OK = qw(
+    prepare LCS LCSidx LCS_length
+    diff sdiff compact_diff
+    traverse_sequences traverse_balanced
+);
+
+# McIlroy-Hunt diff algorithm
+# Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com>
+# by Ned Konz, perl@bike-nomad.com
+# Updates by Tye McQueen, http://perlmonks.org/?node=tye
+
+# Create a hash that maps each element of $aCollection to the set of
+# positions it occupies in $aCollection, restricted to the elements
+# within the range of indexes specified by $start and $end.
+# The fourth parameter is a subroutine reference that will be called to
+# generate a string to use as a key.
+# Additional parameters, if any, will be passed to this subroutine.
+#
+# my $hashRef = _withPositionsOfInInterval( \@array, $start, $end, $keyGen );
+
+sub _withPositionsOfInInterval
+{
+    my $aCollection = shift;    # array ref
+    my $start       = shift;
+    my $end         = shift;
+    my $keyGen      = shift;
+    my %d;
+    my $index;
+    for ( $index = $start ; $index <= $end ; $index++ )
+    {
+        my $element = $aCollection->[$index];
+        my $key = &$keyGen( $element, @_ );
+        if ( exists( $d{$key} ) )
+        {
+            unshift ( @{ $d{$key} }, $index );
+        }
+        else
+        {
+            $d{$key} = [$index];
+        }
+    }
+    return wantarray ? %d : \%d;
+}
+
+# Find the place at which aValue would normally be inserted into the
+# array. If that place is already occupied by aValue, do nothing, and
+# return undef. If the place does not exist (i.e., it is off the end of
+# the array), add it to the end, otherwise replace the element at that
+# point with aValue.  It is assumed that the array's values are numeric.
+# This is where the bulk (75%) of the time is spent in this module, so
+# try to make it fast!
+
+sub _replaceNextLargerWith
+{
+    my ( $array, $aValue, $high ) = @_;
+    $high ||= $#$array;
+
+    # off the end?
+    if ( $high == -1 || $aValue > $array->[-1] )
+    {
+        push ( @$array, $aValue );
+        return $high + 1;
+    }
+
+    # binary search for insertion point...
+    my $low = 0;
+    my $index;
+    my $found;
+    while ( $low <= $high )
+    {
+        $index = ( $high + $low ) / 2;
+
+        # $index = int(( $high + $low ) / 2);  # without 'use integer'
+        $found = $array->[$index];
+
+        if ( $aValue == $found )
+        {
+            return undef;
+        }
+        elsif ( $aValue > $found )
+        {
+            $low = $index + 1;
+        }
+        else
+        {
+            $high = $index - 1;
+        }
+    }
+
+    # now insertion point is in $low.
+    $array->[$low] = $aValue;    # overwrite next larger
+    return $low;
+}
+
+# This method computes the longest common subsequence in $a and $b.
+
+# Result is array or ref, whose contents is such that
+#   $a->[ $i ] == $b->[ $result[ $i ] ]
+# foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined.
+
+# An additional argument may be passed; this is a hash or key generating
+# function that should return a string that uniquely identifies the given
+# element.  It should be the case that if the key is the same, the elements
+# will compare the same. If this parameter is undef or missing, the key
+# will be the element as a string.
+
+# By default, comparisons will use "eq" and elements will be turned into keys
+# using the default stringizing operator '""'.
+
+# Additional parameters, if any, will be passed to the key generation
+# routine.
+
+sub _longestCommonSubsequence
+{
+    my $a        = shift;    # array ref or hash ref
+    my $b        = shift;    # array ref or hash ref
+    my $counting = shift;    # scalar
+    my $keyGen   = shift;    # code ref
+    my $compare;             # code ref
+
+    if ( ref($a) eq 'HASH' )
+    {                        # prepared hash must be in $b
+        my $tmp = $b;
+        $b = $a;
+        $a = $tmp;
+    }
+
+    # Check for bogus (non-ref) argument values
+    if ( !ref($a) || !ref($b) )
+    {
+        my @callerInfo = caller(1);
+        die 'error: must pass array or hash references to ' . $callerInfo[3];
+    }
+
+    # set up code refs
+    # Note that these are optimized.
+    if ( !defined($keyGen) )    # optimize for strings
+    {
+        $keyGen = sub { $_[0] };
+        $compare = sub { my ( $a, $b ) = @_; $a eq $b };
+    }
+    else
+    {
+        $compare = sub {
+            my $a = shift;
+            my $b = shift;
+            &$keyGen( $a, @_ ) eq &$keyGen( $b, @_ );
+        };
+    }
+
+    my ( $aStart, $aFinish, $matchVector ) = ( 0, $#$a, [] );
+    my ( $prunedCount, $bMatches ) = ( 0, {} );
+
+    if ( ref($b) eq 'HASH' )    # was $bMatches prepared for us?
+    {
+        $bMatches = $b;
+    }
+    else
+    {
+        my ( $bStart, $bFinish ) = ( 0, $#$b );
+
+        # First we prune off any common elements at the beginning
+        while ( $aStart <= $aFinish
+            and $bStart <= $bFinish
+            and &$compare( $a->[$aStart], $b->[$bStart], @_ ) )
+        {
+            $matchVector->[ $aStart++ ] = $bStart++;
+            $prunedCount++;
+        }
+
+        # now the end
+        while ( $aStart <= $aFinish
+            and $bStart <= $bFinish
+            and &$compare( $a->[$aFinish], $b->[$bFinish], @_ ) )
+        {
+            $matchVector->[ $aFinish-- ] = $bFinish--;
+            $prunedCount++;
+        }
+
+        # Now compute the equivalence classes of positions of elements
+        $bMatches =
+          _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ );
+    }
+    my $thresh = [];
+    my $links  = [];
+
+    my ( $i, $ai, $j, $k );
+    for ( $i = $aStart ; $i <= $aFinish ; $i++ )
+    {
+        $ai = &$keyGen( $a->[$i], @_ );
+        if ( exists( $bMatches->{$ai} ) )
+        {
+            $k = 0;
+            for $j ( @{ $bMatches->{$ai} } )
+            {
+
+                # optimization: most of the time this will be true
+                if ( $k and $thresh->[$k] > $j and $thresh->[ $k - 1 ] < $j )
+                {
+                    $thresh->[$k] = $j;
+                }
+                else
+                {
+                    $k = _replaceNextLargerWith( $thresh, $j, $k );
+                }
+
+                # oddly, it's faster to always test this (CPU cache?).
+                if ( defined($k) )
+                {
+                    $links->[$k] =
+                      [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];
+                }
+            }
+        }
+    }
+
+    if (@$thresh)
+    {
+        return $prunedCount + @$thresh if $counting;
+        for ( my $link = $links->[$#$thresh] ; $link ; $link = $link->[0] )
+        {
+            $matchVector->[ $link->[1] ] = $link->[2];
+        }
+    }
+    elsif ($counting)
+    {
+        return $prunedCount;
+    }
+
+    return wantarray ? @$matchVector : $matchVector;
+}
+
+sub traverse_sequences
+{
+    my $a                 = shift;          # array ref
+    my $b                 = shift;          # array ref
+    my $callbacks         = shift || {};
+    my $keyGen            = shift;
+    my $matchCallback     = $callbacks->{'MATCH'} || sub { };
+    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };
+    my $finishedACallback = $callbacks->{'A_FINISHED'};
+    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };
+    my $finishedBCallback = $callbacks->{'B_FINISHED'};
+    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );
+
+    # Process all the lines in @$matchVector
+    my $lastA = $#$a;
+    my $lastB = $#$b;
+    my $bi    = 0;
+    my $ai;
+
+    for ( $ai = 0 ; $ai <= $#$matchVector ; $ai++ )
+    {
+        my $bLine = $matchVector->[$ai];
+        if ( defined($bLine) )    # matched
+        {
+            &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;
+            &$matchCallback( $ai,    $bi++, @_ );
+        }
+        else
+        {
+            &$discardACallback( $ai, $bi, @_ );
+        }
+    }
+
+    # The last entry (if any) processed was a match.
+    # $ai and $bi point just past the last matching lines in their sequences.
+
+    while ( $ai <= $lastA or $bi <= $lastB )
+    {
+
+        # last A?
+        if ( $ai == $lastA + 1 and $bi <= $lastB )
+        {
+            if ( defined($finishedACallback) )
+            {
+                &$finishedACallback( $lastA, @_ );
+                $finishedACallback = undef;
+            }
+            else
+            {
+                &$discardBCallback( $ai, $bi++, @_ ) while $bi <= $lastB;
+            }
+        }
+
+        # last B?
+        if ( $bi == $lastB + 1 and $ai <= $lastA )
+        {
+            if ( defined($finishedBCallback) )
+            {
+                &$finishedBCallback( $lastB, @_ );
+                $finishedBCallback = undef;
+            }
+            else
+            {
+                &$discardACallback( $ai++, $bi, @_ ) while $ai <= $lastA;
+            }
+        }
+
+        &$discardACallback( $ai++, $bi, @_ ) if $ai <= $lastA;
+        &$discardBCallback( $ai, $bi++, @_ ) if $bi <= $lastB;
+    }
+
+    return 1;
+}
+
+sub traverse_balanced
+{
+    my $a                 = shift;              # array ref
+    my $b                 = shift;              # array ref
+    my $callbacks         = shift || {};
+    my $keyGen            = shift;
+    my $matchCallback     = $callbacks->{'MATCH'} || sub { };
+    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };
+    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };
+    my $changeCallback    = $callbacks->{'CHANGE'};
+    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );
+
+    # Process all the lines in match vector
+    my $lastA = $#$a;
+    my $lastB = $#$b;
+    my $bi    = 0;
+    my $ai    = 0;
+    my $ma    = -1;
+    my $mb;
+
+    while (1)
+    {
+
+        # Find next match indices $ma and $mb
+        do {
+            $ma++;
+        } while(
+                $ma <= $#$matchVector
+            &&  !defined $matchVector->[$ma]
+        );
+
+        last if $ma > $#$matchVector;    # end of matchVector?
+        $mb = $matchVector->[$ma];
+
+        # Proceed with discard a/b or change events until
+        # next match
+        while ( $ai < $ma || $bi < $mb )
+        {
+
+            if ( $ai < $ma && $bi < $mb )
+            {
+
+                # Change
+                if ( defined $changeCallback )
+                {
+                    &$changeCallback( $ai++, $bi++, @_ );
+                }
+                else
+                {
+                    &$discardACallback( $ai++, $bi, @_ );
+                    &$discardBCallback( $ai, $bi++, @_ );
+                }
+            }
+            elsif ( $ai < $ma )
+            {
+                &$discardACallback( $ai++, $bi, @_ );
+            }
+            else
+            {
+
+                # $bi < $mb
+                &$discardBCallback( $ai, $bi++, @_ );
+            }
+        }
+
+        # Match
+        &$matchCallback( $ai++, $bi++, @_ );
+    }
+
+    while ( $ai <= $lastA || $bi <= $lastB )
+    {
+        if ( $ai <= $lastA && $bi <= $lastB )
+        {
+
+            # Change
+            if ( defined $changeCallback )
+            {
+                &$changeCallback( $ai++, $bi++, @_ );
+            }
+            else
+            {
+                &$discardACallback( $ai++, $bi, @_ );
+                &$discardBCallback( $ai, $bi++, @_ );
+            }
+        }
+        elsif ( $ai <= $lastA )
+        {
+            &$discardACallback( $ai++, $bi, @_ );
+        }
+        else
+        {
+
+            # $bi <= $lastB
+            &$discardBCallback( $ai, $bi++, @_ );
+        }
+    }
+
+    return 1;
+}
+
+sub prepare
+{
+    my $a       = shift;    # array ref
+    my $keyGen  = shift;    # code ref
+
+    # set up code ref
+    $keyGen = sub { $_[0] } unless defined($keyGen);
+
+    return scalar _withPositionsOfInInterval( $a, 0, $#$a, $keyGen, @_ );
+}
+
+sub LCS
+{
+    my $a = shift;                  # array ref
+    my $b = shift;                  # array ref or hash ref
+    my $matchVector = _longestCommonSubsequence( $a, $b, 0, @_ );
+    my @retval;
+    my $i;
+    for ( $i = 0 ; $i <= $#$matchVector ; $i++ )
+    {
+        if ( defined( $matchVector->[$i] ) )
+        {
+            push ( @retval, $a->[$i] );
+        }
+    }
+    return wantarray ? @retval : \@retval;
+}
+
+sub LCS_length
+{
+    my $a = shift;                          # array ref
+    my $b = shift;                          # array ref or hash ref
+    return _longestCommonSubsequence( $a, $b, 1, @_ );
+}
+
+sub LCSidx
+{
+    my $a= shift @_;
+    my $b= shift @_;
+    my $match= _longestCommonSubsequence( $a, $b, 0, @_ );
+    my @am= grep defined $match->[$_], 0..$#$match;
+    my @bm= @{$match}[@am];
+    return \@am, \@bm;
+}
+
+sub compact_diff
+{
+    my $a= shift @_;
+    my $b= shift @_;
+    my( $am, $bm )= LCSidx( $a, $b, @_ );
+    my @cdiff;
+    my( $ai, $bi )= ( 0, 0 );
+    push @cdiff, $ai, $bi;
+    while( 1 ) {
+        while(  @$am  &&  $ai == $am->[0]  &&  $bi == $bm->[0]  ) {
+            shift @$am;
+            shift @$bm;
+            ++$ai, ++$bi;
+        }
+        push @cdiff, $ai, $bi;
+        last   if  ! @$am;
+        $ai = $am->[0];
+        $bi = $bm->[0];
+        push @cdiff, $ai, $bi;
+    }
+    push @cdiff, 0+@$a, 0+@$b
+        if  $ai < @$a || $bi < @$b;
+    return wantarray ? @cdiff : \@cdiff;
+}
+
+sub diff
+{
+    my $a      = shift;    # array ref
+    my $b      = shift;    # array ref
+    my $retval = [];
+    my $hunk   = [];
+    my $discard = sub {
+        push @$hunk, [ '-', $_[0], $a->[ $_[0] ] ];
+    };
+    my $add = sub {
+        push @$hunk, [ '+', $_[1], $b->[ $_[1] ] ];
+    };
+    my $match = sub {
+        push @$retval, $hunk
+            if 0 < @$hunk;
+        $hunk = []
+    };
+    traverse_sequences( $a, $b,
+        { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add }, @_ );
+    &$match();
+    return wantarray ? @$retval : $retval;
+}
+
+sub sdiff
+{
+    my $a      = shift;    # array ref
+    my $b      = shift;    # array ref
+    my $retval = [];
+    my $discard = sub { push ( @$retval, [ '-', $a->[ $_[0] ], "" ] ) };
+    my $add = sub { push ( @$retval, [ '+', "", $b->[ $_[1] ] ] ) };
+    my $change = sub {
+        push ( @$retval, [ 'c', $a->[ $_[0] ], $b->[ $_[1] ] ] );
+    };
+    my $match = sub {
+        push ( @$retval, [ 'u', $a->[ $_[0] ], $b->[ $_[1] ] ] );
+    };
+    traverse_balanced(
+        $a,
+        $b,
+        {
+            MATCH     => $match,
+            DISCARD_A => $discard,
+            DISCARD_B => $add,
+            CHANGE    => $change,
+        },
+        @_
+    );
+    return wantarray ? @$retval : $retval;
+}
+
+########################################
+my $Root= __PACKAGE__;
+package Algorithm::Diff::_impl;
+use strict;
+
+sub _Idx()  { 0 } # $me->[_Idx]: Ref to array of hunk indices
+            # 1   # $me->[1]: Ref to first sequence
+            # 2   # $me->[2]: Ref to second sequence
+sub _End()  { 3 } # $me->[_End]: Diff between forward and reverse pos
+sub _Same() { 4 } # $me->[_Same]: 1 if pos 1 contains unchanged items
+sub _Base() { 5 } # $me->[_Base]: Added to range's min and max
+sub _Pos()  { 6 } # $me->[_Pos]: Which hunk is currently selected
+sub _Off()  { 7 } # $me->[_Off]: Offset into _Idx for current position
+sub _Min() { -2 } # Added to _Off to get min instead of max+1
+
+sub Die
+{
+    require Carp;
+    Carp::confess( @_ );
+}
+
+sub _ChkPos
+{
+    my( $me )= @_;
+    return   if  $me->[_Pos];
+    my $meth= ( caller(1) )[3];
+    Die( "Called $meth on 'reset' object" );
+}
+
+sub _ChkSeq
+{
+    my( $me, $seq )= @_;
+    return $seq + $me->[_Off]
+        if  1 == $seq  ||  2 == $seq;
+    my $meth= ( caller(1) )[3];
+    Die( "$meth: Invalid sequence number ($seq); must be 1 or 2" );
+}
+
+sub getObjPkg
+{
+    my( $us )= @_;
+    return ref $us   if  ref $us;
+    return $us . "::_obj";
+}
+
+sub new
+{
+    my( $us, $seq1, $seq2, $opts ) = @_;
+    my @args;
+    for( $opts->{keyGen} ) {
+        push @args, $_   if  $_;
+    }
+    for( $opts->{keyGenArgs} ) {
+        push @args, @$_   if  $_;
+    }
+    my $cdif= Algorithm::Diff::compact_diff( $seq1, $seq2, @args );
+    my $same= 1;
+    if(  0 == $cdif->[2]  &&  0 == $cdif->[3]  ) {
+        $same= 0;
+        splice @$cdif, 0, 2;
+    }
+    my @obj= ( $cdif, $seq1, $seq2 );
+    $obj[_End] = (1+@$cdif)/2;
+    $obj[_Same] = $same;
+    $obj[_Base] = 0;
+    my $me = bless \@obj, $us->getObjPkg();
+    $me->Reset( 0 );
+    return $me;
+}
+
+sub Reset
+{
+    my( $me, $pos )= @_;
+    $pos= int( $pos || 0 );
+    $pos += $me->[_End]
+        if  $pos < 0;
+    $pos= 0
+        if  $pos < 0  ||  $me->[_End] <= $pos;
+    $me->[_Pos]= $pos || !1;
+    $me->[_Off]= 2*$pos - 1;
+    return $me;
+}
+
+sub Base
+{
+    my( $me, $base )= @_;
+    my $oldBase= $me->[_Base];
+    $me->[_Base]= 0+$base   if  defined $base;
+    return $oldBase;
+}
+
+sub Copy
+{
+    my( $me, $pos, $base )= @_;
+    my @obj= @$me;
+    my $you= bless \@obj, ref($me);
+    $you->Reset( $pos )   if  defined $pos;
+    $you->Base( $base );
+    return $you;
+}
+
+sub Next {
+    my( $me, $steps )= @_;
+    $steps= 1   if  ! defined $steps;
+    if( $steps ) {
+        my $pos= $me->[_Pos];
+        my $new= $pos + $steps;
+        $new= 0   if  $pos  &&  $new < 0;
+        $me->Reset( $new )
+    }
+    return $me->[_Pos];
+}
+
+sub Prev {
+    my( $me, $steps )= @_;
+    $steps= 1   if  ! defined $steps;
+    my $pos= $me->Next(-$steps);
+    $pos -= $me->[_End]   if  $pos;
+    return $pos;
+}
+
+sub Diff {
+    my( $me )= @_;
+    $me->_ChkPos();
+    return 0   if  $me->[_Same] == ( 1 & $me->[_Pos] );
+    my $ret= 0;
+    my $off= $me->[_Off];
+    for my $seq ( 1, 2 ) {
+        $ret |= $seq
+            if  $me->[_Idx][ $off + $seq + _Min ]
+            <   $me->[_Idx][ $off + $seq ];
+    }
+    return $ret;
+}
+
+sub Min {
+    my( $me, $seq, $base )= @_;
+    $me->_ChkPos();
+    my $off= $me->_ChkSeq($seq);
+    $base= $me->[_Base] if !defined $base;
+    return $base + $me->[_Idx][ $off + _Min ];
+}
+
+sub Max {
+    my( $me, $seq, $base )= @_;
+    $me->_ChkPos();
+    my $off= $me->_ChkSeq($seq);
+    $base= $me->[_Base] if !defined $base;
+    return $base + $me->[_Idx][ $off ] -1;
+}
+
+sub Range {
+    my( $me, $seq, $base )= @_;
+    $me->_ChkPos();
+    my $off = $me->_ChkSeq($seq);
+    if( !wantarray ) {
+        return  $me->[_Idx][ $off ]
+            -   $me->[_Idx][ $off + _Min ];
+    }
+    $base= $me->[_Base] if !defined $base;
+    return  ( $base + $me->[_Idx][ $off + _Min ] )
+        ..  ( $base + $me->[_Idx][ $off ] - 1 );
+}
+
+sub Items {
+    my( $me, $seq )= @_;
+    $me->_ChkPos();
+    my $off = $me->_ChkSeq($seq);
+    if( !wantarray ) {
+        return  $me->[_Idx][ $off ]
+            -   $me->[_Idx][ $off + _Min ];
+    }
+    return
+        @{$me->[$seq]}[
+                $me->[_Idx][ $off + _Min ]
+            ..  ( $me->[_Idx][ $off ] - 1 )
+        ];
+}
+
+sub Same {
+    my( $me )= @_;
+    $me->_ChkPos();
+    return wantarray ? () : 0
+        if  $me->[_Same] != ( 1 & $me->[_Pos] );
+    return $me->Items(1);
+}
+
+my %getName;
+BEGIN {
+    %getName= (
+        same => \&Same,
+        diff => \&Diff,
+        base => \&Base,
+        min  => \&Min,
+        max  => \&Max,
+        range=> \&Range,
+        items=> \&Items, # same thing
+    );
+}
+
+sub Get
+{
+    my $me= shift @_;
+    $me->_ChkPos();
+    my @value;
+    for my $arg (  @_  ) {
+        for my $word (  split ' ', $arg  ) {
+            my $meth;
+            if(     $word !~ /^(-?\d+)?([a-zA-Z]+)([12])?$/
+                ||  not  $meth= $getName{ lc $2 }
+            ) {
+                Die( $Root, ", Get: Invalid request ($word)" );
+            }
+            my( $base, $name, $seq )= ( $1, $2, $3 );
+            push @value, scalar(
+                4 == length($name)
+                    ? $meth->( $me )
+                    : $meth->( $me, $seq, $base )
+            );
+        }
+    }
+    if(  wantarray  ) {
+        return @value;
+    } elsif(  1 == @value  ) {
+        return $value[0];
+    }
+    Die( 0+@value, " values requested from ",
+        $Root, "'s Get in scalar context" );
+}
+
+
+my $Obj= getObjPkg($Root);
+no strict 'refs';
+
+for my $meth (  qw( new getObjPkg )  ) {
+    *{$Root."::".$meth} = \&{$meth};
+    *{$Obj ."::".$meth} = \&{$meth};
+}
+for my $meth (  qw(
+    Next Prev Reset Copy Base Diff
+    Same Items Range Min Max Get
+    _ChkPos _ChkSeq
+)  ) {
+    *{$Obj."::".$meth} = \&{$meth};
+}
+
+1;
+# This version released by Tye McQueen (http://perlmonks.org/?node=tye).
+# 
+# =head1 LICENSE
+# 
+# Parts Copyright (c) 2000-2004 Ned Konz.  All rights reserved.
+# Parts by Tye McQueen.
+# 
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl.
+# 
+# =head1 MAILING LIST
+# 
+# Mark-Jason still maintains a mailing list.  To join a low-volume mailing
+# list for announcements related to diff and Algorithm::Diff, send an
+# empty mail message to mjd-perl-diff-request@plover.com.
+# =head1 CREDITS
+# 
+# Versions through 0.59 (and much of this documentation) were written by:
+# 
+# Mark-Jason Dominus, mjd-perl-diff@plover.com
+# 
+# This version borrows some documentation and routine names from
+# Mark-Jason's, but Diff.pm's code was completely replaced.
+# 
+# This code was adapted from the Smalltalk code of Mario Wolczko
+# <mario@wolczko.com>, which is available at
+# ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
+# 
+# C<sdiff> and C<traverse_balanced> were written by Mike Schilli
+# <m@perlmeister.com>.
+# 
+# The algorithm is that described in
+# I<A Fast Algorithm for Computing Longest Common Subsequences>,
+# CACM, vol.20, no.5, pp.350-353, May 1977, with a few
+# minor improvements to improve the speed.
+# 
+# Much work was done by Ned Konz (perl@bike-nomad.com).
+# 
+# The OO interface and some other changes are by Tye McQueen.
+# 
+EOAlgDiff
+# 2}}}
+    my $problems        = 0;
+    $HAVE_Algorith_Diff = 0;
+    my $dir             = "";
+    if ($opt_sdir) {
+        ++$TEMP_OFF;
+        $dir = "$opt_sdir/$TEMP_OFF";
+        File::Path::rmtree($dir) if     is_dir($dir);
+        File::Path::mkpath($dir) unless is_dir($dir);
+    } else {
+        # let File::Temp create a suitable temporary directory
+        $dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit
+        $TEMP_INST{ $dir } = "Algorithm::Diff";
+    }
+    print "Using temp dir [$dir] to install Algorithm::Diff\n" if $opt_v;
+    my $Algorithm_dir      = "$dir/Algorithm";
+    my $Algorithm_Diff_dir = "$dir/Algorithm/Diff";
+    mkdir $Algorithm_dir     ;
+    mkdir $Algorithm_Diff_dir;
+
+    my $OUT = new IO::File "$dir/Algorithm/Diff.pm", "w";
+    if (defined $OUT) {
+        print $OUT $Algorithm_Diff_Contents;
+        $OUT->close;
+    } else {
+        warn "Failed to install Algorithm/Diff.pm\n";
+        $problems = 1;
+    }
+
+    push @INC, $dir;  # between this & Regexp::Common only need to do once
+    eval "use Algorithm::Diff qw / sdiff /";
+    $HAVE_Algorith_Diff = 1 unless $problems;
+} # 1}}}
+sub call_regexp_common {                     # {{{1
+    my ($ra_lines, $language ) = @_;
+    print "-> call_regexp_common\n" if $opt_v > 2;
+
+    Install_Regexp_Common() unless $HAVE_Rexexp_Common;
+
+    my $all_lines = join("", @{$ra_lines});
+
+    no strict 'vars';
+    # otherwise get:
+    #  Global symbol "%RE" requires explicit package name at cloc line xx.
+    if ($all_lines =~ $RE{comment}{$language}) {
+        # Suppress "Use of uninitialized value in regexp compilation" that
+        # pops up when $1 is undefined--happens if there's a bug in the $RE
+        # This Pascal comment will trigger it:
+        #         (* This is { another } test. **)
+        # Curiously, testing for "defined $1" breaks the substitution.
+        no warnings; 
+        # remove   comments
+        $all_lines =~ s/$1//g;
+    }
+    # a bogus use of %RE to avoid:
+    # Name "main::RE" used only once: possible typo at cloc line xx.
+    print scalar keys %RE if $opt_v < -20;
+#?#print "$all_lines\n";
+    print "<- call_regexp_common\n" if $opt_v > 2;
+    return split("\n", $all_lines);
+} # 1}}}
+sub plural_form {                            # {{{1
+    # For getting the right plural form on some English nouns.
+    my $n = shift @_;
+    if ($n == 1) { return ( 1, "" ); }
+    else         { return ($n, "s"); }
+} # 1}}}
+sub matlab_or_objective_C {                  # {{{1
+    # Decide if code is MATLAB, Objective C, or MUMPS
+    my ($file        , # in
+        $rh_Err      , # in   hash of error codes
+        $raa_errors  , # out
+        $rs_language , # out
+       ) = @_;
+
+    print "-> matlab_or_objective_C\n" if $opt_v > 2;
+    # matlab markers:
+    #   first line starts with "function"
+    #   some lines start with "%"
+    #   high marks for lines that start with [
+    #
+    # Objective C markers:
+    #   must have at least two brace characters, { }
+    #   has /* ... */ style comments
+    #   some lines start with @
+    #   some lines start with #include
+    #
+    # MUMPS:
+    #   has ; comment markers
+    #   do not match:  \w+\s*=\s*\w
+    #   lines begin with   \s*\.?\w+\s+\w
+    #   high marks for lines that start with \s*K\s+ or \s*Kill\s+
+
+    ${$rs_language} = "";
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
+        return;
+    }
+
+    my $DEBUG              = 0;
+
+    my $matlab_points      = 0;
+    my $objective_C_points = 0;
+    my $mumps_points       = 0;
+    my $has_braces         = 0;
+    while (<$IN>) {
+        ++$has_braces if m/[{}]/;
+        ++$mumps_points if $. == 1 and m{^[A-Z]};
+        if      (m{^\s*/\*}) {           #   /*
+            ++$objective_C_points;
+            --$matlab_points;
+printf ".m:  /*     obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{\w+\s*=\s*\[}) {      # matrix assignment, very matlab
+            $matlab_points += 5;
+printf ".m:  \\w=[   obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\s*\w+\s*=\s*}) {    # definitely not MUMPS
+            --$mumps_points;
+printf ".m:  \\w=    obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\s*\.?(\w)\s+(\w)} and $1 !~ /\d/ and $2 !~ /\d/) {
+            ++$mumps_points;
+printf ".m:  \\w \\w  obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\s*;}) {
+            ++$mumps_points;
+printf ".m:  ;      obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\s*#(include|import)}) {
+            # Objective C without a doubt
+            $objective_C_points = 1;
+            $matlab_points      = 0;
+printf ".m: #includ obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+            last;
+        } elsif (m{^\s*@(interface|implementation|protocol|public|protected|private|end)\s}o) {
+            # Objective C without a doubt
+            $objective_C_points = 1;
+            $matlab_points      = 0;
+printf ".m: keyword obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+            last;
+        } elsif (m{^\s*\[}) {             #   line starts with [  -- very matlab
+            $matlab_points += 5;
+printf ".m:  [      obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\sK(ill)?\s+}) {
+            $mumps_points  += 5;
+printf ".m:  Kill   obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\s*function}) {
+            --$objective_C_points;
+            ++$matlab_points;
+printf ".m:  funct  obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        } elsif (m{^\s*%}) {              #   %
+            # matlab commented line
+            --$objective_C_points;
+            ++$matlab_points;
+printf ".m:  pcent  obj C=% 2d  matlab=% 2d  mumps=% 2d\n", $objective_C_points, $matlab_points, $mumps_points if $DEBUG;
+        }
+    }
+    $IN->close;
+
+    print "<- matlab_or_objective_C(matlab=$matlab_points, C=$objective_C_points, mumps=$mumps_points)\n"
+        if $opt_v > 2;
+    $objective_C_points = -9.9e20 unless $has_braces >= 2;
+    if      (($matlab_points > $objective_C_points) and
+             ($matlab_points > $mumps_points)      ) {
+        ${$rs_language} = "MATLAB";
+    } elsif (($mumps_points > $objective_C_points) and
+             ($mumps_points > $matlab_points)      ) {
+        ${$rs_language} = "MUMPS";
+    } else {
+        ${$rs_language} = "Objective C";
+    }
+
+} # 1}}}
+sub Lisp_or_OpenCL {                         # {{{1
+    my ($file        , # in
+        $rh_Err      , # in   hash of error codes
+        $raa_errors  , # out
+       ) = @_;
+
+    print "-> Lisp_or_OpenCL\n" if $opt_v > 2;
+
+    my $lang = undef;
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
+        return $lang;
+    }
+    my $lisp_points   = 0;
+    my $opcl_points = 0;
+    while (<$IN>) {
+        ++$lisp_points if  /^\s*;/;
+        ++$lisp_points if  /\((def|eval|require|export|let|loop|dec|format)/;
+        ++$opcl_points if  /^\s*(int|float|const|{)/;
+    }
+    $IN->close;
+    # print "lisp_points=$lisp_points   opcl_points=$opcl_points\n";
+    if ($lisp_points > $opcl_points) {
+        $lang = "Lisp";
+    } else {
+        $lang = "OpenCL";
+    }
+
+    print "<- Lisp_or_OpenCL\n" if $opt_v > 2;
+    return $lang;
+} # 1}}}
+sub Ant_or_XML {                             # {{{1
+    my ($file        , # in
+        $rh_Err      , # in   hash of error codes
+        $raa_errors  , # out
+       ) = @_;
+
+    print "-> Ant_or_XML($file)\n" if $opt_v > 2;
+
+    my $lang = "XML";
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
+        return $lang;
+    }
+    my $Ant_points   = 0;
+    my $XML_points   = 1;
+    while (<$IN>) {
+        if (/^\s*<project\s+/) {
+            ++$Ant_points  ;
+            --$XML_points  ;
+        }
+        if (/xmlns:artifact="antlib:org.apache.maven.artifact.ant"/) {
+            ++$Ant_points  ;
+            --$XML_points  ;
+        }
+    }
+    $IN->close;
+
+    if ($XML_points >= $Ant_points) {
+        # tie or better goes to XML
+        $lang = "XML";
+    } else {
+        $lang = "Ant";
+    }
+
+    print "<- Ant_or_XML($lang)\n" if $opt_v > 2;
+    return $lang;
+} # 1}}}
+sub Maven_or_XML {                           # {{{1
+    my ($file        , # in
+        $rh_Err      , # in   hash of error codes
+        $raa_errors  , # out
+       ) = @_;
+
+    print "-> Maven_or_XML($file)\n" if $opt_v > 2;
+
+    my $lang = "XML";
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];
+        return $lang;
+    }
+    my $Mvn_points   = 0;
+    my $XML_points   = 1;
+    while (<$IN>) {
+        if (/^\s*<project\s+/) {
+            ++$Mvn_points  ;
+            --$XML_points  ;
+        }
+        if (m{xmlns="http://maven.apache.org/POM/}) {
+            ++$Mvn_points  ;
+            --$XML_points  ;
+        }
+    }
+    $IN->close;
+
+    if ($XML_points >= $Mvn_points) {
+        # tie or better goes to XML
+        $lang = "XML";
+    } else {
+        $lang = "Maven";
+    }
+
+    print "<- Maven_or_XML($lang)\n" if $opt_v > 2;
+    return $lang;
+} # 1}}}
+sub html_colored_text {                      # {{{1
+    # http://www.pagetutor.com/pagetutor/makapage/pics/net216-2.gif
+    my ($color, $text) = @_;
+#?#die "html_colored_text($text)";
+    if      ($color =~ /^red$/i)   {
+        $color = "#ff0000";
+    } elsif ($color =~ /^green$/i) {
+        $color = "#00ff00";
+    } elsif ($color =~ /^blue$/i)  {
+        $color = "#0000ff";
+    } elsif ($color =~ /^grey$/i)  {
+        $color = "#cccccc";
+    }
+#   return "" unless $text;
+    return '<font color="' . $color . '">' . html_metachars($text) . "</font>";
+} # 1}}}
+sub html_metachars {                         # {{{1
+    # Replace HTML metacharacters with their printable forms.
+    # Future:  use HTML-Encoder-0.00_04/lib/HTML/Encoder.pm
+    # from Fabiano Reese Righetti's HTML::Encoder module if 
+    # this subroutine proves to be too simplistic.
+    my ($string, ) = shift @_;
+
+    my  @in_chars    = split(//, $string);
+    my  @out_chars   = ();
+    foreach my $c (@in_chars) {
+        if      ($c eq '<') {
+            push @out_chars, '&lt;'
+        } elsif ($c eq '>') {
+            push @out_chars, '&gt;'
+        } elsif ($c eq '&') {
+            push @out_chars, '&amp;'
+        } else {
+            push @out_chars, $c;
+        }
+    }
+    return join "", @out_chars; 
+} # 1}}}
+sub test_alg_diff {                          # {{{1
+    my ($file_1 ,
+        $file_2 )
+       = @_;
+    my $fh_1 = new IO::File $file_1, "r";
+    die "Unable to read $file_1:  $!\n" unless defined $fh_1;
+    chomp(my @lines_1 = <$fh_1>);
+    $fh_1->close;
+
+    my $fh_2 = new IO::File $file_2, "r";
+    die "Unable to read $file_2:  $!\n" unless defined $fh_2;
+    chomp(my @lines_2 = <$fh_2>);
+    $fh_2->close;
+
+    my $n_no_change = 0;
+    my $n_modified  = 0;
+    my $n_added     = 0;
+    my $n_deleted   = 0;
+    my @min_sdiff   = ();
+my $NN = chr(27) . "[0m";  # normal
+my $BB = chr(27) . "[1m";  # bold
+
+    my @sdiffs = sdiff( \@lines_1, \@lines_2 );
+    foreach my $entry (@sdiffs) {
+        my ($out_1, $out_2) = ('', '');
+        if ($entry->[0] eq 'u') { 
+            ++$n_no_change; 
+          # $out_1 = $entry->[1];
+          # $out_2 = $entry->[2];
+            next; 
+        }
+#       push @min_sdiff, $entry;
+        if      ($entry->[0] eq 'c') { 
+            ++$n_modified;
+            ($out_1, $out_2) = diff_two_strings($entry->[1], $entry->[2]);
+            $out_1 =~ s/\cA(\w)/${BB}$1${NN}/g;
+            $out_2 =~ s/\cA(\w)/${BB}$1${NN}/g;
+          # $out_1 =~ s/\cA//g;
+          # $out_2 =~ s/\cA//g;
+        } elsif ($entry->[0] eq '+') { 
+            ++$n_added;
+            $out_1 = $entry->[1];
+            $out_2 = $entry->[2];
+        } elsif ($entry->[0] eq '-') { 
+            ++$n_deleted;
+            $out_1 = $entry->[1];
+            $out_2 = $entry->[2];
+        } elsif ($entry->[0] eq 'u') { 
+        } else { die "unknown entry->[0]=[$entry->[0]]\n"; }
+        printf "%-80s | %s\n", $out_1, $out_2;
+    }
+
+#   foreach my $entry (@min_sdiff) {
+#       printf "DIFF:  %s  %s  %s\n", @{$entry};
+#   }
+} # 1}}}
+sub write_comments_to_html {                 # {{{1
+    my ($filename      , # in
+        $rah_diff_L    , # in  see routine array_diff() for explanation
+        $rah_diff_R    , # in  see routine array_diff() for explanation
+        $rh_blank      , # in  location and counts of blank lines
+       ) = @_;
+
+    print "-> write_comments_to_html($filename)\n" if $opt_v > 2;
+    my $file = $filename . ".html";
+#use Data::Dumper;
+#print Dumper("rah_diff_L", $rah_diff_L, "rah_diff_R", $rah_diff_R);
+    my $OUT = new IO::File $file, "w";
+    if (!defined $OUT) {
+        warn "Unable to write to $file\n";
+        print "<- write_comments_to_html\n" if $opt_v > 2;
+        return;
+    }
+
+    my $approx_line_count = scalar @{$rah_diff_L};
+    my $n_digits = 1 + int(log($approx_line_count)/2.30258509299405); # log_10
+
+    my $html_out = html_header($filename);
+
+    my $comment_line_number = 0;
+    for (my $i = 0; $i < scalar @{$rah_diff_R}; $i++) {
+        if (defined $rh_blank->{$i}) {
+            foreach (1..$rh_blank->{$i}) {
+                $html_out .= "<!-- blank -->\n";
+            }
+        }
+        my $line_num = "";
+        my $pre      = "";
+        my $post     = '</span> &nbsp;';
+warn "undef rah_diff_R[$i]{type} " unless defined $rah_diff_R->[$i]{type};
+        if ($rah_diff_R->[$i]{type} eq 'nonexist') {
+            ++$comment_line_number;
+            $line_num = sprintf "\&nbsp; <span class=\"clinenum\"> %0${n_digits}d %s",
+                            $comment_line_number, $post;
+            $pre = '<span class="comment">';
+            $html_out .= $line_num;  
+            $html_out .= $pre .  
+                         html_metachars($rah_diff_L->[$i]{char}) . 
+                         $post . "\n";
+            next;
+        }
+        if      ($rah_diff_R->[$i]{type} eq 'code' and
+                 $rah_diff_R->[$i]{desc} eq 'same') {
+            # entire line remains as-is
+            $line_num = sprintf "\&nbsp; <span class=\"linenum\"> %0${n_digits}d %s",
+                            $rah_diff_R->[$i]{lnum}, $post;
+            $pre    = '<span class="normal">';
+            $html_out .= $line_num;  
+            $html_out .= $pre . 
+                         html_metachars($rah_diff_R->[$i]{char}) . $post;
+#XX     } elsif ($rah_diff_R->[$i]{type} eq 'code') { # code+comments
+#XX
+#XX         $line_num = '<span class="linenum">' .
+#XX                      $rah_diff_R->[$i]{lnum} . $post;
+#XX         $html_out .= $line_num;  
+#XX
+#XX         my @strings = @{$rah_diff_R->[$i]{char}{strings}}; 
+#XX         my @type    = @{$rah_diff_R->[$i]{char}{type}}; 
+#XX         for (my $i = 0; $i < scalar @strings; $i++) {
+#XX             if ($type[$i] eq 'u') {
+#XX                 $pre = '<span class="normal">';
+#XX             } else {
+#XX                 $pre = '<span class="comment">';
+#XX             }
+#XX             $html_out .= $pre .  html_metachars($strings[$i]) . $post;
+#XX         }
+# print Dumper(@strings, @type); die;
+
+        } elsif ($rah_diff_R->[$i]{type} eq 'comment') {
+            $line_num = '<span class="clinenum">' . $comment_line_number . $post;
+            # entire line is a comment
+            $pre    = '<span class="comment">';
+            $html_out .= $pre .
+                         html_metachars($rah_diff_R->[$i]{char}) . $post;
+        }
+#printf "%-30s %s %-30s\n", $line_1, $separator, $line_2;
+        $html_out .= "\n";
+    }
+
+    $html_out .= html_end();
+
+    my $out_file = "$filename.html";
+    open  OUT, ">$out_file" or die "Cannot write to $out_file $!\n";
+    print OUT $html_out;
+    close OUT;
+    print "Wrote $out_file\n" unless $opt_quiet;
+    $OUT->close;
+
+    print "<- write_comments_to_html\n" if $opt_v > 2;
+} # 1}}}
+sub array_diff {                             # {{{1
+    my ($file          , # in  only used for error reporting
+        $ra_lines_L    , # in  array of lines in Left  file (no blank lines)
+        $ra_lines_R    , # in  array of lines in Right file (no blank lines)
+        $mode          , # in  "comment" | "revision"
+        $rah_diff_L    , # out
+        $rah_diff_R    , # out
+        $raa_Errors    , # in/out
+       ) = @_;
+
+    # This routine operates in two ways:
+    # A. Computes diffs of the same file with and without comments.
+    #    This is used to classify lines as code, comments, or blank.
+    # B. Computes diffs of two revisions of a file.  This method
+    #    requires a prior run of method A using the older version
+    #    of the file because it needs lines to be classified.
+
+    # $rah_diff structure:
+    # An array with n entries where n equals the number of lines in 
+    # an sdiff of the two files.  Each entry in the array describes
+    # the contents of the corresponding line in file Left and file Right:
+    #  diff[]{type} = blank | code | code+comment | comment | nonexist
+    #        {lnum} = line number within the original file (1-based)
+    #        {desc} = same | added | removed | modified
+    #        {char} = the input line unless {desc} = 'modified' in
+    #                 which case
+    #        {char}{strings} = [ substrings ]
+    #        {char}{type}    = [ disposition (added, removed, etc)]
+    #
+
+    @{$rah_diff_L} = ();
+    @{$rah_diff_R} = ();
+
+    print "-> array_diff()\n" if $opt_v > 2;
+    my $COMMENT_MODE = 0;
+       $COMMENT_MODE = 1 if $mode eq "comment";
+
+#print "array_diff(mode=$mode)\n";
+#print Dumper("block left:" , $ra_lines_L);
+#print Dumper("block right:", $ra_lines_R);
+
+    my @sdiffs = ();
+    eval {
+        local $SIG{ALRM} = sub { die "alarm\n" };
+        alarm $opt_diff_timeout;
+        @sdiffs = sdiff($ra_lines_L, $ra_lines_R);
+        alarm 0;
+    };
+    if ($@) {
+        # timed out
+        die unless $@ eq "alarm\n"; # propagate unexpected errors
+        push @{$raa_Errors}, 
+             [ $Error_Codes{'Diff error, exceeded timeout'}, $file ];
+        if ($opt_v) {
+          warn "array_diff: diff timeout failure for $file--ignoring\n";
+        }
+        return;
+    }
+
+#use Data::Dumper::Simple;
+#print Dumper($ra_lines_L, $ra_lines_R, @sdiffs);
+#die;
+
+    my $n_L        = 0;
+    my $n_R        = 0;
+    my $n_sdiff    = 0;  # index to $rah_diff_L, $rah_diff_R
+    foreach my $triple (@sdiffs) {
+        my $flag   = $triple->[0];
+        my $line_L = $triple->[1];
+        my $line_R = $triple->[2];
+        $rah_diff_L->[$n_sdiff]{char} = $line_L;
+        $rah_diff_R->[$n_sdiff]{char} = $line_R;
+        if      ($flag eq 'u') {  # u = unchanged
+            ++$n_L;
+            ++$n_R;
+            if ($COMMENT_MODE) {
+                # line exists in both with & without comments, must be code
+                $rah_diff_L->[$n_sdiff]{type} = "code";
+                $rah_diff_R->[$n_sdiff]{type} = "code";
+            }
+            $rah_diff_L->[$n_sdiff]{desc} = "same";
+            $rah_diff_R->[$n_sdiff]{desc} = "same";
+            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;
+            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;
+        } elsif ($flag eq 'c') {  # c = changed
+# warn "per line sdiff() commented out\n"; if (0) {
+            ++$n_L;
+            ++$n_R;
+
+            if ($COMMENT_MODE) {
+                # line has text both with & without comments;
+                # count as code
+                $rah_diff_L->[$n_sdiff]{type} = "code";
+                $rah_diff_R->[$n_sdiff]{type} = "code";
+            }
+
+            my @chars_L = split '', $line_L;
+            my @chars_R = split '', $line_R;
+
+#XX         my @inline_sdiffs = sdiff( \@chars_L, \@chars_R );
+
+#use Data::Dumper::Simple; 
+#if ($n_R == 6 or $n_R == 1 or $n_R == 2) {
+#print "L=[$line_L]\n";
+#print "R=[$line_R]\n";
+#print Dumper(@chars_L, @chars_R, @inline_sdiffs);
+#}
+#XX         my @index = ();
+#XX         foreach my $il_triple (@inline_sdiffs) {
+#XX             # make an array of u|c|+|- corresponding
+#XX             # to each character
+#XX             push @index, $il_triple->[0];
+#XX         }
+#XX#print Dumper(@index); die;
+#XX          # expect problems if arrays @index and $inline_sdiffs[1];
+#XX          # (@{$inline_sdiffs->[1]} are the characters of line_L)
+#XX          # aren't the same length
+#XX          my $prev_type = $index[0];
+#XX          my @strings   = ();  # blocks of consecutive code or comment
+#XX          my @type      = ();  # u (=code) or c (=comment)
+#XX          my $j_str     = 0;
+#XX          $strings[$j_str] .= $chars_L[0];
+#XX          $type[$j_str] = $prev_type;
+#XX          for (my $i = 1; $i < scalar @chars_L; $i++) {
+#XX              if ($index[$i] ne $prev_type) {
+#XX                  ++$j_str;
+#XX#print "change at j_str=$j_str type=$index[$i]\n";
+#XX                  $type[$j_str] = $index[$i];
+#XX                  $prev_type    = $index[$i];
+#XX              }
+#XX              $strings[$j_str] .= $chars_L[$i];
+#XX          }
+# print Dumper(@strings, @type); die;
+#XX         delete $rah_diff_R->[$n_sdiff]{char};
+#XX         @{$rah_diff_R->[$n_sdiff]{char}{strings}} = @strings;
+#XX         @{$rah_diff_R->[$n_sdiff]{char}{type}}    = @type;
+            $rah_diff_L->[$n_sdiff]{desc} = "modified";
+            $rah_diff_R->[$n_sdiff]{desc} = "modified";
+            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;
+            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;
+#}
+
+        } elsif ($flag eq '+') {  # + = added
+            ++$n_R;
+            if ($COMMENT_MODE) {
+                # should never get here
+                @{$rah_diff_L} = ();
+                @{$rah_diff_R} = ();
+                push @{$raa_Errors}, 
+                     [ $Error_Codes{'Diff error (quoted comments?)'}, $file ];
+                if ($opt_v) {
+                  warn "array_diff: diff failure (diff says the\n";
+                  warn "comment-free file has added lines).\n";
+                  warn "$n_sdiff  $line_L\n";
+                }
+                last;
+            }
+            $rah_diff_L->[$n_sdiff]{type} = "nonexist";
+            $rah_diff_L->[$n_sdiff]{desc} = "removed";
+            $rah_diff_R->[$n_sdiff]{desc} = "added";
+            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;
+        } elsif ($flag eq '-') {  # - = removed
+            ++$n_L;
+            if ($COMMENT_MODE) {
+                # line must be comment because blanks already gone
+                $rah_diff_L->[$n_sdiff]{type} = "comment";
+            }
+            $rah_diff_R->[$n_sdiff]{type} = "nonexist";
+            $rah_diff_R->[$n_sdiff]{desc} = "removed";
+            $rah_diff_L->[$n_sdiff]{desc} = "added";
+            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;
+        }
+#printf "%-30s %s %-30s\n", $line_L, $separator, $line_R;
+        ++$n_sdiff;
+    }
+#use Data::Dumper::Simple;
+#print Dumper($rah_diff_L, $rah_diff_R);
+
+    print "<- array_diff\n" if $opt_v > 2;
+} # 1}}}
+sub remove_leading_dir {                     # {{{1 
+    my @filenames = @_;
+    #
+    #  Input should be a list of file names
+    #  with the same leading directory such as
+    # 
+    #      dir1/dir2/a.txt
+    #      dir1/dir2/b.txt
+    #      dir1/dir2/dir3/c.txt
+    #
+    #  Output is the same list minus the common
+    #  directory path:
+    # 
+    #      a.txt
+    #      b.txt
+    #      dir3/c.txt
+    #
+    print "-> remove_leading_dir()\n" if $opt_v > 2;
+    my @D = (); # a matrix:   [ [ dir1, dir2 ],         # dir1/dir2/a.txt
+                #               [ dir1, dir2 ],         # dir1/dir2/b.txt
+                #               [ dir1, dir2 , dir3] ]  # dir1/dir2/dir3/c.txt
+    if ($ON_WINDOWS) {
+        foreach my $F (@filenames) {
+            $F =~ s{\\}{/}g;
+            $F = ucfirst($F) if $F =~ /^\w:/;  # uppercase drive letter
+        }
+    }
+    if (scalar @filenames == 1) {
+        # special case:  with only one filename
+        # cannot determine a baseline, just remove first directory level
+        $filenames[0] =~ s{^.*?/}{};
+        print "-> $filenames[0]\n";
+        return $filenames[0];
+    }
+    foreach my $F (@filenames) {
+        my ($Vol, $Dir, $File) = File::Spec->splitpath($F);
+        my @x = File::Spec->splitdir( $Dir );
+        pop @x unless $x[$#x]; # last entry usually null, remove it
+        if ($ON_WINDOWS) {
+            if (defined($Vol) and $Vol) {
+                # put the drive letter, eg, C:, at the front
+                unshift @x, uc $Vol;
+            }
+        }
+#print "F=$F, Dir=$Dir  x=[", join("][", @x), "]\n";
+        push @D, [ @x ];
+    }
+
+    # now loop over columns until either they are all
+    # eliminated or a unique column is found
+
+#use Data::Dumper::Simple;
+#print Dumper("remove_leading_dir after ", @D);
+
+    my @common   = ();  # to contain the common leading directories
+    my $mismatch = 0;
+    while (!$mismatch) {
+        for (my $row = 1; $row < scalar @D; $row++) {
+#print "comparing $D[$row][0] to $D[0][0]\n";
+
+            if (!defined $D[$row][0] or !defined $D[0][0] or
+                ($D[$row][0] ne $D[0][0])) {
+                $mismatch = 1;
+                last;
+            }
+        }
+#print "mismatch=$mismatch\n";
+        if (!$mismatch) {
+            push @common, $D[0][0];
+            # all terms in the leading match; unshift the batch
+            foreach my $ra (@D) {
+                shift @{$ra};
+            }
+        }
+    }
+
+    push @common, " ";  # so that $leading will end with "/ "
+    my $leading = File::Spec->catdir( @common );
+       $leading =~ s{ $}{};  # now take back the bogus appended space
+#print "remove_leading_dir leading=[$leading]\n"; die;
+    if ($ON_WINDOWS) {
+       $leading =~ s{\\}{/}g;
+    }
+    foreach my $F (@filenames) {
+        $F =~ s{^$leading}{};
+    }
+
+    print "<- remove_leading_dir()\n" if $opt_v > 2;
+    return @filenames;
+
+} # 1}}}
+sub align_by_pairs {                         # {{{1 
+    my ($rh_file_list_L        , # in
+        $rh_file_list_R        , # in
+        $ra_added              , # out
+        $ra_removed            , # out
+        $ra_compare_list       , # out
+        ) = @_;
+    print "-> align_by_pairs()\n" if $opt_v > 2;
+    @{$ra_compare_list} = ();
+
+    my @files_L = sort keys %{$rh_file_list_L};
+    my @files_R = sort keys %{$rh_file_list_R};
+    return () unless @files_L or  @files_R;  # at least one must have stuff
+    if      ( @files_L and !@files_R) {
+        # left side has stuff, right side is empty; everything deleted
+        @{$ra_added   }     = ();
+        @{$ra_removed }     = @files_L;
+        @{$ra_compare_list} = ();
+        return;
+    } elsif (!@files_L and  @files_R) {
+        # left side is empty, right side has stuff; everything added
+        @{$ra_added   }     = @files_R;
+        @{$ra_removed }     = ();
+        @{$ra_compare_list} = ();
+        return;
+    }
+#use Data::Dumper::Simple;
+#print Dumper("align_by_pairs", @files_L, @files_R);
+#die;
+    if (scalar @files_L == 1 and scalar @files_R == 1) {
+        # The easy case:  compare two files.
+        push @{$ra_compare_list}, [ $files_L[0],  $files_R[0] ]; 
+        @{$ra_added  } = ();
+        @{$ra_removed} = ();
+        return;
+    }
+    # The harder case:  compare groups of files.  This only works
+    # if the groups are in different directories so the first step
+    # is to strip the leading directory names from file lists to
+    # make it possible to align by file names.
+    my @files_L_minus_dir = remove_leading_dir(@files_L);
+    my @files_R_minus_dir = remove_leading_dir(@files_R);
+
+    # Keys of the stripped_X arrays are canonical file names;
+    # should overlap mostly.  Keys in stripped_L but not in
+    # stripped_R are files that have been deleted.  Keys in
+    # stripped_R but not in stripped_L have been added.
+    my %stripped_L = ();
+       @stripped_L{ @files_L_minus_dir } = @files_L;
+    my %stripped_R = ();
+       @stripped_R{ @files_R_minus_dir } = @files_R;
+
+    my %common = ();
+    foreach my $f (keys %stripped_L) {
+        $common{$f}  = 1 if     defined $stripped_R{$f};
+    }
+
+    my %deleted = ();
+    foreach my $f (keys %stripped_L) {
+        $deleted{$stripped_L{$f}} = $f unless defined $stripped_R{$f};
+    }
+
+    my %added = ();
+    foreach my $f (keys %stripped_R) {
+        $added{$stripped_R{$f}}   = $f unless defined $stripped_L{$f};
+    }
+
+#use Data::Dumper::Simple;
+#print Dumper("align_by_pairs", %stripped_L, %stripped_R);
+#print Dumper("align_by_pairs", %common, %added, %deleted);
+    
+    foreach my $f (keys %common) {
+        push @{$ra_compare_list}, [ $stripped_L{$f},  
+                                    $stripped_R{$f} ]; 
+    }
+    @{$ra_added   } = keys %added  ;
+    @{$ra_removed } = keys %deleted;
+
+    print "<- align_by_pairs()\n" if $opt_v > 2;
+    return;
+#print Dumper("align_by_pairs", @files_L_minus_dir, @files_R_minus_dir);
+#die;
+} # 1}}}
+sub html_header {                            # {{{1
+    my ($title , ) = @_;
+
+    print "-> html_header\n" if $opt_v > 2;
+    return 
+'<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="GENERATOR" content="cloc http://cloc.sourceforge.net">
+' .
+"
+<!-- Created by $script v$VERSION -->
+<title>$title</title>
+" .
+'
+<style TYPE="text/css">
+<!--
+    body {
+        color: black;
+        background-color: white;
+        font-family: monospace
+    }
+
+    .whitespace {
+        background-color: gray;
+    }
+
+    .comment {
+        color: gray;
+        font-style: italic;
+    }
+
+    .clinenum {
+        color: red;
+    }
+
+    .linenum {
+        color: green;
+    }
+ -->
+</style>
+</head>
+<body>
+<pre><tt>
+';
+    print "<- html_header\n" if $opt_v > 2;
+} # 1}}}
+sub html_end {                               # {{{1
+return 
+'</tt></pre>
+</body>
+</html>
+';
+} # 1}}}
+sub die_unknown_lang {                       # {{{1
+    my ($lang, $option_name) = @_;
+    die "Unknown language '$lang' used with $option_name option.  " .
+        "The command\n  $script --show-lang\n" .
+        "will print all recognized languages.  Language names are " .
+        "case sensitive.\n" ;
+} # 1}}}
+sub unicode_file {                           # {{{1
+    my $file = shift @_; 
+
+    print "-> unicode_file($file)\n" if $opt_v > 2;
+    return 0 if (-s $file > 2_000_000);  
+    # don't bother trying to test binary files bigger than 2 MB
+
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        warn "Unable to read $file; ignoring.\n";
+        return 0;
+    }
+    my @lines = <$IN>;
+    $IN->close;
+
+    if (unicode_to_ascii( join('', @lines) )) {
+        print "<- unicode_file()\n" if $opt_v > 2;
+        return 1;
+    } else {
+        print "<- unicode_file()\n" if $opt_v > 2;
+        return 0;
+    }
+
+} # 1}}}
+sub unicode_to_ascii {                       # {{{1
+    my $string = shift @_; 
+
+    # A trivial attempt to convert UTF-16 little or big endian
+    # files into ASCII.  These files exhibit the following byte
+    # sequence:
+    #   byte   1:  255
+    #   byte   2:  254
+    #   byte   3:  ord of ASCII character
+    #   byte   4:    0
+    #   byte 3+i:  ord of ASCII character
+    #   byte 4+i:    0
+    # or
+    #   byte   1:  255
+    #   byte   2:  254
+    #   byte   3:    0
+    #   byte   4:  ord of ASCII character
+    #   byte 3+i:    0
+    #   byte 4+i:  ord of ASCII character
+
+    my $length  = length $string;
+#print "length=$length\n";
+    return '' if $length <= 3;
+    my @unicode = split(//, $string);
+
+    # check the first 100 characters for big or little endian UTF-16 encoding
+    my $max_peek = $length < 200 ? $length : 200;
+    my @view_1   = ();
+    for (my $i = 2; $i < $max_peek; $i += 2) { push @view_1, $unicode[$i] }
+    my @view_2   = ();
+    for (my $i = 3; $i < $max_peek; $i += 2) { push @view_2, $unicode[$i] }
+
+    my $points_1 = 0;
+    foreach my $C (@view_1) {
+        ++$points_1 if (32 <= ord($C) and ord($C) <= 127) or ord($C) == 13
+                                                          or ord($C) == 10
+                                                          or ord($C) ==  9;
+    }
+
+    my $points_2 = 0;
+    foreach my $C (@view_2) {
+        ++$points_2 if (32 <= ord($C) and ord($C) <= 127) or ord($C) == 13
+                                                          or ord($C) == 10
+                                                          or ord($C) ==  9;
+    }
+#print "points 1: $points_1\n";
+#print "points 2: $points_2\n";
+
+    my $offset = undef;
+    if    ($points_1 > 90) { $offset = 2; }
+    elsif ($points_2 > 90) { $offset = 3; }
+    else                   { return '' }  # neither big or little endian UTF-16
+
+    my @ascii              = ();
+    for (my $i = $offset; $i < $length; $i += 2) { push @ascii, $unicode[$i]; }
+    return join("", @ascii);
+} # 1}}}
+sub uncompress_archive_cmd {                 # {{{1
+    my ($archive_file, ) = @_;
+
+    # Wrap $archive_file in single or double quotes in the system
+    # commands below to avoid filename chicanery (including
+    # spaces in the names).
+
+    print "-> uncompress_archive_cmd($archive_file)\n" if $opt_v > 2;
+    my $extract_cmd = "";
+    my $missing     = "";
+    if ($opt_extract_with) {
+        ( $extract_cmd = $opt_extract_with ) =~ s/>FILE</$archive_file/g;
+    } elsif (basename($archive_file) eq "-" and !$ON_WINDOWS) {
+        $extract_cmd = "cat > -";
+    } elsif (($archive_file =~ /\.tar\.(gz|Z)$/ or 
+              $archive_file =~ /\.tgz$/       ) and !$ON_WINDOWS)    {
+        if (external_utility_exists("gzip --version")) {
+            if (external_utility_exists("tar --version")) {
+                $extract_cmd = "gzip -dc '$archive_file' | tar xf -";
+            } else {
+                $missing = "tar";
+            }
+        } else {
+            $missing = "gzip";
+        }
+    } elsif ($archive_file =~ /\.tar\.bz2$/ and !$ON_WINDOWS)    {
+        if (external_utility_exists("bzip2 --help")) {
+            if (external_utility_exists("tar --version")) {
+                $extract_cmd = "bzip2 -dc '$archive_file' | tar xf -";
+            } else {
+                $missing = "tar";
+            }
+        } else {
+            $missing = "bzip2";
+        }
+    } elsif ($archive_file =~ /\.tar\.xz$/ and !$ON_WINDOWS)    {
+        if (external_utility_exists("unxz --version")) {
+            if (external_utility_exists("tar --version")) {
+                $extract_cmd = "unxz -dc '$archive_file' | tar xf -";
+            } else {
+                $missing = "tar";
+            }
+        } else {
+            $missing = "bzip2";
+        }
+    } elsif ($archive_file =~ /\.tar$/ and !$ON_WINDOWS)    {
+        $extract_cmd = "tar xf '$archive_file'";
+    } elsif ($archive_file =~ /\.src\.rpm$/i and !$ON_WINDOWS) {
+        if (external_utility_exists("cpio --version")) {
+            if (external_utility_exists("rpm2cpio")) {
+                $extract_cmd = "rpm2cpio '$archive_file' | cpio -i";
+            } else {
+                $missing = "rpm2cpio";
+            }
+        } else {
+            $missing = "bzip2";
+        }
+    } elsif ($archive_file =~ /\.zip$/i and !$ON_WINDOWS)    {
+        if (external_utility_exists("unzip")) {
+            $extract_cmd = "unzip -qq -d . '$archive_file'";
+        } else {
+            $missing = "unzip";
+        }
+    } elsif ($ON_WINDOWS and $archive_file =~ /\.zip$/i) {
+        # zip on Windows, guess default Winzip install location
+        $extract_cmd = "";
+        my $WinZip = '"C:\\Program Files\\WinZip\\WinZip32.exe"';
+        if (external_utility_exists($WinZip)) {
+            $extract_cmd = "$WinZip -e -o \"$archive_file\" .";
+#print "trace 5 extract_cmd=[$extract_cmd]\n";
+        } else {
+#print "trace 6\n";
+            $missing = $WinZip;
+        }
+    }
+    print "<- uncompress_archive_cmd\n" if $opt_v > 2;
+    if ($missing) {
+        die "Unable to expand $archive_file because external\n",
+            "utility '$missing' is not available.\n",
+            "Another possibility is to use the --extract-with option.\n";
+    } else {
+        return $extract_cmd;
+    }
+}
+# 1}}}
+sub read_list_file {                         # {{{1
+    my ($file, ) = @_;
+
+    print "-> read_list_file($file)\n" if $opt_v > 2;
+    my $IN = new IO::File $file, "r";
+    if (!defined $IN) {
+        warn "Unable to read $file; ignoring.\n";
+        next;
+    }
+    my @entry = ();
+    while (<$IN>) {
+        next if /^\s*$/ or /^\s*#/; # skip empty or commented lines
+        chomp;
+        push @entry, $_;
+    }
+    $IN->close;
+
+    print "<- read_list_file\n" if $opt_v > 2;
+    return @entry;
+}
+# 1}}}
+sub external_utility_exists {                # {{{1
+    my $exe = shift @_;
+
+    my $success      = 0;
+    if ($ON_WINDOWS) {
+        $success = 1 unless system $exe . ' > nul';
+    } else {
+        $success = 1 unless system $exe . ' >/dev/null 2>&1';
+        if (!$success) {
+            $success = 1 unless system "which" . " $exe" . ' >/dev/null 2>&1';
+        }
+    }
+    
+    return $success;
+} # 1}}}
+sub write_xsl_file {                         # {{{1
+    my $OUT = new IO::File $CLOC_XSL, "w";
+    if (!defined $OUT) {
+        warn "Unable to write $CLOC_XSL  $!\n";
+        return;
+    }
+    my $XSL =             # <style>  </style> {{{2
+'<?xml version="1.0" encoding="US-ASCII"?>
+<!-- XLS file by Paul Schwann, January 2009.
+     Fixes for by-file and by-file-by-lang by d_uragan, November 2010.
+     -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:output method="html"/>
+  <xsl:template match="/">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+      <head>
+        <title>CLOC Results</title>
+      </head>
+      <style type="text/css">
+        table {
+          table-layout: auto;
+          border-collapse: collapse;
+          empty-cells: show;
+        }
+        td, th {
+          padding: 4px;
+        }
+        th {
+          background-color: #CCCCCC;
+        }
+        td {
+          text-align: center;
+        }
+        table, td, tr, th {
+          border: thin solid #999999;
+        }
+      </style>
+      <body>
+        <h3><xsl:value-of select="results/header"/></h3>
+';
+# 2}}}
+
+    if ($opt_by_file) {
+        $XSL .=             # <table> </table>{{{2
+'        <table>
+          <thead>
+            <tr>
+              <th>File</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>
+              <th>Language</th>
+';
+        $XSL .=
+'             <th>3<sup>rd</sup> Generation Equivalent</th>
+              <th>Scale</th>
+' if $opt_3;
+        $XSL .=
+'           </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="results/files/file">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>
+              <td><xsl:value-of select="@language"/></td>
+';
+        $XSL .=
+'             <td><xsl:value-of select="@factor"/></td>
+              <td><xsl:value-of select="@scaled"/></td>
+' if $opt_3;
+        $XSL .=
+'           </tr>
+          </xsl:for-each>
+            <tr>
+              <th>Total</th>
+              <th><xsl:value-of select="results/files/total/@blank"/></th>
+              <th><xsl:value-of select="results/files/total/@comment"/></th>
+              <th><xsl:value-of select="results/files/total/@code"/></th>
+              <th><xsl:value-of select="results/files/total/@language"/></th>
+';
+        $XSL .=
+'             <th><xsl:value-of select="results/files/total/@factor"/></th>
+              <th><xsl:value-of select="results/files/total/@scaled"/></th>
+' if $opt_3;
+        $XSL .=
+'           </tr>
+          </tbody>
+        </table>
+        <br/>
+';
+# 2}}}
+    }
+
+    if (!$opt_by_file or $opt_by_file_by_lang) {
+        $XSL .=             # <table> </table> {{{2
+'       <table>
+          <thead>
+            <tr>
+              <th>Language</th>
+              <th>Files</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>
+';
+        $XSL .=
+'             <th>Scale</th>
+              <th>3<sup>rd</sup> Generation Equivalent</th>
+' if $opt_3;
+        $XSL .=
+'           </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="results/languages/language">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@files_count"/></td>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>
+';
+        $XSL .=
+'             <td><xsl:value-of select="@factor"/></td>
+              <td><xsl:value-of select="@scaled"/></td>
+' if $opt_3;
+        $XSL .=
+'          </tr>
+          </xsl:for-each>
+            <tr>
+              <th>Total</th>
+              <th><xsl:value-of select="results/languages/total/@sum_files"/></th>
+              <th><xsl:value-of select="results/languages/total/@blank"/></th>
+              <th><xsl:value-of select="results/languages/total/@comment"/></th>
+              <th><xsl:value-of select="results/languages/total/@code"/></th>
+';
+        $XSL .=
+'             <th><xsl:value-of select="results/languages/total/@factor"/></th>
+              <th><xsl:value-of select="results/languages/total/@scaled"/></th>
+' if $opt_3;
+        $XSL .=
+'           </tr>
+          </tbody>
+        </table>
+';
+# 2}}}
+    }
+
+    $XSL.= <<'EO_XSL'; # {{{2
+      </body>
+    </html>
+  </xsl:template>
+</xsl:stylesheet>
+
+EO_XSL
+# 2}}}
+
+    my $XSL_DIFF = <<'EO_DIFF_XSL'; # {{{2
+<?xml version="1.0" encoding="US-ASCII"?>
+<!-- XLS file by Blazej Kroll, November 2010 -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:output method="html"/>
+  <xsl:template match="/">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+      <head>
+        <title>CLOC Results</title>
+      </head>
+      <style type="text/css">
+        table {
+          table-layout: auto;
+          border-collapse: collapse;
+          empty-cells: show;
+		  margin: 1em;
+        }
+        td, th {
+          padding: 4px;
+        }
+        th {
+          background-color: #CCCCCC;
+        }
+        td {
+          text-align: center;
+        }
+        table, td, tr, th {
+          border: thin solid #999999;
+        }
+      </style>
+      <body>
+        <h3><xsl:value-of select="results/header"/></h3>
+EO_DIFF_XSL
+# 2}}}
+
+    if ($opt_by_file) {
+        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2
+		<table>
+          <thead>
+		  <tr><th colspan="4">Same</th>
+		  </tr>
+            <tr>
+              <th>File</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/same/file">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+		
+		<table>
+          <thead>
+		  <tr><th colspan="4">Modified</th>
+		  </tr>
+            <tr>
+              <th>File</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/modified/file">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+		
+		<table>
+          <thead>
+		  <tr><th colspan="4">Added</th>
+		  </tr>
+            <tr>
+              <th>File</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/added/file">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+		
+		<table>
+          <thead>
+		  <tr><th colspan="4">Removed</th>
+		  </tr>
+            <tr>
+              <th>File</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/removed/file">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+EO_DIFF_XSL
+# 2}}}
+    }
+
+    if (!$opt_by_file or $opt_by_file_by_lang) {
+        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2
+		<table>
+          <thead>
+		  <tr><th colspan="5">Same</th>
+		  </tr>
+            <tr>
+              <th>Language</th>
+              <th>Files</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/same/language">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@files_count"/></td>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+		
+		<table>
+          <thead>
+		  <tr><th colspan="5">Modified</th>
+		  </tr>
+            <tr>
+              <th>Language</th>
+              <th>Files</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/modified/language">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@files_count"/></td>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+		
+		<table>
+          <thead>
+		  <tr><th colspan="5">Added</th>
+		  </tr>
+            <tr>
+              <th>Language</th>
+              <th>Files</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/added/language">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@files_count"/></td>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+		
+		<table>
+          <thead>
+		  <tr><th colspan="5">Removed</th>
+		  </tr>
+            <tr>
+              <th>Language</th>
+              <th>Files</th>
+              <th>Blank</th>
+              <th>Comment</th>
+              <th>Code</th>              
+            </tr>
+          </thead>
+          <tbody>
+          <xsl:for-each select="diff_results/removed/language">
+            <tr>
+              <th><xsl:value-of select="@name"/></th>
+              <td><xsl:value-of select="@files_count"/></td>
+              <td><xsl:value-of select="@blank"/></td>
+              <td><xsl:value-of select="@comment"/></td>
+              <td><xsl:value-of select="@code"/></td>              
+            </tr>
+          </xsl:for-each>            
+          </tbody>
+        </table>
+EO_DIFF_XSL
+# 2}}}
+
+    }
+    
+    $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2
+      </body>
+    </html>
+  </xsl:template>
+</xsl:stylesheet>
+EO_DIFF_XSL
+# 2}}}
+    if ($opt_diff) {
+        print $OUT $XSL_DIFF;
+    } else {
+        print $OUT $XSL;
+    }
+    $OUT->close();
+} # 1}}}
+sub normalize_file_names {                   # {{{1 
+    my (@files, ) = @_;
+
+    # Returns a hash of file names reduced to a canonical form
+    # (fully qualified file names, all path separators changed to /,
+    # Windows file names lowercased).  Hash values are the original
+    # file name.
+
+    my %normalized = ();
+    foreach my $F (@files) {
+        my $F_norm = $F;
+        if ($ON_WINDOWS) {
+            $F_norm = lc $F_norm; # for case insensitive file name comparisons
+            $F_norm =~ s{\\}{/}g; # Windows directory separators to Unix
+            $F_norm =~ s{^\./}{}g;  # remove leading ./
+            if (($F_norm !~ m{^/}) and ($F_norm !~ m{^\w:/})) {
+                # looks like a relative path; prefix with cwd
+                $F_norm = lc "$cwd/$F_norm";
+            }
+        } else {
+            $F_norm =~ s{^\./}{}g;  # remove leading ./
+            if ($F_norm !~ m{^/}) {
+                # looks like a relative path; prefix with cwd
+                $F_norm = lc "$cwd/$F_norm";
+            }
+        }
+        $normalized{ $F_norm } = $F;
+    }
+    return %normalized;
+} # 1}}}
+sub combine_diffs {                          # {{{1
+    # subroutine by Andy (awalshe@sf.net)
+    # https://sourceforge.net/tracker/?func=detail&aid=3261017&group_id=174787&atid=870625
+    my ($ra_files) = @_;
+
+    my $res   = "$URL v $VERSION\n";
+    my $dl    = '-';
+    my $width = 79;
+    # columns are in this order
+    my @cols  = ('files', 'blank', 'comment', 'code');
+    my %HoH   = ();
+  
+    foreach my $file (@{$ra_files}) {
+        my $IN = new IO::File $file, "r";
+        if (!defined $IN) {
+            warn "Unable to read $file; ignoring.\n";
+            next;
+        }
+
+        my $sec;
+        while (<$IN>) {
+            next if /^(http|Language|-----)/;
+            if (/^[A-Za-z0-9]+/) {        # section title
+                $sec = $_;
+                chomp($sec);
+                $HoH{$sec} = () if ! exists $HoH{$sec};
+                next;
+            }
+  
+            if (/^\s(same|modified|added|removed)/) {  # calculated totals row
+                my @ar = grep { $_ ne '' } split(/ /, $_);
+                chomp(@ar);
+                my $ttl = shift @ar;
+                my $i = 0;
+                foreach(@ar) {
+                    my $t = "$ttl$dl$cols[$i]";
+                    $HoH{$sec}{$t} = 0 if ! exists $HoH{$sec}{$t};
+                    $HoH{$sec}{$t} += $_;
+                    $i++;
+                }
+            }
+        }
+        $IN->close;
+    }
+
+    # rows are in this order
+    my @rows = ('same', 'modified', 'added', 'removed');
+  
+    $res .= sprintf("%s\n", "-" x $width);
+    $res .= sprintf("%-19s %14s %14s %14s %14s\n", 'Language', 
+                    $cols[0], $cols[1], $cols[2], $cols[3]);
+    $res .= sprintf("%s\n", "-" x $width);
+  
+    for my $sec ( keys %HoH ) {
+        next if $sec =~ /SUM:/;
+        $res .= "$sec\n";
+        foreach (@rows) {
+            $res .= sprintf(" %-18s %14s %14s %14s %14s\n", 
+                            $_, $HoH{$sec}{"$_$dl$cols[0]"},
+                                $HoH{$sec}{"$_$dl$cols[1]"},
+                                $HoH{$sec}{"$_$dl$cols[2]"},
+                                $HoH{$sec}{"$_$dl$cols[3]"});
+        }
+    }
+    $res .= sprintf("%s\n", "-" x $width);
+    my $sec = 'SUM:';
+    $res .= "$sec\n";
+    foreach (@rows) {
+        $res .= sprintf(" %-18s %14s %14s %14s %14s\n", 
+                        $_, $HoH{$sec}{"$_$dl$cols[0]"},
+                            $HoH{$sec}{"$_$dl$cols[1]"},
+                            $HoH{$sec}{"$_$dl$cols[2]"},
+                            $HoH{$sec}{"$_$dl$cols[3]"});
+    }
+    $res .= sprintf("%s\n", "-" x $width);
+  
+    return $res;
+} # 1}}}
+sub get_time {                               # {{{1
+    if ($HAVE_Time_HiRes) {
+        return Time::HiRes::time();
+    } else {
+        return time();
+    }
+} # 1}}}
+# subroutines copied from SLOCCount
+my %lex_files    = ();  # really_is_lex()
+my %expect_files = ();  # really_is_expect()
+my %php_files    = ();  # really_is_php()
+sub really_is_lex {                          # {{{1
+# Given filename, returns TRUE if its contents really is lex.
+# lex file must have "%%", "%{", and "%}".
+# In theory, a lex file doesn't need "%{" and "%}", but in practice
+# they all have them, and requiring them avoid mislabeling a
+# non-lexfile as a lex file.
+
+ my $filename = shift;
+ chomp($filename);
+
+ my $is_lex = 0;      # Value to determine.
+ my $percent_percent = 0;
+ my $percent_opencurly = 0;
+ my $percent_closecurly = 0;
+
+ # Return cached result, if available:
+ if ($lex_files{$filename}) { return $lex_files{$filename};}
+
+ open(LEX_FILE, "<$filename") ||
+      die "Can't open $filename to determine if it's lex.\n";
+ while(<LEX_FILE>) {
+   $percent_percent++     if (m/^\s*\%\%/);
+   $percent_opencurly++   if (m/^\s*\%\{/);
+   $percent_closecurly++   if (m/^\s*\%\}/);
+ }
+ close(LEX_FILE);
+
+ if ($percent_percent && $percent_opencurly && $percent_closecurly)
+          {$is_lex = 1;}
+
+ $lex_files{$filename} = $is_lex; # Store result in cache.
+
+ return $is_lex;
+} # 1}}}
+sub really_is_expect {                       # {{{1
+# Given filename, returns TRUE if its contents really are Expect.
+# Many "exp" files (such as in Apache and Mesa) are just "export" data,
+# summarizing something else # (e.g., its interface).
+# Sometimes (like in RPM) it's just misc. data.
+# Thus, we need to look at the file to determine
+# if it's really an "expect" file.
+
+ my $filename = shift;
+ chomp($filename);
+
+# The heuristic is as follows: it's Expect _IF_ it:
+# 1. has "load_lib" command and either "#" comments or {}.
+# 2. {, }, and one of: proc, if, [...], expect
+
+ my $is_expect = 0;      # Value to determine.
+
+ my $begin_brace = 0;  # Lines that begin with curly braces.
+ my $end_brace = 0;    # Lines that begin with curly braces.
+ my $load_lib = 0;     # Lines with the Load_lib command.
+ my $found_proc = 0;
+ my $found_if = 0;
+ my $found_brackets = 0;
+ my $found_expect = 0;
+ my $found_pound = 0;
+
+ # Return cached result, if available:
+ if ($expect_files{$filename}) { return expect_files{$filename};}
+
+ open(EXPECT_FILE, "<$filename") ||
+      die "Can't open $filename to determine if it's expect.\n";
+ while(<EXPECT_FILE>) {
+
+   if (m/#/) {$found_pound++; s/#.*//;}
+   if (m/^\s*\{/) { $begin_brace++;}
+   if (m/\{\s*$/) { $begin_brace++;}
+   if (m/^\s*\}/) { $end_brace++;}
+   if (m/\};?\s*$/) { $end_brace++;}
+   if (m/^\s*load_lib\s+\S/) { $load_lib++;}
+   if (m/^\s*proc\s/) { $found_proc++;}
+   if (m/^\s*if\s/) { $found_if++;}
+   if (m/\[.*\]/) { $found_brackets++;}
+   if (m/^\s*expect\s/) { $found_expect++;}
+ }
+ close(EXPECT_FILE);
+
+ if ($load_lib && ($found_pound || ($begin_brace && $end_brace)))
+          {$is_expect = 1;}
+ if ( $begin_brace && $end_brace &&
+      ($found_proc || $found_if || $found_brackets || $found_expect))
+          {$is_expect = 1;}
+
+ $expect_files{$filename} = $is_expect; # Store result in cache.
+
+ return $is_expect;
+} # 1}}}
+sub really_is_pascal {                       # {{{1
+# Given filename, returns TRUE if its contents really are Pascal.
+
+# This isn't as obvious as it seems.
+# Many ".p" files are Perl files
+# (such as /usr/src/redhat/BUILD/ispell-3.1/dicts/czech/glob.p),
+# others are C extractions
+# (such as /usr/src/redhat/BUILD/linux/include/linux/umsdos_fs.p
+# and some files in linuxconf).
+# However, test files in "p2c" really are Pascal, for example.
+
+# Note that /usr/src/redhat/BUILD/ucd-snmp-4.1.1/ov/bitmaps/UCD.20.p
+# is actually C code.  The heuristics determine that they're not Pascal,
+# but because it ends in ".p" it's not counted as C code either.
+# I believe this is actually correct behavior, because frankly it
+# looks like it's automatically generated (it's a bitmap expressed as code).
+# Rather than guess otherwise, we don't include it in a list of
+# source files.  Let's face it, someone who creates C files ending in ".p"
+# and expects them to be counted by default as C files in SLOCCount needs
+# their head examined.  I suggest examining their head
+# with a sucker rod (see syslogd(8) for more on sucker rods).
+
+# This heuristic counts as Pascal such files such as:
+#  /usr/src/redhat/BUILD/teTeX-1.0/texk/web2c/tangleboot.p
+# Which is hand-generated.  We don't count woven documents now anyway,
+# so this is justifiable.
+
+ my $filename = shift;
+ chomp($filename);
+
+# The heuristic is as follows: it's Pascal _IF_ it has all of the following
+# (ignoring {...} and (*...*) comments):
+# 1. "^..program NAME" or "^..unit NAME",
+# 2. "procedure", "function", "^..interface", or "^..implementation",
+# 3. a "begin", and
+# 4. it ends with "end.",
+#
+# Or it has all of the following:
+# 1. "^..module NAME" and
+# 2. it ends with "end.".
+#
+# Or it has all of the following:
+# 1. "^..program NAME",
+# 2. a "begin", and
+# 3. it ends with "end.".
+#
+# The "end." requirements in particular filter out non-Pascal.
+#
+# Note (jgb): this does not detect Pascal main files in fpc, like
+# fpc-1.0.4/api/test/testterminfo.pas, which does not have "program" in
+# it
+
+ my $is_pascal = 0;      # Value to determine.
+
+ my $has_program = 0;
+ my $has_unit = 0;
+ my $has_module = 0;
+ my $has_procedure_or_function = 0;
+ my $found_begin = 0;
+ my $found_terminating_end = 0;
+ my $has_begin = 0;
+
+ open(PASCAL_FILE, "<$filename") ||
+      die "Can't open $filename to determine if it's pascal.\n";
+ while(<PASCAL_FILE>) {
+   s/\{.*?\}//g;  # Ignore {...} comments on this line; imperfect, but effective.
+   s/\(\*.*?\*\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.
+   if (m/\bprogram\s+[A-Za-z]/i)  {$has_program=1;}
+   if (m/\bunit\s+[A-Za-z]/i)     {$has_unit=1;}
+   if (m/\bmodule\s+[A-Za-z]/i)   {$has_module=1;}
+   if (m/\bprocedure\b/i)         { $has_procedure_or_function = 1; }
+   if (m/\bfunction\b/i)          { $has_procedure_or_function = 1; }
+   if (m/^\s*interface\s+/i)      { $has_procedure_or_function = 1; }
+   if (m/^\s*implementation\s+/i) { $has_procedure_or_function = 1; }
+   if (m/\bbegin\b/i) { $has_begin = 1; }
+   # Originally I said:
+   # "This heuristic fails if there are multi-line comments after
+   # "end."; I haven't seen that in real Pascal programs:"
+   # But jgb found there are a good quantity of them in Debian, specially in 
+   # fpc (at the end of a lot of files there is a multiline comment
+   # with the changelog for the file).
+   # Therefore, assume Pascal if "end." appears anywhere in the file.
+   if (m/end\.\s*$/i) {$found_terminating_end = 1;}
+#   elsif (m/\S/) {$found_terminating_end = 0;}
+ }
+ close(PASCAL_FILE);
+
+ # Okay, we've examined the entire file looking for clues;
+ # let's use those clues to determine if it's really Pascal:
+
+ if ( ( ($has_unit || $has_program) && $has_procedure_or_function &&
+     $has_begin && $found_terminating_end ) ||
+      ( $has_module && $found_terminating_end ) ||
+      ( $has_program && $has_begin && $found_terminating_end ) )
+          {$is_pascal = 1;}
+
+ return $is_pascal;
+} # 1}}}
+sub really_is_incpascal {                    # {{{1
+# Given filename, returns TRUE if its contents really are Pascal.
+# For .inc files (mainly seen in fpc)
+
+ my $filename = shift;
+ chomp($filename);
+
+# The heuristic is as follows: it is Pacal if any of the following:
+# 1. really_is_pascal returns true
+# 2. Any usual reserverd word is found (program, unit, const, begin...)
+
+ # If the general routine for Pascal files works, we have it
+ if (really_is_pascal($filename)) { 
+   return 1;
+ }
+
+ my $is_pascal = 0;      # Value to determine.
+ my $found_begin = 0;
+
+ open(PASCAL_FILE, "<$filename") ||
+      die "Can't open $filename to determine if it's pascal.\n";
+ while(<PASCAL_FILE>) {
+   s/\{.*?\}//g;  # Ignore {...} comments on this line; imperfect, but effective.
+   s/\(\*.*?\*\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.
+   if (m/\bprogram\s+[A-Za-z]/i)  {$is_pascal=1;}
+   if (m/\bunit\s+[A-Za-z]/i)     {$is_pascal=1;}
+   if (m/\bmodule\s+[A-Za-z]/i)   {$is_pascal=1;}
+   if (m/\bprocedure\b/i)         {$is_pascal = 1; }
+   if (m/\bfunction\b/i)          {$is_pascal = 1; }
+   if (m/^\s*interface\s+/i)      {$is_pascal = 1; }
+   if (m/^\s*implementation\s+/i) {$is_pascal = 1; }
+   if (m/\bconstant\s+/i)         {$is_pascal=1;}
+   if (m/\bbegin\b/i) { $found_begin = 1; }
+   if ((m/end\.\s*$/i) && ($found_begin = 1)) {$is_pascal = 1;}
+   if ($is_pascal) {
+     last;
+   }
+ }
+
+ close(PASCAL_FILE);
+ return $is_pascal;
+} # 1}}}
+sub really_is_php {                          # {{{1
+# Given filename, returns TRUE if its contents really is php.
+
+ my $filename = shift;
+ chomp($filename);
+
+ my $is_php = 0;      # Value to determine.
+ # Need to find a matching pair of surrounds, with ending after beginning:
+ my $normal_surround = 0;  # <?; bit 0 = <?, bit 1 = ?>
+ my $script_surround = 0;  # <script..>; bit 0 = <script language="php">
+ my $asp_surround = 0;     # <%; bit 0 = <%, bit 1 = %>
+
+ # Return cached result, if available:
+ if ($php_files{$filename}) { return $php_files{$filename};}
+
+ open(PHP_FILE, "<$filename") ||
+      die "Can't open $filename to determine if it's php.\n";
+ while(<PHP_FILE>) {
+   if (m/\<\?/)                           { $normal_surround |= 1; }
+   if (m/\?\>/ && ($normal_surround & 1)) { $normal_surround |= 2; }
+   if (m/\<script.*language="?php"?/i)    { $script_surround |= 1; }
+   if (m/\<\/script\>/i && ($script_surround & 1)) { $script_surround |= 2; }
+   if (m/\<\%/)                           { $asp_surround |= 1; }
+   if (m/\%\>/ && ($asp_surround & 1)) { $asp_surround |= 2; }
+ }
+ close(PHP_FILE);
+
+ if ( ($normal_surround == 3) || ($script_surround == 3) ||
+      ($asp_surround == 3)) {
+   $is_php = 1;
+ }
+
+ $php_files{$filename} = $is_php; # Store result in cache.
+
+ return $is_php;
+} # 1}}}
+__END__
+mode values (stat $item)[2]
+       Unix    Windows
+file:  33188   33206
+dir :  16832   16895
+link:  33261   33206
+pipe:   4544    null
Index: /issm/trunk/scripts/cloc2html.py
===================================================================
--- /issm/trunk/scripts/cloc2html.py	(revision 17988)
+++ /issm/trunk/scripts/cloc2html.py	(revision 17989)
@@ -46,5 +46,5 @@
 		else:       mystr = '<tr>\n<th '+color2+style_l+'>'
 		for i in line.split():
-			if(not i.isdigit()):
+			if(not i.isdigit() or (i.isdigit and int(i)==77)):
 				mystr += ' '+i+' '
 			else:
Index: /issm/trunk/scripts/getloc.sh
===================================================================
--- /issm/trunk/scripts/getloc.sh	(revision 17988)
+++ /issm/trunk/scripts/getloc.sh	(revision 17989)
@@ -1,5 +1,5 @@
 #!/bin/bash
 #get number of lines of code
-cloc-1.55.pl $ISSM_DIR/src $ISSM_DIR/m4 --exclude-dir=.svn --exclude-dir=ad  --exclude-ext=exp --exclude-lang=make --out=temp
+cloc-1.60.pl $ISSM_DIR/src $ISSM_DIR/m4 --exclude-dir=.svn --exclude-dir=ad  --exclude-ext=exp --exclude-lang=make --out=temp
 cat temp
 ./cloc2html.py
@@ -10,27 +10,2 @@
 cat input1 temp.html input2 > $ISSM_DIR/src/dox/issm.dox
 rm input1 input2 temp.html
-
-exit 1
-
-
-
-
-
-#OLDER MANUAL VESION
-#get Matlab number of lines
-cd $ISSM_DIR/src/m
-M_LOC=$(find . -name "*.m" -exec wc -l '{}' \; | awk '{ sum += $1 } END { print sum}');
-echo "Matlab code: $M_LOC"
-
-#get C/CPP number of lines
-cd $ISSM_DIR/src
-CPP_LOC=$(find . -name "*.cpp" -exec wc -l '{}' \; | awk '{ sum += $1 } END { print sum}');
-echo "C++    code: $CPP_LOC"
-C_LOC=$(find . -name "*.c" -exec wc -l '{}' \; | awk '{ sum += $1 } END { print sum}');
-echo "C      code: $C_LOC"
-H_LOC=$(find . -name "*.h" -exec wc -l '{}' \; | awk '{ sum += $1 } END { print sum}');
-echo "header code: $H_LOC"
-
-#print total
-let SUM=$M_LOC+$CPP_LOC+$C_LOC+$H_LOC
-echo "Total      : $SUM"
Index: sm/trunk/scripts/sync.sh
===================================================================
--- /issm/trunk/scripts/sync.sh	(revision 17988)
+++ 	(revision )
@@ -1,100 +1,0 @@
-#!/bin/bash
-
-#This shell tries to synchronize the current cielo root directory on another 
-#machine. 
-
-echo "Watch out, this script should be run in top level directory of cielo"
-
-echo -n "Platform (cosmos,mustang,gemini,pleiades)?: "
-read platform 
-
-
-if [[ "$platform" ==  "cosmos" ]]
-then
-	echo "Synchronizing cielo with cosmos"
-	#first cleanup the archive
-	cl
-	clb
-	cls
-	#then tar the archive
-	present_directory=`pwd`;
-	cd ../
-	rm -rf trunk.tar.gz
-	tar zcvf trunk.tar.gz trunk
-
-	#send archive to cosmos
-	scp  trunk.tar.gz larour@cosmos.jpl.nasa.gov:/home/larour
-
-	#run synchronization script on cosmos
-	ssh larour@cosmos.jpl.nasa.gov './sync_cosmos.sh'
-
-	rm -rf trunk.tar.gz
-elif [[ "$platform" ==  "mustang" ]]
-then
-	
-	echo "Synchronizing cielo with mustang"
-	#first cleanup the archive
-	cl
-	clb
-	cls
-	#then tar the archive
-	present_directory=`pwd`;
-	cd ../
-	rm -rf trunk.tar.gz
-	tar zcvf trunk.tar.gz trunk
-
-	#send archive to mustang
-	scp  trunk.tar.gz larour@mustang.jpl.nasa.gov:/proj/ice/larour/Ice/
-
-	#run synchronization script on cosmos
-	ssh larour@mustang.jpl.nasa.gov './sync_mustang.sh'
-
-	rm -rf trunk.tar.gz
-elif [[ "$platform" ==  "gemini" ]]
-then
-	echo "Synchronizing cielo with gemini"
-
-	rm -rf Synchronisation
-	mkdir Synchronisation
-	cd Synchronisation
-	svn co svn+ssh://mustang.jpl.nasa.gov/proj/ice/issm/issm/trunk
-
-	#then tar the archive
-	tar zcvf trunk.tar.gz trunk/
-
-	#send archive to cosmos
-	scp  trunk.tar.gz larour@gemini.jpl.nasa.gov:/home/larour
-
-	#run synchronization script on cosmos
-	ssh larour@gemini.jpl.nasa.gov './sync_gemini.sh' 
-
-	#exit 
-	cd ..
-	rm -rf Synchronisation
-
-elif [[ "$platform" ==  "pleiades" ]]
-then
-	echo "Synchronizing issm with pleiades"
-
-	rm -rf Synchronisation
-	mkdir Synchronisation
-	cd Synchronisation
-	svn co svn+ssh://mustang.jpl.nasa.gov/proj/ice/issm/issm/trunk
-
-	#then tar the archive
-	tar zcvf trunk.tar.gz trunk/
-
-	#send archive to cosmos
-	scp  trunk.tar.gz elarour@pfe:/home1/elarour
-
-	#run synchronization script on cosmos
-	ssh elarour@pfe './sync_pleiades.sh'
-
-	#exit 
-	cd ..
-	rm -rf Synchronisation
-
-else
-	echo "This platform not supported yet"
-	exit
-fi
Index: /issm/trunk/src/c/Makefile.am
===================================================================
--- /issm/trunk/src/c/Makefile.am	(revision 17988)
+++ /issm/trunk/src/c/Makefile.am	(revision 17989)
@@ -209,5 +209,4 @@
 					./shared/Numerics/extrema.cpp\
 					./shared/Numerics/XZvectorsToCoordinateSystem.cpp\
-					./shared/Numerics/OptArgs.h\
 					./shared/Numerics/OptPars.h\
 					./shared/Exceptions/exceptions.h\
@@ -284,6 +283,10 @@
 					./modules/OutputResultsx/OutputResultsx.h\
 					./modules/OutputResultsx/OutputResultsx.cpp\
+					./modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.h\
+					./modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.cpp\
 					./modules/InputDuplicatex/InputDuplicatex.h\
 					./modules/InputDuplicatex/InputDuplicatex.cpp\
+					./modules/InputExtrudex/InputExtrudex.h\
+					./modules/InputExtrudex/InputExtrudex.cpp\
 					./modules/InputScalex/InputScalex.h\
 					./modules/InputScalex/InputScalex.cpp\
@@ -316,8 +319,4 @@
 					./modules/ConfigureObjectsx/ConfigureObjectsx.h\
 					./modules/ConfigureObjectsx/ConfigureObjectsx.cpp\
-					./modules/ComputeBasalStressx/ComputeBasalStressx.h\
-					./modules/ComputeBasalStressx/ComputeBasalStressx.cpp\
-					./modules/ComputeStrainRatex/ComputeStrainRatex.h\
-					./modules/ComputeStrainRatex/ComputeStrainRatex.cpp\
 					./modules/SpcNodesx/SpcNodesx.h\
 					./modules/SpcNodesx/SpcNodesx.cpp\
@@ -416,11 +415,11 @@
 					./classes/Inputs/ControlInput.cpp\
 					./shared/Numerics/BrentSearch.cpp\
-					./shared/Numerics/OptimalSearch.cpp \
 					./cores/control_core.cpp\
 					./cores/controltao_core.cpp\
-					./cores/objectivefunction.cpp\
+					./cores/controlm1qn3_core.cpp\
 					./cores/gradient_core.cpp\
 					./cores/adjointstressbalance_core.cpp\
 					./cores/adjointbalancethickness_core.cpp\
+					./cores/adjointbalancethickness2_core.cpp\
 					./cores/AdjointCorePointerFromSolutionEnum.cpp\
 					./solutionsequences/solutionsequence_adjoint_linear.cpp\
@@ -430,4 +429,5 @@
 					./solutionsequences/solutionsequence_stokescoupling_nonlinear.cpp\
 					./cores/balancethickness_core.cpp \
+					./cores/balancethickness2_core.cpp \
 					./cores/balancevelocity_core.cpp \
 					./cores/dummy_core.cpp\
@@ -516,4 +516,7 @@
 issm_sources += ./analyses/AdjointBalancethicknessAnalysis.cpp
 endif
+if ADJOINTBALANCETHICKNESS2
+issm_sources += ./analyses/AdjointBalancethickness2Analysis.cpp
+endif
 if ADJOINTHORIZ
 issm_sources += ./analyses/AdjointHorizAnalysis.cpp
@@ -521,4 +524,7 @@
 if BALANCETHICKNESS
 issm_sources += ./analyses/BalancethicknessAnalysis.cpp
+endif
+if BALANCETHICKNESS2
+issm_sources += ./analyses/Balancethickness2Analysis.cpp
 endif
 if BALANCETHICKNESSSOFT
@@ -833,6 +839,4 @@
 			./modules/ContourToNodesx/ContourToNodesx.cpp\
 			./modules/ContourToNodesx/ContourToNodesx.h\
-			./modules/Reducevectorgtosx/Reducevectorgtosx.cpp\
-			./modules/Reducevectorgtosx/Reducevectorgtosx.h\
 			./modules/NodeConnectivityx/NodeConnectivityx.cpp\
 			./modules/NodeConnectivityx/NodeConnectivityx.h\
@@ -866,5 +870,5 @@
 
 libISSMCore_la_SOURCES  = $(issm_sources)
-libISSMCore_la_LIBADD = $(PETSCLIB) $(TAOLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(FORTRANLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB)   $(ADOLCLIB) $(AMPILIB) $(METEOIOLIB) $(SNOWPACKLIB) 
+libISSMCore_la_LIBADD = $(PETSCLIB) $(TAOLIB) $(M1QN3LIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB) $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB)   $(ADOLCLIB) $(AMPILIB) $(METEOIOLIB) $(SNOWPACKLIB) 
 libISSMCore_la_FFLAGS = $(AM_FFLAGS)
 endif
@@ -913,8 +917,8 @@
 
 #External packages
-LDADD += $(PETSCLIB) $(TAOLIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB)  $(MATHLIB) $(FORTRANLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(AMPILIB) $(ADOLCLIB) $(MPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
+LDADD += $(PETSCLIB) $(TAOLIB) $(M1QN3LIB) $(PLAPACKLIB) $(MUMPSLIB) $(SUPERLULIB) $(SPOOLESLIB) $(SCALAPACKLIB) $(BLACSLIB) $(HYPRELIB) $(SPAILIB) $(PROMETHEUSLIB) $(PASTIXLIB) $(MLLIB) $(DAKOTALIB) $(METISLIB) $(CHACOLIB) $(SCOTCHLIB) $(BLASLAPACKLIB) $(MKLLIB) $(MPILIB)  $(MATHLIB) $(GRAPHICSLIB) $(MULTITHREADINGLIB) $(OSLIBS) $(GSLLIB) $(AMPILIB) $(ADOLCLIB) $(MPILIB) $(METEOIOLIB) $(SNOWPACKLIB)
 
 if FORTRAN
-LDADD += $(FLIBS)
+LDADD += $(FLIBS) $(FORTRANLIB)
 endif
 
Index: /issm/trunk/src/c/analyses/AdjointBalancethickness2Analysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/AdjointBalancethickness2Analysis.cpp	(revision 17989)
+++ /issm/trunk/src/c/analyses/AdjointBalancethickness2Analysis.cpp	(revision 17989)
@@ -0,0 +1,160 @@
+#include "./AdjointBalancethickness2Analysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+
+/*Model processor*/
+int  AdjointBalancethickness2Analysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}/*}}}*/
+void AdjointBalancethickness2Analysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void AdjointBalancethickness2Analysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void AdjointBalancethickness2Analysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void AdjointBalancethickness2Analysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void AdjointBalancethickness2Analysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           AdjointBalancethickness2Analysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented");
+}/*}}}*/
+ElementVector* AdjointBalancethickness2Analysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* AdjointBalancethickness2Analysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* AdjointBalancethickness2Analysis::CreateKMatrix(Element* element){/*{{{*/
+
+	_error_("not implemented");
+	Balancethickness2Analysis* analysis = new Balancethickness2Analysis();
+	ElementMatrix* Ke = analysis->CreateKMatrix(element);
+	delete analysis;
+
+	/*Transpose and return Ke*/
+	Ke->Transpose();
+	return Ke;
+}/*}}}*/
+ElementVector* AdjointBalancethickness2Analysis::CreatePVector(Element* element){/*{{{*/
+
+	_error_("not implemented");
+	/*Intermediaries*/
+	int      domaintype;
+	Element* basalelement;
+
+	/*Get basal element*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DhorizontalEnum:
+			basalelement = element;
+			break;
+		case Domain3DEnum:
+			if(!element->IsOnBase()) return NULL;
+			basalelement = element->SpawnBasalElement();
+			break;
+		default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet");
+	}
+
+	/*Intermediaries */
+	int         num_responses,i;
+	IssmDouble  dH[2];
+	IssmDouble  vx,vy,vel,Jdet;
+	IssmDouble  thickness,thicknessobs,weight;
+	int        *responses = NULL;
+	IssmDouble *xyz_list  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = basalelement->GetNumberOfNodes();
+
+	/*Initialize Element vector and vectors*/
+	ElementVector* pe     = basalelement->NewElementVector(SSAApproximationEnum);
+	IssmDouble*    basis  = xNew<IssmDouble>(numnodes);
+	IssmDouble*    dbasis = xNew<IssmDouble>(2*numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+	basalelement->FindParam(&num_responses,InversionNumCostFunctionsEnum);
+	basalelement->FindParam(&responses,NULL,InversionCostFunctionsEnum);
+	Input* thickness_input    = basalelement->GetInput(ThicknessEnum);                          _assert_(thickness_input);
+	Input* thicknessobs_input = basalelement->GetInput(InversionThicknessObsEnum);              _assert_(thicknessobs_input);
+	Input* weights_input      = basalelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input           = basalelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input           = basalelement->GetInput(VyEnum);                                 _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		basalelement->NodalFunctions(basis,gauss);
+		basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+
+		thickness_input->GetInputValue(&thickness, gauss);
+		thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss);
+		thicknessobs_input->GetInputValue(&thicknessobs, gauss);
+
+		/*Loop over all requested responses*/
+		for(int resp=0;resp<num_responses;resp++){
+			weights_input->GetInputValue(&weight,gauss,responses[resp]);
+
+			switch(responses[resp]){
+				case ThicknessAbsMisfitEnum:
+					for(i=0;i<numnodes;i++) pe->values[i]+=(thicknessobs-thickness)*weight*Jdet*gauss->weight*basis[i];
+					break;
+				case ThicknessAbsGradientEnum:
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[0]*dbasis[0*numnodes+i]*Jdet*gauss->weight;
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*dH[1]*dbasis[1*numnodes+i]*Jdet*gauss->weight;
+					break;
+				case ThicknessAlongGradientEnum:
+					vx_input->GetInputValue(&vx,gauss);
+					vy_input->GetInputValue(&vy,gauss);
+					vel = sqrt(vx*vx+vy*vy);
+					vx  = vx/(vel+1.e-9);
+					vy  = vy/(vel+1.e-9);
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*vx+dH[1]*vy)*(dbasis[0*numnodes+i]*vx+dbasis[1*numnodes+i]*vy)*Jdet*gauss->weight;
+					break;
+				case ThicknessAcrossGradientEnum:
+					vx_input->GetInputValue(&vx,gauss);
+					vy_input->GetInputValue(&vy,gauss);
+					vel = sqrt(vx*vx+vy*vy);
+					vx  = vx/(vel+1.e-9);
+					vy  = vy/(vel+1.e-9);
+					for(i=0;i<numnodes;i++) pe->values[i]+= - weight*(dH[0]*(-vy)+dH[1]*vx)*(dbasis[0*numnodes+i]*(-vy)+dbasis[1*numnodes+i]*vx)*Jdet*gauss->weight;
+					break;
+				default:
+					_error_("response " << EnumToStringx(responses[resp]) << " not supported yet");
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<int>(responses);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	xDelete<IssmDouble>(dbasis);
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	delete gauss;
+	return pe;
+}/*}}}*/
+void AdjointBalancethickness2Analysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+void AdjointBalancethickness2Analysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+	element->InputUpdateFromSolutionOneDof(solution,AdjointEnum);
+}/*}}}*/
+void AdjointBalancethickness2Analysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/AdjointBalancethickness2Analysis.h
===================================================================
--- /issm/trunk/src/c/analyses/AdjointBalancethickness2Analysis.h	(revision 17989)
+++ /issm/trunk/src/c/analyses/AdjointBalancethickness2Analysis.h	(revision 17989)
@@ -0,0 +1,32 @@
+/*! \file AdjointBalancethickness2Analysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _AdjointBalancethickness2Analysis_
+#define _AdjointBalancethickness2Analysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class AdjointBalancethickness2Analysis: public Analysis{
+
+	public:
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
+		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+		void CreateNodes(Nodes* nodes,IoModel* iomodel);
+		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+};
+#endif
Index: /issm/trunk/src/c/analyses/AdjointHorizAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/AdjointHorizAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/AdjointHorizAnalysis.cpp	(revision 17989)
@@ -208,4 +208,5 @@
 	/*Intermediaries */
 	bool        incomplete_adjoint;
+	int         dim,epssize;
 	IssmDouble  Jdet,mu_prime;
 	IssmDouble  eps1dotdphii,eps1dotdphij,eps2dotdphii,eps2dotdphij,eps3dotdphii,eps3dotdphij;
@@ -213,8 +214,13 @@
 	IssmDouble *xyz_list = NULL;
 
+	/*Get problem dimension*/
+	element->FindParam(&dim,DomainDimensionEnum);
+	if(dim==2) epssize = 3;
+	else       epssize = 6;
+
 	/*Fetch number of nodes and dof for this finite element*/
 	int vnumnodes = element->NumberofNodesVelocity();
 	int pnumnodes = element->NumberofNodesPressure();
-	int numdof    = vnumnodes*3 + pnumnodes;
+	int numdof    = vnumnodes*dim + pnumnodes;
 
 	/*Initialize Jacobian with regular FS (first part of the Gateau derivative)*/
@@ -229,8 +235,14 @@
 	Input* vx_input = element->GetInput(VxEnum);_assert_(vx_input);
 	Input* vy_input = element->GetInput(VyEnum);_assert_(vy_input);
-	Input* vz_input = element->GetInput(VzEnum);_assert_(vz_input);
+	Input* vz_input = NULL;
+	if(dim==3){
+		vz_input = element->GetInput(VzEnum);
+	}
+	else{
+		_error_("Not implemented yet");
+	}
 
 	/*Allocate dbasis*/
-	IssmDouble* dbasis = xNew<IssmDouble>(3*vnumnodes);
+	IssmDouble* dbasis = xNew<IssmDouble>(dim*vnumnodes);
 
 	/* Start  looping on the number of gaussian points: */
@@ -320,5 +332,6 @@
 	/*Prepare coordinate system list*/
 	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i]           = XYZEnum;
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
 	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
 
@@ -376,7 +389,9 @@
 					for(i=0;i<vnumnodes;i++){
 						dux=vxobs-vx;
-						duy=vyobs-vy;
 						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
-						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+						if(dim==3){
+							duy=vyobs-vy;
+							pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+						}
 					}
 					break;
@@ -415,11 +430,20 @@
 					 */
 					for(i=0;i<vnumnodes;i++){
-						velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
-						obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
-						scale=-8*pow(meanvel,2)/pow(velocity_mag,2)*log(velocity_mag/obs_velocity_mag);
-						dux=scale*vx;
-						duy=scale*vy;
-						pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
-						pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+						if(dim==3){
+							velocity_mag    =sqrt(vx*vx+vy*vy)+epsvel;
+							obs_velocity_mag=sqrt(vxobs*vxobs+vyobs*vyobs)+epsvel;
+							scale=-8.*meanvel*meanvel/(velocity_mag*velocity_mag)*log(velocity_mag/obs_velocity_mag);
+							dux=scale*vx;
+							duy=scale*vy;
+							pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+							pe->values[i*dim+1]+=duy*weight*Jdet*gauss->weight*vbasis[i]; 
+						}
+						else{
+							velocity_mag    =fabs(vx)+epsvel;
+							obs_velocity_mag=fabs(vxobs)+epsvel;
+							scale=-8.*meanvel*meanvel/(velocity_mag*velocity_mag)*log(velocity_mag/obs_velocity_mag);
+							dux=scale*vx;
+							pe->values[i*dim+0]+=dux*weight*Jdet*gauss->weight*vbasis[i]; 
+						}
 					}
 					break;
@@ -490,5 +514,4 @@
 	delete gauss;
 	return pe;
-	_error_("S");
 }/*}}}*/
 ElementVector* AdjointHorizAnalysis::CreatePVectorHO(Element* element){/*{{{*/
@@ -928,13 +951,15 @@
 }/*}}}*/
 void AdjointHorizAnalysis::InputUpdateFromSolutionFS(IssmDouble* solution,Element* element){/*{{{*/
-	int          i;
+	int          i,dim;
 	int*         vdoflist=NULL;
 	int*         pdoflist=NULL;
 	IssmDouble   FSreconditioning;
 
+	element->FindParam(&dim,DomainDimensionEnum);
+
 	/*Fetch number of nodes and dof for this finite element*/
 	int vnumnodes = element->NumberofNodesVelocity();
 	int pnumnodes = element->NumberofNodesPressure();
-	int vnumdof   = vnumnodes*3;
+	int vnumdof   = vnumnodes*dim;
 	int pnumdof   = pnumnodes*1;
 
@@ -947,5 +972,6 @@
 
 	int* cs_list = xNew<int>(vnumnodes+pnumnodes);
-	for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
+	if(dim==2) for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;
+	else       for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;
 	for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;
 
Index: /issm/trunk/src/c/analyses/Analysis.h
===================================================================
--- /issm/trunk/src/c/analyses/Analysis.h	(revision 17988)
+++ /issm/trunk/src/c/analyses/Analysis.h	(revision 17989)
@@ -17,4 +17,5 @@
 class ElementMatrix;
 class Gauss;
+class FemModel;
 
 class Analysis{
Index: /issm/trunk/src/c/analyses/Balancethickness2Analysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/Balancethickness2Analysis.cpp	(revision 17989)
+++ /issm/trunk/src/c/analyses/Balancethickness2Analysis.cpp	(revision 17989)
@@ -0,0 +1,268 @@
+#include "./Balancethickness2Analysis.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+
+/*Model processing*/
+int  Balancethickness2Analysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/
+	return 1;
+}/*}}}*/
+void Balancethickness2Analysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+}/*}}}*/
+void Balancethickness2Analysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+
+	/*Finite element type*/
+	int finiteelement = P1Enum;
+
+	/*Update elements: */
+	int counter=0;
+	for(int i=0;i<iomodel->numberofelements;i++){
+		if(iomodel->my_elements[i]){
+			Element* element=(Element*)elements->GetObjectByOffset(counter);
+			element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
+			counter++;
+		}
+	}
+
+	iomodel->FetchDataToInput(elements,BalancethicknessApparentMassbalanceEnum);
+	iomodel->FetchDataToInput(elements,BalancethicknessNuxEnum);
+	iomodel->FetchDataToInput(elements,BalancethicknessNuyEnum);
+	iomodel->FetchDataToInput(elements,BalancethicknessVxObsEnum);
+	iomodel->FetchDataToInput(elements,BalancethicknessVyObsEnum);
+	iomodel->FetchDataToInput(elements,BalancethicknessThicknessObsEnum);
+	iomodel->FetchDataToInput(elements,MeshVertexonboundaryEnum);
+	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
+}/*}}}*/
+void Balancethickness2Analysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
+
+	int finiteelement = P1Enum;
+	::CreateNodes(nodes,iomodel,Balancethickness2AnalysisEnum,finiteelement);
+}/*}}}*/
+void Balancethickness2Analysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/
+
+
+	int finiteelement = P1Enum;
+	IoModelToConstraintsx(constraints,iomodel,BalancethicknessSpcpotentialEnum,Balancethickness2AnalysisEnum,finiteelement);
+
+}/*}}}*/
+void Balancethickness2Analysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/
+
+}/*}}}*/
+
+/*Finite Element Analysis*/
+void           Balancethickness2Analysis::Core(FemModel* femmodel){/*{{{*/
+	_error_("not implemented yet");
+}/*}}}*/
+ElementVector* Balancethickness2Analysis::CreateDVector(Element* element){/*{{{*/
+	/*Default, return NULL*/
+	return NULL;
+}/*}}}*/
+ElementMatrix* Balancethickness2Analysis::CreateJacobianMatrix(Element* element){/*{{{*/
+_error_("Not implemented");
+}/*}}}*/
+ElementMatrix* Balancethickness2Analysis::CreateKMatrix(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble Jdet,D_scalar;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementMatrix* Ke  = element->NewElementMatrix();
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
+		element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		for(int i=0;i<numnodes;i++){
+			for(int j=0;j<numnodes;j++){
+				Ke->values[i*numnodes+j] += gauss->weight*Jdet*(dbasis[0*numnodes+i]*dbasis[0*numnodes+j] + dbasis[1*numnodes+i]*dbasis[1*numnodes+j]);
+			}
+		}
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Ke;
+}/*}}}*/
+ElementVector* Balancethickness2Analysis::CreatePVector(Element* element){/*{{{*/
+
+	/*compute all load vectors for this element*/
+	ElementVector* pe1=CreatePVectorVolume(element);
+	ElementVector* pe2=CreatePVectorBoundary(element);
+	ElementVector* pe =new ElementVector(pe1,pe2);
+
+	/*clean-up and return*/
+	delete pe1;
+	delete pe2;
+	return pe;
+}/*}}}*/
+ElementVector* Balancethickness2Analysis::CreatePVectorVolume(Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  adot,Jdet;
+	IssmDouble* xyz_list = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* adot_input   = element->GetInput(BalancethicknessApparentMassbalanceEnum); _assert_(adot_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+		gauss->GaussPoint(ig);
+
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+		element->NodalFunctions(basis,gauss);
+		adot_input->GetInputValue(&adot,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*adot*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+ElementVector* Balancethickness2Analysis::CreatePVectorBoundary(Element* element){/*{{{*/
+
+	/*If no front, return NULL*/
+	if(!element->IsFaceOnBoundary()) return NULL;
+
+	/*Intermediaries*/
+	IssmDouble  Jdet,thickness,vx,vy;
+	IssmDouble *xyz_list = NULL;
+	IssmDouble *xyz_list_front = NULL;
+	IssmDouble  normal[2];
+
+	/*Fetch number of nodes for this finite element*/
+	int numnodes = element->GetNumberOfNodes();
+
+	/*Initialize Element vector and other vectors*/
+	ElementVector* pe    = element->NewElementVector();
+	IssmDouble*    basis = xNew<IssmDouble>(numnodes);
+
+	/*Retrieve all inputs and parameters*/
+	Input* thickness_input = element->GetInput(BalancethicknessThicknessObsEnum); _assert_(thickness_input);
+	Input* vx_input        = element->GetInput(BalancethicknessVxObsEnum);        _assert_(vx_input);
+	Input* vy_input        = element->GetInput(BalancethicknessVyObsEnum);        _assert_(vy_input);
+
+	element->GetVerticesCoordinates(&xyz_list);
+	element->GetIcefrontCoordinates(&xyz_list_front,xyz_list,MaskIceLevelsetEnum);
+	element->NormalSection(&normal[0],xyz_list_front);
+
+	/*Start looping on Gaussian points*/
+	Gauss* gauss=element->NewGauss(xyz_list,xyz_list_front,3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+		thickness_input->GetInputValue(&thickness,gauss);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		element->JacobianDeterminantSurface(&Jdet,xyz_list_front,gauss);
+		element->NodalFunctions(basis,gauss);
+
+		for(int i=0;i<numnodes;i++) pe->values[i] += - Jdet*gauss->weight*thickness*(vx*normal[0] + vy*normal[1])*basis[i];
+	}
+
+	/*Clean up and return*/
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_front);
+	xDelete<IssmDouble>(basis);
+	delete gauss;
+	return pe;
+}/*}}}*/
+void Balancethickness2Analysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
+	   _error_("not implemented yet");
+}/*}}}*/
+void Balancethickness2Analysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/
+
+	/*Intermediaries */
+	IssmDouble  vx,vy,vbar,nux,nuy,normdphi,dphi[2];
+	IssmDouble* xyz_list = NULL;
+	int       * doflist  = NULL;
+
+	/*Fetch number of nodes and dof for this finite element*/
+	int numnodes    = element->GetNumberOfNodes();
+	int numvertices = element->GetNumberOfVertices();
+
+	/*Fetch dof list and allocate solution vector*/
+	element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
+	IssmDouble* values         = xNew<IssmDouble>(numnodes);
+	IssmDouble* thickness_list = xNew<IssmDouble>(numvertices);
+	IssmDouble* vx_list        = xNew<IssmDouble>(numvertices);
+	IssmDouble* vy_list        = xNew<IssmDouble>(numvertices);
+
+	/*Use the dof list to index into the solution vector: */
+	for(int i=0;i<numnodes;i++){
+		values[i]=solution[doflist[i]];
+
+		/*Check solution*/
+		if(xIsNan<IssmDouble>(values[i])) _error_("NaN found in solution vector");
+	}
+
+	element->AddInput(PotentialEnum,values,element->GetElementType());
+
+	/*Retrieve all inputs and parameters*/
+	element->GetVerticesCoordinates(&xyz_list);
+	Input* potential_input = element->GetInput(PotentialEnum);             _assert_(potential_input);
+	Input* vx_input        = element->GetInput(BalancethicknessVxObsEnum); _assert_(vx_input);
+	Input* vy_input        = element->GetInput(BalancethicknessVyObsEnum); _assert_(vy_input);
+	Input* nux_input       = element->GetInput(BalancethicknessNuxEnum);   _assert_(nux_input);
+	Input* nuy_input       = element->GetInput(BalancethicknessNuyEnum);   _assert_(nuy_input);
+
+	Gauss* gauss=element->NewGauss();
+	for (int iv=0;iv<numvertices;iv++){
+		gauss->GaussVertex(iv);
+
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		nux_input->GetInputValue(&nux,gauss);
+		nuy_input->GetInputValue(&nuy,gauss);
+		potential_input->GetInputDerivativeValue(&dphi[0],xyz_list,gauss);
+
+		vx = vx*nux; vy = vy*nuy;
+		vbar = sqrt(vx*vx + vy*vy) + 1.e-10;
+		normdphi = sqrt(dphi[0]*dphi[0] + dphi[1]*dphi[1]);
+
+		thickness_list[iv] = normdphi/vbar;
+		vx_list[iv]        = -1./thickness_list[iv] * dphi[0];
+		vy_list[iv]        = -1./thickness_list[iv] * dphi[1];
+	}
+	element->AddInput(ThicknessEnum,thickness_list,P1Enum);
+	element->AddInput(VxEnum,vx_list,P1Enum);
+	element->AddInput(VyEnum,vy_list,P1Enum);
+
+	/*Clean up and return*/
+	delete gauss;
+	xDelete<int>(doflist);
+	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(values);
+	xDelete<IssmDouble>(thickness_list);
+	xDelete<IssmDouble>(vx_list);
+	xDelete<IssmDouble>(vy_list);
+}/*}}}*/
+void Balancethickness2Analysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
+	/*Default, do nothing*/
+	return;
+}/*}}}*/
Index: /issm/trunk/src/c/analyses/Balancethickness2Analysis.h
===================================================================
--- /issm/trunk/src/c/analyses/Balancethickness2Analysis.h	(revision 17989)
+++ /issm/trunk/src/c/analyses/Balancethickness2Analysis.h	(revision 17989)
@@ -0,0 +1,34 @@
+/*! \file Balancethickness2Analysis.h 
+ *  \brief: header file for generic external result object
+ */
+
+#ifndef _Balancethickness2Analysis_
+#define _Balancethickness2Analysis_
+
+/*Headers*/
+#include "./Analysis.h"
+
+class Balancethickness2Analysis: public Analysis{
+
+	public:
+		/*Model processing*/
+		int  DofsPerNode(int** doflist,int domaintype,int approximation);
+		void UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum);
+		void UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
+		void CreateNodes(Nodes* nodes,IoModel* iomodel);
+		void CreateConstraints(Constraints* constraints,IoModel* iomodel);
+		void CreateLoads(Loads* loads, IoModel* iomodel);
+
+		/*Finite element Analysis*/
+		void           Core(FemModel* femmodel);
+		ElementVector* CreateDVector(Element* element);
+		ElementMatrix* CreateJacobianMatrix(Element* element);
+		ElementMatrix* CreateKMatrix(Element* element);
+		ElementVector* CreatePVector(Element* element);
+		ElementVector* CreatePVectorVolume(Element* element);
+		ElementVector* CreatePVectorBoundary(Element* element);
+		void GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element);
+		void InputUpdateFromSolution(IssmDouble* solution,Element* element);
+		void UpdateConstraints(FemModel* femmodel);
+};
+#endif
Index: /issm/trunk/src/c/analyses/BalancethicknessAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/BalancethicknessAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/BalancethicknessAnalysis.cpp	(revision 17989)
@@ -10,4 +10,5 @@
 }/*}}}*/
 void BalancethicknessAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+	parameters->AddObject(iomodel->CopyConstantObject(BalancethicknessStabilizationEnum));
 }/*}}}*/
 void BalancethicknessAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
@@ -44,7 +45,7 @@
 	iomodel->FetchDataToInput(elements,BalancethicknessThickeningRateEnum);
 
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
Index: /issm/trunk/src/c/analyses/BalancevelocityAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/BalancevelocityAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/BalancevelocityAnalysis.cpp	(revision 17989)
@@ -33,7 +33,7 @@
 	iomodel->FetchDataToInput(elements,BalancethicknessThickeningRateEnum);
 
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
Index: /issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/EnthalpyAnalysis.cpp	(revision 17989)
@@ -17,4 +17,5 @@
 	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsenthalpyEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsdynamicbasalspcEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(FrictionLawEnum));
 
 	iomodel->FetchData(&requestedoutputs,&numoutputs,ThermalRequestedOutputsEnum);
@@ -25,6 +26,6 @@
 void EnthalpyAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
 
-	bool dakota_analysis, islevelset;
-	bool isenthalpy;
+	bool dakota_analysis,islevelset,isenthalpy;
+	int frictionlaw;
 
 	/*Now, is the model 3d? otherwise, do nothing: */
@@ -50,15 +51,15 @@
 	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
 	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
+	iomodel->Constant(&frictionlaw,FrictionLawEnum);
 
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
 	iomodel->FetchDataToInput(elements,BaseEnum);
-	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
-	iomodel->FetchDataToInput(elements,FrictionPEnum);
-	iomodel->FetchDataToInput(elements,FrictionQEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	iomodel->FetchDataToInput(elements,FlowequationElementEquationEnum);
 	iomodel->FetchDataToInput(elements,MaterialsRheologyBEnum);
@@ -88,5 +89,19 @@
 		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
 	}
-
+	
+	/*Friction law variables*/
+	switch(frictionlaw){
+		case 1:
+			iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
+			iomodel->FetchDataToInput(elements,FrictionPEnum);
+			iomodel->FetchDataToInput(elements,FrictionQEnum);
+			break;
+		case 2:
+			iomodel->FetchDataToInput(elements,FrictionCEnum);
+			iomodel->FetchDataToInput(elements,FrictionMEnum);
+			break;
+		default:
+			_error_("not supported");
+	}
 	/*Free data: */
 	iomodel->DeleteData(3,TemperatureEnum,WaterfractionEnum,PressureEnum);
@@ -243,5 +258,5 @@
 	element->FindParam(&dt,TimesteppingTimeStepEnum);
 	element->FindParam(&stabilization,ThermalStabilizationEnum);
-	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
@@ -371,5 +386,5 @@
 	element->FindParam(&dt,TimesteppingTimeStepEnum);
 	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
-	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
@@ -586,5 +601,5 @@
 			geothermalflux_input->GetInputValue(&geothermalflux,gauss);
 
-			friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+			friction->GetAlpha2(&alpha2,gauss);
 			vx_input->GetInputValue(&vx,gauss);
 			vy_input->GetInputValue(&vy,gauss);
@@ -646,5 +661,5 @@
 	Input*      pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);
 	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
-	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
@@ -909,5 +924,4 @@
 	IssmDouble  heatflux;
 	IssmDouble  vec_heatflux[dim],normal_base[dim],d1enthalpy[dim];
-	IssmDouble  temperature, waterfraction;
 	IssmDouble  basalfriction,alpha2;
 	IssmDouble  dt,yts;
@@ -924,5 +938,5 @@
 	IssmDouble latentheat = element->GetMaterialParameter(MaterialsLatentheatEnum);
 	IssmDouble rho_ice    = element->GetMaterialParameter(MaterialsRhoIceEnum);
-	IssmDouble rho_water  = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_water  = element->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
 	Input* enthalpy_input         = element->GetInput(EnthalpyEnum);                    _assert_(enthalpy_input);
 	Input* geothermalflux_input   = element->GetInput(BasalforcingsGeothermalfluxEnum); _assert_(geothermalflux_input);
@@ -988,5 +1002,5 @@
 
 			/*basal friction*/
-			friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+			friction->GetAlpha2(&alpha2,gauss);
 			vx_input->GetInputValue(&vx,gauss);
 			vy_input->GetInputValue(&vy,gauss);
@@ -994,9 +1008,8 @@
 			basalfriction=alpha2*(vx*vx + vy*vy + vz*vz);
 
-			element->EnthalpyToThermal(&temperature,&waterfraction,enthalpy[vertexdown],pressure[vertexdown]);
 			geothermalflux_input->GetInputValue(&geothermalflux,gauss);
-			/* -Mb= Fb-(q-q_geo)/((1-w)*L), cf Aschwanden 2012, eq.66*/
+			/* -Mb= Fb-(q-q_geo)/((1-w)*L*rho), and (1-w)*rho=rho_ice, cf Aschwanden 2012, eqs.1, 2, 66*/
 			heating[is]=(heatflux+basalfriction+geothermalflux);
-			meltingrate_enthalpy[is]=heating[is]/((1-waterfraction)*latentheat*rho_water); // m/s water equivalent
+			meltingrate_enthalpy[is]=heating[is]/(latentheat*rho_ice); // m/s water equivalent
 		}
 	}
@@ -1034,4 +1047,5 @@
 	delete gauss;
 	delete friction;
+	xDelete<int>(pairindices);
 	xDelete<IssmDouble>(enthalpy);
 	xDelete<IssmDouble>(pressure);
@@ -1041,4 +1055,5 @@
 	xDelete<IssmDouble>(heating);
 	xDelete<IssmDouble>(xyz_list);
+	xDelete<IssmDouble>(xyz_list_base);
 }/*}}}*/
 void EnthalpyAnalysis::DrainWaterfractionIcecolumn(Element* element){/*{{{*/
@@ -1103,5 +1118,5 @@
 	
 	rho_ice=element->GetMaterialParameter(MaterialsRhoIceEnum);
-	rho_water=element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	rho_water=element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 
 	element->GetVerticesCoordinates(&xyz_list);
Index: /issm/trunk/src/c/analyses/EnumToAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/EnumToAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/EnumToAnalysis.cpp	(revision 17989)
@@ -17,4 +17,7 @@
 		case AdjointBalancethicknessAnalysisEnum : return new AdjointBalancethicknessAnalysis();
 		#endif
+		#ifdef _HAVE_ADJOINTBALANCETHICKNESS2_
+		case AdjointBalancethickness2AnalysisEnum : return new AdjointBalancethickness2Analysis();
+		#endif
 		#ifdef _HAVE_ADJOINTHORIZ_
 		case AdjointHorizAnalysisEnum : return new AdjointHorizAnalysis();
@@ -22,4 +25,7 @@
 		#ifdef _HAVE_BALANCETHICKNESS_
 		case BalancethicknessAnalysisEnum : return new BalancethicknessAnalysis();
+		#endif
+		#ifdef _HAVE_BALANCETHICKNESS2_
+		case Balancethickness2AnalysisEnum : return new Balancethickness2Analysis();
 		#endif
 		#ifdef _HAVE_BALANCETHICKNESSSOFT_
Index: /issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/ExtrapolationAnalysis.cpp	(revision 17989)
@@ -30,7 +30,7 @@
 		}
 	}
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }
Index: /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/FreeSurfaceBaseAnalysis.cpp	(revision 17989)
@@ -35,8 +35,10 @@
 	iomodel->FetchDataToInput(elements,VxEnum);
 	iomodel->FetchDataToInput(elements,VyEnum);
-	if(iomodel->domaintype==Domain3DEnum){
+	if(iomodel->domaindim==3){
 		iomodel->FetchDataToInput(elements,VzEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	}
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
Index: /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp	(revision 17989)
@@ -35,9 +35,10 @@
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,VxEnum);
-	if(iomodel->domaintype!=Domain2DhorizontalEnum) iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
-	if(iomodel->domaintype==Domain3DEnum){
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+	}
+	if(iomodel->domaindim==3){
 		iomodel->FetchDataToInput(elements,VzEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
 	}
 	switch(smb_model){
Index: /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/HydrologyDCEfficientAnalysis.cpp	(revision 17989)
@@ -57,7 +57,8 @@
 	iomodel->FetchDataToInput(elements,HydrologydcSedimentTransmitivityEnum);
 	iomodel->FetchDataToInput(elements,HydrologydcEplThicknessEnum);
-	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-	
-	//	elements->InputDuplicate(HydrologydcEplInitialThicknessEnum,HydrologydcEplThicknessEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 
 }/*}}}*/
@@ -287,5 +288,5 @@
 			thickness_input ->GetInputValue(&epl_thickness,gauss);
 			
-			/*Dealing with the sediment part of the transfer term*/
+			/*Dealing with the epl part of the transfer term*/
 			transfer=GetHydrologyPVectorTransfer(basalelement,gauss,thickness_input,sed_head_input,epl_head_input,sed_trans_input,residual_input);
 			scalar = Jdet*gauss->weight*((water_head*epl_specificstoring*epl_thickness)+(transfer*dt));
@@ -409,16 +410,18 @@
 		residual_input->GetInputValue(&residual,gauss);
 		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
-
-		if(epl_head>sed_head){
-			if(residual>0.0){	
-				transfer=0.0;
-			}
-			else{
-				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity)/(sediment_thickness*leakage);
-			}
-		}
-		else{
-			transfer=(sediment_storing*sediment_transmitivity)/(sediment_thickness*leakage);
-		}
+		transfer=(sediment_transmitivity)/(sediment_thickness*leakage); 
+		/* if(epl_head>sed_head){ */
+		/* 	if(residual>0.0){	 */
+		/* 		transfer=0.0; */
+		/* 	} */
+		/* 	else{ */
+		/* 		transfer=(sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* 		//transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* 	} */
+		/* } */
+		/* else{ */
+		/* 	transfer=(sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* 	//transfer=(sediment_storing*sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* } */
 		break;
 	default:
@@ -460,16 +463,18 @@
 		residual_input->GetInputValue(&residual,gauss);
 		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
-		
-		if(epl_head>sediment_head){
-			if(residual>0.0){	
-				transfer=0.0;
-			}
-			else{
-				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity*sediment_head)/(sediment_thickness*leakage);
-			}
-		}
-		else{
-			transfer=(sediment_storing*sediment_transmitivity*sediment_head)/(sediment_thickness*leakage);
-		}
+		transfer=(sediment_transmitivity*sediment_head)/(sediment_thickness*leakage);
+		/* if(epl_head>sediment_head){ */
+		/* 	if(residual>0.0){	 */
+		/* 		transfer=0.0; */
+		/* 	} */
+		/* 	else{ */
+		/* 		transfer=(sediment_transmitivity*sediment_head)/(sediment_thickness*leakage); */
+		/* 		//transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity*sediment_head)/(sediment_thickness*leakage); */
+		/* 	} */
+		/* } */
+		/* else{ */
+		/* 	transfer=(sediment_transmitivity*sediment_head)/(sediment_thickness*leakage); */
+		/* 	//transfer=(sediment_storing*sediment_transmitivity*sediment_head)/(sediment_thickness*leakage); */
+		/* } */
 		break;
 	default:
Index: /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/HydrologyDCInefficientAnalysis.cpp	(revision 17989)
@@ -88,5 +88,8 @@
 	iomodel->FetchDataToInput(elements,SedimentHeadEnum);
 	iomodel->FetchDataToInput(elements,HydrologydcSedimentTransmitivityEnum);
-	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 
 	if(isefficientlayer)iomodel->FetchDataToInput(elements,HydrologydcMaskEplactiveNodeEnum);
@@ -326,4 +329,5 @@
 
 		scalar = Jdet*gauss->weight*(water_load);
+
 		if(dt!=0.) scalar = scalar*dt;
 		for(int i=0;i<numnodes;i++){
@@ -425,7 +429,5 @@
 	/*Get inputs*/
 	if(converged){
-		IssmDouble penalty_factor,kmax,kappa,h_max;
-		IssmDouble rho_freshwater,rho_ice;
-		IssmDouble g;
+		IssmDouble  penalty_factor,kmax,kappa,h_max;
 		IssmDouble* thickness = xNew<IssmDouble>(numnodes);
 		IssmDouble* base      = xNew<IssmDouble>(numnodes);
@@ -433,7 +435,7 @@
 		basalelement->FindParam(&kmax,HydrologySedimentKmaxEnum);
 		basalelement->FindParam(&penalty_factor,HydrologydcPenaltyFactorEnum);
-		basalelement->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
-		basalelement->GetMaterialParameter(MaterialsRhoIceEnum);
-		basalelement->GetMaterialParameter(ConstantsGEnum);
+		IssmDouble rho_freshwater = basalelement->GetMaterialParameter(MaterialsRhoFreshwaterEnum);
+		IssmDouble rho_ice        = basalelement->GetMaterialParameter(MaterialsRhoIceEnum);
+		IssmDouble g              = basalelement->GetMaterialParameter(ConstantsGEnum);
 		
 		basalelement->GetInputListOnVertices(thickness,ThicknessEnum);
@@ -447,10 +449,9 @@
 			if(values[i]>h_max) {
 				residual[i] = kappa*(values[i]-h_max);
-				pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(values[i]-base[i]));
 			}
 			else{
 				residual[i] = 0.;
-				pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(h_max-base[i]));
 			}
+			pressure[i]=(rho_ice*g*thickness[i])-(rho_freshwater*g*(min(h_max,values[i])-base[i]));
 		}
 		xDelete<IssmDouble>(thickness);
@@ -600,17 +601,19 @@
 		sed_trans_input->GetInputValue(&sediment_transmitivity,gauss);
 		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
-	
-		if(epl_head>sed_head){
-			h_max=GetHydrologyDCInefficientHmax(element,gauss,thickness_input,base_input);
-			if(sed_head>=h_max){
-				transfer=0.0;
-			}
-			else{
-				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity)/(sediment_thickness*leakage);
-			}
-		}
-		else{
-			transfer=(sediment_storing*sediment_transmitivity)/(sediment_thickness*leakage);
-		}
+		transfer=(sediment_transmitivity)/(sediment_thickness*leakage);
+		/* if(epl_head>sed_head){ */
+		/* 	h_max=GetHydrologyDCInefficientHmax(element,gauss,thickness_input,base_input); */
+		/* 	if(sed_head>=h_max){ */
+		/* 		transfer=0.0; */
+		/* 	} */
+		/* 	else{ */
+		/* 		transfer=(sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* 		//transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* 	} */
+		/* } */
+		/* else{ */
+		/* 	transfer=(sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* 	//transfer=(sediment_storing*sediment_transmitivity)/(sediment_thickness*leakage); */
+		/* } */
 		break;
 	default:
@@ -655,17 +658,19 @@
 
 		element->FindParam(&leakage,HydrologydcLeakageFactorEnum);
-
-		if(epl_head>sediment_head){
-			h_max=GetHydrologyDCInefficientHmax(element,gauss,thickness_input,base_input);
-			if(sediment_head>=h_max){
-				transfer=0.0;
-			}
-			else{
-				transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity*epl_head)/(sediment_thickness*leakage);
-			}
-		}
-		else{
-			transfer=(sediment_storing*sediment_transmitivity*epl_head)/(sediment_thickness*leakage);
-		}
+ 		transfer=(sediment_transmitivity*epl_head)/(sediment_thickness*leakage);
+		/* if(epl_head>sediment_head){ */
+		/* 	h_max=GetHydrologyDCInefficientHmax(element,gauss,thickness_input,base_input); */
+ 		/* 	if(sediment_head>=h_max){ */
+		/* 		transfer=0.0; */
+		/* 	} */
+		/* 	else{ */
+		/* 		transfer=(sediment_transmitivity*epl_head)/(sediment_thickness*leakage); */
+		/* 		//transfer=(epl_specificstoring*epl_thickness*sediment_transmitivity*epl_head)/(sediment_thickness*leakage); */
+		/* 	} */
+		/* } */
+		/* else{ */
+		/* 	transfer=(sediment_transmitivity*epl_head)/(sediment_thickness*leakage); */
+		/* 	//transfer=(sediment_storing*sediment_transmitivity*epl_head)/(sediment_thickness*leakage); */
+		/* } */
 		break;
 	default:
Index: /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/HydrologyShreveAnalysis.cpp	(revision 17989)
@@ -44,6 +44,8 @@
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
 	iomodel->FetchDataToInput(elements,BaseEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
@@ -329,8 +331,6 @@
 	/*Retrieve all inputs and parameters*/
 	IssmDouble  rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
-	IssmDouble  rho_water = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  g         = element->GetMaterialParameter(ConstantsGEnum);
-	IssmDouble  CR        = element->GetMaterialParameter(HydrologyshreveCREnum);
-	IssmDouble  n_man     = element->GetMaterialParameter(HydrologyshreveNEnum);
 	IssmDouble  mu_water  = element->GetMaterialParameter(MaterialsMuWaterEnum);
 	Input* surfaceslopex_input = element->GetInput(SurfaceSlopeXEnum); _assert_(surfaceslopex_input);
@@ -339,7 +339,4 @@
 	Input* bedslopey_input     = element->GetInput(BedSlopeYEnum);     _assert_(bedslopey_input);
 	Input* watercolumn_input   = element->GetInput(WatercolumnEnum);   _assert_(watercolumn_input);
-
-	/* compute VelocityFactor */
-	IssmDouble VelocityFactor = n_man*CR*CR*rho_water*g/mu_water;
 
 	/*Fetch number of vertices and allocate output*/
@@ -358,8 +355,6 @@
 
 		/* Water velocity x and y components */
-	//	vx[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
-	//	vy[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
-		vx[iv]= - w*w/(VelocityFactor* mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
-		vy[iv]= - w*w/(VelocityFactor* mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
+		vx[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
+		vy[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
 	}
 
@@ -373,2 +368,25 @@
 	xDelete<IssmDouble>(vy);
 }/*}}}*/
+
+
+
+/*Needed changes to switch to the Johnson formulation*//*{{{*/
+/*All the changes are to be done in the velocity computation.
+	The new velocity needs some new parameter that should be introduce in the hydrologyshreve class:
+	'p' and 'q' which are the exponent of the Manning formula for laminar (p=2,q=1) or turbulent (p=2/3,q=1/2) flow
+	'R' the hydraulic radius
+	'n' the manning roughness coeficient
+
+	With these, the velocity reads ;
+
+	v= - (1/n)* pow(R,p)*pow((grad phi(rho_water*g)),q)
+
+	you should also redefine the water pressure potential 'phi' with respect to the effective pressure deffinition given in Johson:
+	phi=(rho_ice*g*( surface + ((rho_water/rho_ice)-1)*base - k_n*((thickness* grad(base))/omega) )
+
+	where 
+	'omega' is the fractional area of the base occupied by the water film
+	'k_n' is a parameter
+	This last equation derives from the effective pressure definition developped in Alley 1989
+*/
+/*}}}*/
Index: /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/L2ProjectionBaseAnalysis.cpp	(revision 17989)
@@ -26,13 +26,7 @@
 	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->domaintype==Domain3DEnum){
-		if(iomodel->meshelementtype==PentaEnum){
-			iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-			iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-		}
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
 		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
-	}
-	if(iomodel->domaintype==Domain2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
Index: /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/L2ProjectionEPLAnalysis.cpp	(revision 17989)
@@ -36,6 +36,7 @@
 	iomodel->FetchDataToInput(elements,EplHeadEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
Index: /issm/trunk/src/c/analyses/LevelsetAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/LevelsetAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/LevelsetAnalysis.cpp	(revision 17989)
@@ -89,55 +89,8 @@
 ElementMatrix* LevelsetAnalysis::CreateKMatrix(Element* element){/*{{{*/
 
-	_error_("NOT IMPLEMENTED YET");
-
+	_error_("not implemented yet");
 }/*}}}*/
 ElementVector* LevelsetAnalysis::CreatePVector(Element* element){/*{{{*/
-	
-	if(!element->IsOnBase()) return NULL;
-	Element* basalelement = element->SpawnBasalElement();
-
-	/*Intermediaries */
-	int i, ig, domaintype;
-	IssmDouble  Jdet,dt;
-	IssmDouble  lsf;
-	IssmDouble* xyz_list = NULL;
-	
-	/*Fetch number of nodes and dof for this finite element*/
-	int numnodes = basalelement->GetNumberOfNodes();
-
-	/*Initialize Element vector*/
-	ElementVector* pe = basalelement->NewElementVector();
-	basalelement->FindParam(&dt,TimesteppingTimeStepEnum);
-	
-	if(dt!=0.){
-		/*Initialize basis vector*/
-		IssmDouble*    basis = xNew<IssmDouble>(numnodes);
-
-		/*Retrieve all inputs and parameters*/
-		basalelement->GetVerticesCoordinates(&xyz_list);
-		Input* levelset_input     = basalelement->GetInput(MaskIceLevelsetEnum);                    _assert_(levelset_input);
-
-		/* Start  looping on the number of gaussian points: */
-		Gauss* gauss=basalelement->NewGauss(2);
-		for(ig=gauss->begin();ig<gauss->end();ig++){
-			gauss->GaussPoint(ig);
-
-			basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
-			basalelement->NodalFunctions(basis,gauss);
-
-			/* old function value */
-			levelset_input->GetInputValue(&lsf,gauss);
-			for(i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*lsf*basis[i];
-		}
-
-		/*Clean up and return*/
-		xDelete<IssmDouble>(xyz_list);
-		xDelete<IssmDouble>(basis);
-		basalelement->FindParam(&domaintype,DomainTypeEnum);
-		if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
-		delete gauss;
-	}
-
-	return pe;
+	_error_("not implemented yet");
 }/*}}}*/
 void LevelsetAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/
Index: /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/LsfReinitializationAnalysis.cpp	(revision 17989)
@@ -112,5 +112,5 @@
 	/*Intermediaries */
 	const int dim = 2;
-	int        i,row,col,stabilization;
+	int        row,col,stabilization;
 	IssmDouble Jdet,D_scalar;
 	IssmDouble dtau = 1.;
@@ -399,5 +399,5 @@
 
 	/* Intermediaries */
-	int i,k;
+	int i;
 	IssmDouble dmaxp,dmaxm,val;
 	Element* element;
Index: /issm/trunk/src/c/analyses/MasstransportAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/MasstransportAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/MasstransportAnalysis.cpp	(revision 17989)
@@ -32,6 +32,4 @@
 	int    stabilization,finiteelement,smb_model;
 	bool   dakota_analysis;
-	bool   issmbgradients;
-	bool   ispdd;
 	bool   isdelta18o;
 	bool   isgroundingline;
@@ -83,13 +81,11 @@
 	}
 
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 
 	if(islevelset){
 		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
-		if(iomodel->domaintype!=Domain2DhorizontalEnum)
-			iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
 	}
 
@@ -715,5 +711,5 @@
 	basalelement->FindParam(&hydroadjustment,MasstransportHydrostaticAdjustmentEnum);
 	rho_ice   = basalelement->GetMaterialParameter(MaterialsRhoIceEnum);
-	rho_water = basalelement->GetMaterialParameter(MaterialsRhoWaterEnum);
+	rho_water = basalelement->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 
 	for(i=0;i<numnodes;i++) {
Index: /issm/trunk/src/c/analyses/MeltingAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/MeltingAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/MeltingAnalysis.cpp	(revision 17989)
@@ -10,6 +10,9 @@
 }/*}}}*/
 void MeltingAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/
+	parameters->AddObject(iomodel->CopyConstantObject(FrictionLawEnum));
 }/*}}}*/
 void MeltingAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
+
+	int frictionlaw;
 
 	/*Now, is the model 3d? otherwise, do nothing: */
@@ -26,14 +29,15 @@
 	}
 
+	iomodel->Constant(&frictionlaw,FrictionLawEnum);
+
 	/*Create inputs: */
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
 	iomodel->FetchDataToInput(elements,BaseEnum);
-	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
-	iomodel->FetchDataToInput(elements,FrictionPEnum);
-	iomodel->FetchDataToInput(elements,FrictionQEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	iomodel->FetchDataToInput(elements,FlowequationElementEquationEnum);
 	iomodel->FetchDataToInput(elements,MaterialsRheologyBEnum);
@@ -41,4 +45,19 @@
 	iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
 	iomodel->FetchDataToInput(elements,PressureEnum);
+	
+	/*Friction law variables*/
+	switch(frictionlaw){
+		case 1:
+			iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
+			iomodel->FetchDataToInput(elements,FrictionPEnum);
+			iomodel->FetchDataToInput(elements,FrictionQEnum);
+			break;
+		case 2:
+			iomodel->FetchDataToInput(elements,FrictionCEnum);
+			iomodel->FetchDataToInput(elements,FrictionMEnum);
+			break;
+		default:
+			_error_("not supported");
+	}
 }/*}}}*/
 void MeltingAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
Index: /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeXAnalysis.cpp	(revision 17989)
@@ -26,10 +26,7 @@
 	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-	}
-	if(iomodel->domaintype==Domain2DverticalEnum){
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
 		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
Index: /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/SmoothedSurfaceSlopeYAnalysis.cpp	(revision 17989)
@@ -26,10 +26,7 @@
 	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->domaintype==Domain3DEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-	}
-	if(iomodel->domaintype==Domain2DverticalEnum){
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
 		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	}
 }/*}}}*/
@@ -122,5 +119,4 @@
 
 	/*Intermediaries */
-	int         input_enum;
 	IssmDouble  Jdet,thickness,slope[2];
 	IssmDouble  taud_y,norms,normv,vx,vy;
Index: /issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/StressbalanceAnalysis.cpp	(revision 17989)
@@ -106,4 +106,5 @@
 	parameters->AddObject(iomodel->CopyConstantObject(StressbalanceShelfDampeningEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(StressbalanceViscosityOvershootEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(FrictionLawEnum));
 
 	/*XTH parameters*/
@@ -125,5 +126,5 @@
 	/*Intermediaries*/
 	int    materials_type,finiteelement;
-	int    approximation;
+	int    approximation,frictionlaw;
 	int*   finiteelement_list=NULL;
 	bool   isSSA,isL1L2,isHO,isFS,iscoupling;
@@ -142,4 +143,5 @@
 	iomodel->Constant(&materials_type,MaterialsEnum);
 	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
+	iomodel->Constant(&frictionlaw,FrictionLawEnum);
 
 	/*return if no processing required*/
@@ -205,7 +207,4 @@
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
 	iomodel->FetchDataToInput(elements,BaseEnum);
-	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
-	iomodel->FetchDataToInput(elements,FrictionPEnum);
-	iomodel->FetchDataToInput(elements,FrictionQEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
@@ -220,10 +219,9 @@
 	if(isdamage)iomodel->FetchDataToInput(elements,DamageDEnum);
 
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	if(iomodel->domaintype==Domain3DEnum){
-		if(iomodel->meshelementtype==PentaEnum){
-			iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-			iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-		}
-		iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
 		iomodel->FetchDataToInput(elements,FlowequationBorderFSEnum);
 		iomodel->FetchDataToInput(elements,LoadingforceZEnum);
@@ -231,16 +229,26 @@
 		if(dakota_analysis)elements->InputDuplicate(VzEnum,QmuVzEnum);
 	}
-	if(iomodel->domaintype==Domain2DverticalEnum){
-		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
-	}
 	if(isFS){
-		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
 		iomodel->FetchDataToInput(elements,PressureEnum,0.);
+		iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum,0.);
 		if(dakota_analysis)elements->InputDuplicate(PressureEnum,QmuPressureEnum);
 	}
 	if(islevelset){
 		iomodel->FetchDataToInput(elements,IceMaskNodeActivationEnum);
-		if(iomodel->domaintype!=Domain2DhorizontalEnum)
-			iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
+	}
+
+	/*Friction law variables*/
+	switch(frictionlaw){
+		case 1:
+			iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
+			iomodel->FetchDataToInput(elements,FrictionPEnum);
+			iomodel->FetchDataToInput(elements,FrictionQEnum);
+			break;
+		case 2:
+			iomodel->FetchDataToInput(elements,FrictionCEnum);
+			iomodel->FetchDataToInput(elements,FrictionMEnum);
+			break;
+		default:
+			_error_("not supported");
 	}
 
@@ -1227,8 +1235,5 @@
 	element->FindParam(&migration_style,GroundinglineMigrationEnum);
 	Input* surface_input    = element->GetInput(SurfaceEnum); _assert_(surface_input);
-	Input* vx_input         = element->GetInput(VxEnum);      _assert_(vx_input);
 	Input* gllevelset_input = NULL;
-	Input* vy_input         = NULL;
-	if(dim==2){vy_input     = element->GetInput(VyEnum);      _assert_(vy_input);}
 
 	/*build friction object, used later on: */
@@ -1250,5 +1255,5 @@
 		gauss->GaussPoint(ig);
 
-		friction->GetAlpha2(&alpha2, gauss,vx_input,vy_input,NULL);
+		friction->GetAlpha2(&alpha2,gauss);
 		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
 		if(migration_style==SubelementMigration2Enum){
@@ -1486,5 +1491,5 @@
 	Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input);
 	Input* base_input       = element->GetInput(BaseEnum);       _assert_(base_input);
-	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
@@ -1938,5 +1943,5 @@
 	Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input);
 	Input* base_input       = element->GetInput(BaseEnum);       _assert_(base_input);
-	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
@@ -2255,9 +2260,5 @@
 	element->GetVerticesCoordinatesBase(&xyz_list_base);
 	element->FindParam(&migration_style,GroundinglineMigrationEnum);
-	Input* vx_input = element->GetInput(VxEnum);   _assert_(vx_input);
-	Input* vy_input = element->GetInput(VyEnum);   _assert_(vy_input);
-	Input* vz_input = NULL;
 	Input* gllevelset_input = NULL;
-	if(dim==3){vz_input=element->GetInput(VzEnum); _assert_(vz_input);}
 
 	/*build friction object, used later on: */
@@ -2280,5 +2281,5 @@
 		gauss->GaussPoint(ig);
 
-		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2,gauss);
 		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
 		if(migration_style==SubelementMigration2Enum){
@@ -2341,7 +2342,7 @@
 		element->NodalFunctions(basis, gauss);
 
-		x_coord=element->GetXcoord(gauss);
-		y_coord=element->GetYcoord(gauss);
-		if(dim==3) z_coord=element->GetZcoord(gauss);
+		x_coord=element->GetXcoord(xyz_list,gauss);
+		y_coord=element->GetYcoord(xyz_list,gauss);
+		if(dim==3) z_coord=element->GetZcoord(xyz_list,gauss);
 		else z_coord=0.;
 
@@ -2460,5 +2461,5 @@
 	/*Retrieve all inputs and parameters*/
 	Input* surface_input = element->GetInput(SurfaceEnum); _assert_(surface_input);
-	IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble rho_ice   = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble gravity   = element->GetMaterialParameter(ConstantsGEnum);
@@ -2478,6 +2479,6 @@
 		gauss->GaussPoint(ig);
 		surface_input->GetInputValue(&surface,gauss);
-		if(dim==3) z=element->GetZcoord(gauss);
-		else       z=element->GetYcoord(gauss);
+		if(dim==3) z=element->GetZcoord(xyz_list,gauss);
+		else       z=element->GetYcoord(xyz_list,gauss);
 		element->NodalFunctions(basis,gauss);
 		element->JacobianDeterminantSurface(&Jdet,xyz_list_front,gauss);
@@ -3025,5 +3026,5 @@
 	element->FindParam(&dt,TimesteppingTimeStepEnum);
 	if(dt==0)   dt=1.e+5;
-	IssmDouble  rho_water     = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water     = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  gravity       = element->GetMaterialParameter(ConstantsGEnum);
 	Input*      surface_input = element->GetInput(SurfaceEnum); _assert_(surface_input);
@@ -3098,7 +3099,7 @@
 		gauss->GaussPoint(ig);
 
-		x_coord=element->GetXcoord(gauss);
-		y_coord=element->GetYcoord(gauss);
-		if(dim==3) z_coord=element->GetZcoord(gauss);
+		x_coord=element->GetXcoord(xyz_list,gauss);
+		y_coord=element->GetYcoord(xyz_list,gauss);
+		if(dim==3) z_coord=element->GetZcoord(xyz_list,gauss);
 		else z_coord=0.;
 
@@ -3159,7 +3160,7 @@
 		element->NodalFunctionsVelocity(vbasis,gauss);
 
-		x_coord=element->GetXcoord(gauss);
-		y_coord=element->GetYcoord(gauss);
-		if(dim==3) z_coord=element->GetZcoord(gauss);
+		x_coord=element->GetXcoord(xyz_list,gauss);
+		y_coord=element->GetYcoord(xyz_list,gauss);
+		if(dim==3) z_coord=element->GetZcoord(xyz_list,gauss);
 		else z_coord=0.;
 
@@ -3204,5 +3205,5 @@
 	/*Intermediaries*/
 	bool        mainlyfloating;
-	int         i,dim,domaintype,epssize;
+	int         dim,domaintype;
 	int         migration_style,point1;
 	IssmDouble  alpha2,Jdet,fraction1,fraction2;
@@ -3228,8 +3229,4 @@
 	element->GetVerticesCoordinatesBase(&xyz_list_base);
 	element->FindParam(&migration_style,GroundinglineMigrationEnum);
-	Input* vx_input         = element->GetInput(VxEnum);      _assert_(vx_input);
-	Input* vy_input         = element->GetInput(VyEnum);      _assert_(vy_input);
-	Input* vz_input         = NULL;
-	if(dim==3){    vz_input = element->GetInput(VzEnum);      _assert_(vz_input);}
 	Input* gllevelset_input = NULL;
 
@@ -3254,5 +3251,5 @@
 		gauss->GaussPoint(ig);
 
-		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2,gauss);
 		if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;
 		if(migration_style==SubelementMigration2Enum){
@@ -3586,5 +3583,5 @@
 	element->GetVerticesCoordinatesBase(&xyz_list_base);
 	Input*      base_input=element->GetInput(BaseEnum); _assert_(base_input);
-	IssmDouble  rho_water=element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water=element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  gravity  =element->GetMaterialParameter(ConstantsGEnum);
 
@@ -3613,4 +3610,25 @@
 	/*Transform coordinate system*/
 	element->TransformLoadVectorCoord(pe,cs_list);
+
+	/* shelf dampening*/
+	int shelf_dampening;
+	element->FindParam(&shelf_dampening,StressbalanceShelfDampeningEnum);
+	if(shelf_dampening) {
+		Input*      mb_input=element->GetInput(BasalforcingsMeltingRateEnum); _assert_(mb_input);
+		IssmDouble dt,mb,normal_b;
+		element->FindParam(&dt,TimesteppingTimeStepEnum);
+		for(int ig=gauss->begin();ig<gauss->end();ig++){
+			gauss->GaussPoint(ig);
+			element->JacobianDeterminantBase(&Jdet,xyz_list_base,gauss);
+			element->NodalFunctionsVelocity(vbasis,gauss);
+			element->NormalBase(&normal[0],xyz_list_base);
+			if (dim==2) normal_b=normal[1];
+			else if (dim==3) normal_b=sqrt(normal[0]*normal[0]+normal[1]*normal[1]);
+			mb_input->GetInputValue(&mb, gauss);
+			for(i=0;i<vnumnodes;i++){
+				pe->values[i*dim+1] += dt*rho_water*gravity*mb*gauss->weight*Jdet*vbasis[i]*normal_b;
+			}
+		}
+	}
 
 	/*Clean up and return*/
@@ -3660,5 +3678,5 @@
 	element->NormalSection(&normal[0],xyz_list_front);
 	Input* surface_input  = element->GetInput(SurfaceEnum); _assert_(surface_input);
-	IssmDouble  rho_water = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  gravity   = element->GetMaterialParameter(ConstantsGEnum);
 
@@ -3676,6 +3694,6 @@
 		element->NodalFunctionsVelocity(vbasis,gauss);
 		surface_input->GetInputValue(&surface,gauss);
-		if(dim==3) z=element->GetZcoord(gauss);
-		else       z=element->GetYcoord(gauss);
+		if(dim==3) z=element->GetZcoord(xyz_list,gauss);
+		else       z=element->GetYcoord(xyz_list,gauss);
 		pressure = rho_water*gravity*min(0.,z);//0 if the gaussian point is above water level
 
@@ -4820,7 +4838,4 @@
 	/*retrieve inputs :*/
 	element->GetVerticesCoordinatesBase(&xyz_list_tria);
-	Input* vx_input=element->GetInput(VxEnum);  _assert_(vx_input);
-	Input* vy_input=element->GetInput(VyEnum);  _assert_(vy_input);
-	Input* vz_input=element->GetInput(VzEnum);  _assert_(vz_input);
 
 	/*build friction object, used later on: */
@@ -4834,5 +4849,5 @@
 
 		/*Friction: */
-		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2,gauss);
 		element->JacobianDeterminantBase(&Jdet2d, xyz_list_tria,gauss);
 		this->GetBHOFriction(L,element,3,xyz_list_tria,gauss);
@@ -5045,5 +5060,5 @@
 
 		element->NormalBase(&bed_normal[0],xyz_list_tria);
-		friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2_gauss,gauss);
 
 		DLSSAFS[0][0]=alpha2_gauss*gauss->weight*Jdet2d;
@@ -5266,5 +5281,5 @@
 
 	/*Intermediaries*/
-	int         i,j,approximation;
+	int         i,approximation;
 	int         dim=3;
 	IssmDouble  Jdet,Jdet2d,FSreconditioning;
@@ -5325,5 +5340,5 @@
 		element->NormalBase(&bed_normal[0],xyz_list_tria);
 		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
-		friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2_gauss,gauss);
 
 		for(i=0;i<3;i++){
@@ -5486,5 +5501,5 @@
 		element->NormalBase(&bed_normal[0],xyz_list_tria);
 		element->ViscosityFS(&viscosity,dim,xyz_list,gauss,vx_input,vy_input,vz_input);
-		friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2_gauss,gauss);
 
 		for(i=0;i<3;i++){
Index: /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/StressbalanceSIAAnalysis.cpp	(revision 17989)
@@ -405,5 +405,5 @@
 			constant_part=-2.*pow(rho_ice*gravity,n)*pow(slope2,((n-1.)/2.));
 
-			z = element->GetZcoord(gauss);
+			z = element->GetZcoord(xyz_list,gauss);
 			element->JacobianDeterminantLine(&Jdet,&xyz_list_line[0][0],gauss);
 
Index: /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/StressbalanceVerticalAnalysis.cpp	(revision 17989)
@@ -34,9 +34,8 @@
 	iomodel->FetchDataToInput(elements,BaseEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
-	if(iomodel->meshelementtype==PentaEnum){
-		iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-		iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
-	}
-	iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	iomodel->FetchDataToInput(elements,BasalforcingsMeltingRateEnum);
 	iomodel->FetchDataToInput(elements,VxEnum,0.);
Index: /issm/trunk/src/c/analyses/ThermalAnalysis.cpp
===================================================================
--- /issm/trunk/src/c/analyses/ThermalAnalysis.cpp	(revision 17988)
+++ /issm/trunk/src/c/analyses/ThermalAnalysis.cpp	(revision 17989)
@@ -21,4 +21,5 @@
 	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsenthalpyEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(ThermalIsdynamicbasalspcEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(FrictionLawEnum));
 
 	iomodel->FetchData(&requestedoutputs,&numoutputs,ThermalRequestedOutputsEnum);
@@ -30,13 +31,16 @@
 void ThermalAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/
 
+	int frictionlaw;
+
 	/*Now, is the model 3d? otherwise, do nothing: */
 	if(iomodel->domaintype==Domain2DhorizontalEnum)return;
 
 	/*Update elements: */
+	int finiteelement = P1Enum;
 	int counter=0;
 	for(int i=0;i<iomodel->numberofelements;i++){
 		if(iomodel->my_elements[i]){
 			Element* element=(Element*)elements->GetObjectByOffset(counter);
-			element->Update(i,iomodel,analysis_counter,analysis_type,P1Enum);
+			element->Update(i,iomodel,analysis_counter,analysis_type,finiteelement);
 			counter++;
 		}
@@ -46,16 +50,18 @@
 	iomodel->Constant(&dakota_analysis,QmuIsdakotaEnum);
 	iomodel->Constant(&islevelset,TransientIslevelsetEnum);
+	iomodel->Constant(&frictionlaw,FrictionLawEnum);
 
 	iomodel->FetchDataToInput(elements,ThicknessEnum);
 	iomodel->FetchDataToInput(elements,SurfaceEnum);
 	iomodel->FetchDataToInput(elements,BaseEnum);
-	iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
-	iomodel->FetchDataToInput(elements,FrictionPEnum);
-	iomodel->FetchDataToInput(elements,FrictionQEnum);
 	iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum);
 	iomodel->FetchDataToInput(elements,MaskGroundediceLevelsetEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonbaseEnum);
-	iomodel->FetchDataToInput(elements,MeshElementonsurfaceEnum);
+	if(iomodel->domaintype!=Domain2DhorizontalEnum){
+		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+		iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
+	}
 	iomodel->FetchDataToInput(elements,FlowequationElementEquationEnum);
+	iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum);
+	iomodel->FetchDataToInput(elements,MeshVertexonsurfaceEnum);
 	iomodel->FetchDataToInput(elements,MaterialsRheologyBEnum);
 	iomodel->FetchDataToInput(elements,MaterialsRheologyNEnum);
@@ -80,9 +86,24 @@
 		iomodel->FetchDataToInput(elements,MeshVertexonbaseEnum); // required for updating active nodes
 	}
+	/*Friction law variables*/
+	switch(frictionlaw){
+		case 1:
+			iomodel->FetchDataToInput(elements,FrictionCoefficientEnum);
+			iomodel->FetchDataToInput(elements,FrictionPEnum);
+			iomodel->FetchDataToInput(elements,FrictionQEnum);
+			break;
+		case 2:
+			iomodel->FetchDataToInput(elements,FrictionCEnum);
+			iomodel->FetchDataToInput(elements,FrictionMEnum);
+			break;
+		default:
+			_error_("not supported");
+	}
 }/*}}}*/
 void ThermalAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/
 
+	int finiteelement = P1Enum;
 	if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
-	::CreateNodes(nodes,iomodel,ThermalAnalysisEnum,P1Enum);
+	::CreateNodes(nodes,iomodel,ThermalAnalysisEnum,finiteelement);
 	iomodel->DeleteData(2,MeshVertexonbaseEnum,MeshVertexonsurfaceEnum);
 }/*}}}*/
@@ -90,6 +111,7 @@
 
 	/*Only 3d mesh supported*/
+	int finiteelement = P1Enum;
 	if(iomodel->domaintype==Domain3DEnum){
-		IoModelToConstraintsx(constraints,iomodel,ThermalSpctemperatureEnum,ThermalAnalysisEnum,P1Enum);
+		IoModelToConstraintsx(constraints,iomodel,ThermalSpctemperatureEnum,ThermalAnalysisEnum,finiteelement);
 	}
 
@@ -171,5 +193,5 @@
 	element->FindParam(&dt,TimesteppingTimeStepEnum);
 	element->FindParam(&stabilization,ThermalStabilizationEnum);
-	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
@@ -300,5 +322,5 @@
 	element->FindParam(&dt,TimesteppingTimeStepEnum);
 	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
-	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
@@ -469,5 +491,5 @@
 
 		geothermalflux_input->GetInputValue(&geothermalflux,gauss);
-		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlpha2(&alpha2,gauss);
 		vx_input->GetInputValue(&vx,gauss);
 		vy_input->GetInputValue(&vy,gauss);
@@ -513,5 +535,5 @@
 	Input*      pressure_input=element->GetInput(PressureEnum); _assert_(pressure_input);
 	IssmDouble  gravity             = element->GetMaterialParameter(ConstantsGEnum);
-	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble  rho_water           = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble  rho_ice             = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble  heatcapacity        = element->GetMaterialParameter(MaterialsHeatcapacityEnum);
Index: /issm/trunk/src/c/analyses/analyses.h
===================================================================
--- /issm/trunk/src/c/analyses/analyses.h	(revision 17988)
+++ /issm/trunk/src/c/analyses/analyses.h	(revision 17989)
@@ -9,6 +9,8 @@
 
 #include "./AdjointBalancethicknessAnalysis.h"
+#include "./AdjointBalancethickness2Analysis.h"
 #include "./AdjointHorizAnalysis.h"
 #include "./BalancethicknessAnalysis.h"
+#include "./Balancethickness2Analysis.h"
 #include "./BalancethicknessSoftAnalysis.h"
 #include "./BalancevelocityAnalysis.h"
Index: /issm/trunk/src/c/classes/Elements/Element.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Element.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Element.cpp	(revision 17989)
@@ -33,5 +33,5 @@
 
 /*Other*/
-void Element::AddInput(Input* input_in){/*{{{*/
+void       Element::AddInput(Input* input_in){/*{{{*/
 
 	/*Call inputs method*/
@@ -39,21 +39,5 @@
 	this->inputs->AddInput(input_in);
 }/*}}}*/
-/* bool Element::AllActive(void){/\*{{{*\/ */
-
-/* 	int numnodes = this->GetNumberOfNodes(); */
-/* 	for(int i=0;i<numnodes;i++){ */
-/* 		if(!this->nodes[i]->IsActive()) return false; */
-/* 	} */
-/* 	return true; */
-/* }/\*}}}*\/ */
-/* bool Element::AnyActive(void){/\*{{{*\/ */
-
-/* 	int numnodes = this->GetNumberOfNodes(); */
-/* 	for(int i=0;i<numnodes;i++){ */
-/* 		if(this->nodes[i]->IsActive()) return true; */
-/* 	} */
-/* 	return false; */
-/* }/\*}}}*\/ */
-void Element::CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+void       Element::CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
 
 	int         i,counter;
@@ -129,8 +113,8 @@
 }
 /*}}}*/
-void Element::DeleteMaterials(void){/*{{{*/
+void       Element::DeleteMaterials(void){/*{{{*/
 	delete this->material;
 }/*}}}*/
-void Element::DeepEcho(void){/*{{{*/
+void       Element::DeepEcho(void){/*{{{*/
 
 	_printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
@@ -166,5 +150,5 @@
 }
 /*}}}*/
-void Element::Echo(void){/*{{{*/
+void       Element::Echo(void){/*{{{*/
 	_printf_(EnumToStringx(this->ObjectEnum())<<" element:\n");
 	_printf_("   id : "<<this->id <<"\n");
@@ -229,8 +213,8 @@
 	return divergence;
 }/*}}}*/
-void Element::ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure){/*{{{*/
+void       Element::ThermalToEnthalpy(IssmDouble* penthalpy,IssmDouble temperature,IssmDouble waterfraction,IssmDouble pressure){/*{{{*/
 	matpar->ThermalToEnthalpy(penthalpy,temperature,waterfraction,pressure);
 }/*}}}*/
-void Element::EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
+void       Element::EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
 	matpar->EnthalpyToThermal(ptemperature,pwaterfraction,enthalpy,pressure);
 }/*}}}*/
@@ -241,17 +225,17 @@
 	return matpar->GetEnthalpyDiffusionParameterVolume(numvertices,enthalpy,pressure);
 }/*}}}*/
-void Element::FindParam(bool* pvalue,int paramenum){/*{{{*/
+void       Element::FindParam(bool* pvalue,int paramenum){/*{{{*/
 	this->parameters->FindParam(pvalue,paramenum);
 }/*}}}*/
-void Element::FindParam(int* pvalue,int paramenum){/*{{{*/
+void       Element::FindParam(int* pvalue,int paramenum){/*{{{*/
 	this->parameters->FindParam(pvalue,paramenum);
 }/*}}}*/
-void Element::FindParam(IssmDouble* pvalue,int paramenum){/*{{{*/
+void       Element::FindParam(IssmDouble* pvalue,int paramenum){/*{{{*/
 	this->parameters->FindParam(pvalue,paramenum);
 }/*}}}*/
-void Element::FindParam(int** pvalues,int* psize,int paramenum){/*{{{*/
+void       Element::FindParam(int** pvalues,int* psize,int paramenum){/*{{{*/
 	this->parameters->FindParam(pvalues,psize,paramenum);
 }/*}}}*/
-void Element::GetDofList(int** pdoflist,int approximation_enum,int setenum){/*{{{*/
+void       Element::GetDofList(int** pdoflist,int approximation_enum,int setenum){/*{{{*/
 
 	/*Fetch number of nodes and dof for this finite element*/
@@ -276,5 +260,5 @@
 }
 /*}}}*/
-void Element::GetDofListVelocity(int** pdoflist,int setenum){/*{{{*/
+void       Element::GetDofListVelocity(int** pdoflist,int setenum){/*{{{*/
 
 	/*Fetch number of nodes and dof for this finite element*/
@@ -299,5 +283,5 @@
 }
 /*}}}*/
-void Element::GetDofListPressure(int** pdoflist,int setenum){/*{{{*/
+void       Element::GetDofListPressure(int** pdoflist,int setenum){/*{{{*/
 
 	/*Fetch number of nodes and dof for this finite element*/
@@ -337,5 +321,5 @@
 	}
 }/*}}}*/
-void Element::GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity){/*{{{*/
+void       Element::GetPhi(IssmDouble* phi, IssmDouble*  epsilon, IssmDouble viscosity){/*{{{*/
 	/*Compute deformational heating from epsilon and viscosity */
 
@@ -374,8 +358,8 @@
 }
 /*}}}*/
-Input* Element::GetInput(int inputenum){/*{{{*/
+Input*     Element::GetInput(int inputenum){/*{{{*/
 	return inputs->GetInput(inputenum);
 }/*}}}*/
-void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){/*{{{*/
+void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype){/*{{{*/
 
 	/*Recover input*/
@@ -400,5 +384,5 @@
 }
 /*}}}*/
-void Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
+void       Element::GetInputListOnVertices(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
 
 	/*Recover input*/
@@ -425,5 +409,5 @@
 }
 /*}}}*/
-void Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
+void       Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype,IssmDouble defaultvalue){/*{{{*/
 
 	_assert_(pvalue);
@@ -446,5 +430,5 @@
 }
 /*}}}*/
-void Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){/*{{{*/
+void       Element::GetInputListOnNodes(IssmDouble* pvalue,int enumtype){/*{{{*/
 
 	_assert_(pvalue);
@@ -463,5 +447,5 @@
 }
 /*}}}*/
-void Element::GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype){/*{{{*/
+void       Element::GetInputListOnNodesVelocity(IssmDouble* pvalue,int enumtype){/*{{{*/
 
 	_assert_(pvalue);
@@ -480,5 +464,5 @@
 }
 /*}}}*/
-void Element::GetInputValue(bool* pvalue,int inputenum){/*{{{*/
+void       Element::GetInputValue(bool* pvalue,int inputenum){/*{{{*/
 
 	Input* input=inputs->GetInput(inputenum);
@@ -487,5 +471,5 @@
 
 }/*}}}*/
-void Element::GetInputValue(int* pvalue,int inputenum){/*{{{*/
+void       Element::GetInputValue(int* pvalue,int inputenum){/*{{{*/
 
 	Input* input=inputs->GetInput(inputenum);
@@ -494,5 +478,5 @@
 
 }/*}}}*/
-void Element::GetInputValue(IssmDouble* pvalue,int inputenum){/*{{{*/
+void       Element::GetInputValue(IssmDouble* pvalue,int inputenum){/*{{{*/
 
 	Input* input=inputs->GetInput(inputenum);
@@ -501,5 +485,5 @@
 
 }/*}}}*/
-void Element::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int inputenum){/*{{{*/
+void       Element::GetInputValue(IssmDouble* pvalue,Gauss* gauss,int inputenum){/*{{{*/
 
 	Input* input=inputs->GetInput(inputenum);
@@ -508,5 +492,5 @@
 
 }/*}}}*/
-void Element::GetNodesSidList(int* sidlist){/*{{{*/
+void       Element::GetNodesSidList(int* sidlist){/*{{{*/
 
 	_assert_(sidlist);
@@ -518,5 +502,5 @@
 }
 /*}}}*/
-void Element::GetNodesLidList(int* lidlist){/*{{{*/
+void       Element::GetNodesLidList(int* lidlist){/*{{{*/
 
 	_assert_(lidlist);
@@ -528,5 +512,5 @@
 }
 /*}}}*/
-void  Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){/*{{{*/
+void       Element::GetVectorFromInputs(Vector<IssmDouble>* vector,int input_enum){/*{{{*/
 
 	/*Fetch number vertices for this element and allocate arrays*/
@@ -546,5 +530,5 @@
 }
 /*}}}*/
-void  Element::GetVertexPidList(int* pidlist){/*{{{*/
+void       Element::GetVertexPidList(int* pidlist){/*{{{*/
 
 	int numvertices = this->GetNumberOfVertices();
@@ -553,5 +537,5 @@
 }
 /*}}}*/
-void Element::GetVerticesCoordinates(IssmDouble** pxyz_list){/*{{{*/
+void       Element::GetVerticesCoordinates(IssmDouble** pxyz_list){/*{{{*/
 
 	int         numvertices = this->GetNumberOfVertices();
@@ -562,5 +546,5 @@
 
 }/*}}}*/
-void Element::GetVerticesSidList(int* sidlist){/*{{{*/
+void       Element::GetVerticesSidList(int* sidlist){/*{{{*/
 
 	int numvertices = this->GetNumberOfVertices();
@@ -568,5 +552,5 @@
 }
 /*}}}*/
-void Element::GetVerticesConnectivityList(int* connectivity){/*{{{*/
+void       Element::GetVerticesConnectivityList(int* connectivity){/*{{{*/
 
 	int numvertices = this->GetNumberOfVertices();
@@ -574,11 +558,56 @@
 }
 /*}}}*/
-bool Element::HasNodeOnBase(){/*{{{*/
+IssmDouble Element::GetXcoord(IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+
+	/*output*/
+	IssmDouble x;
+
+	/*Create list of x*/
+	int         numvertices = this->GetNumberOfVertices();
+	IssmDouble* x_list      = xNew<IssmDouble>(numvertices);
+
+	for(int i=0;i<numvertices;i++) x_list[i]=xyz_list[i*3+0];
+	ValueP1OnGauss(&x,x_list,gauss);
+
+	xDelete<IssmDouble>(x_list);
+	return x;
+}/*}}}*/
+IssmDouble Element::GetYcoord(IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+
+	/*output*/
+	IssmDouble y;
+
+	/*Create list of y*/
+	int         numvertices = this->GetNumberOfVertices();
+	IssmDouble* y_list      = xNew<IssmDouble>(numvertices);
+
+	for(int i=0;i<numvertices;i++) y_list[i]=xyz_list[i*3+1];
+	ValueP1OnGauss(&y,y_list,gauss);
+
+	xDelete<IssmDouble>(y_list);
+	return y;
+}/*}}}*/
+IssmDouble Element::GetZcoord(IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+
+	/*output*/
+	IssmDouble z;
+
+	/*Create list of z*/
+	int         numvertices = this->GetNumberOfVertices();
+	IssmDouble* z_list      = xNew<IssmDouble>(numvertices);
+
+	for(int i=0;i<numvertices;i++) z_list[i]=xyz_list[i*3+2];
+	ValueP1OnGauss(&z,z_list,gauss);
+
+	xDelete<IssmDouble>(z_list);
+	return z;
+}/*}}}*/
+bool       Element::HasNodeOnBase(){/*{{{*/
 	return (this->inputs->Max(MeshVertexonbaseEnum)>0.);
 }/*}}}*/
-bool Element::HasNodeOnSurface(){/*{{{*/
+bool       Element::HasNodeOnSurface(){/*{{{*/
 	return (this->inputs->Max(MeshVertexonsurfaceEnum)>0.);
 }/*}}}*/
-int  Element::Id(){/*{{{*/
+int        Element::Id(){/*{{{*/
 
 	return this->id;
@@ -586,12 +615,12 @@
 }
 /*}}}*/
-void Element::InputChangeName(int original_enum,int new_enum){/*{{{*/
+void       Element::InputChangeName(int original_enum,int new_enum){/*{{{*/
 	this->inputs->ChangeEnum(original_enum,new_enum);
 }
 /*}}}*/
-void Element::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){/*{{{*/
+void       Element::InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code){/*{{{*/
 
 	/*Intermediaries*/
-	int        i,t,row;
+	int        i,t;
 	IssmDouble time;
 
@@ -658,5 +687,12 @@
 	}
 }/*}}}*/
-void Element::InputUpdateFromConstant(int constant, int name){/*{{{*/
+void       Element::InputDuplicate(int original_enum,int new_enum){/*{{{*/
+
+	/*Call inputs method*/
+	if (IsInput(original_enum)) inputs->DuplicateInput(original_enum,new_enum);
+
+}
+/*}}}*/
+void       Element::InputUpdateFromConstant(int constant, int name){/*{{{*/
 
 	/*Check that name is an element input*/
@@ -667,5 +703,5 @@
 }
 /*}}}*/
-void Element::InputUpdateFromConstant(IssmDouble constant, int name){/*{{{*/
+void       Element::InputUpdateFromConstant(IssmDouble constant, int name){/*{{{*/
 
 	/*Check that name is an element input*/
@@ -676,5 +712,5 @@
 }
 /*}}}*/
-void Element::InputUpdateFromConstant(bool constant, int name){/*{{{*/
+void       Element::InputUpdateFromConstant(bool constant, int name){/*{{{*/
 
 	/*Check that name is an element input*/
@@ -685,5 +721,5 @@
 }
 /*}}}*/
-bool Element::IsFloating(){/*{{{*/
+bool       Element::IsFloating(){/*{{{*/
 
 	bool shelf;
@@ -695,5 +731,5 @@
 		else shelf=false;
 	}
-	else if(migration_style==NoneEnum || migration_style==AgressiveMigrationEnum || migration_style==SoftMigrationEnum){ //Floating if all nodes are floating
+	else if(migration_style==NoneEnum || migration_style==AggressiveMigrationEnum || migration_style==SoftMigrationEnum){ //Floating if all nodes are floating
 		if(this->inputs->Min(MaskGroundediceLevelsetEnum) > 0.) shelf=false;
 		else shelf=true;
@@ -703,9 +739,9 @@
 	return shelf;
 }/*}}}*/
-bool Element::IsIceInElement(){/*{{{*/
+bool       Element::IsIceInElement(){/*{{{*/
 	return (this->inputs->Min(MaskIceLevelsetEnum)<0.);
 }
 /*}}}*/
-bool Element::IsInput(int name){/*{{{*/
+bool       Element::IsInput(int name){/*{{{*/
 	if (
 				name==ThicknessEnum ||
@@ -798,5 +834,5 @@
 	return this->matpar->PureIceEnthalpy(pressure);
 }/*}}}*/
-void Element::ResultInterpolation(int* pinterpolation,int* pnodesperelement,int output_enum){/*{{{*/
+void       Element::ResultInterpolation(int* pinterpolation,int* pnodesperelement,int output_enum){/*{{{*/
 
 	Input* input=this->inputs->GetInput(output_enum);
@@ -816,4 +852,13 @@
 			case StressTensorzzEnum: 
 				this->ComputeStressTensor();
+				input=this->inputs->GetInput(output_enum);
+				break;
+			case StrainRatexxEnum:
+			case StrainRatexyEnum:
+			case StrainRatexzEnum:
+			case StrainRateyyEnum:
+			case StrainRateyzEnum:
+			case StrainRatezzEnum:
+				this->ComputeStrainRate();
 				input=this->inputs->GetInput(output_enum);
 				break;
@@ -840,5 +885,5 @@
 	*pnodesperelement = input->GetResultNumberOfNodes();
 }/*}}}*/
-void Element::ResultToVector(Vector<IssmDouble>* vector,int output_enum){/*{{{*/
+void       Element::ResultToVector(Vector<IssmDouble>* vector,int output_enum){/*{{{*/
 
 	Input* input=this->inputs->GetInput(output_enum);
@@ -886,5 +931,5 @@
 	}
 } /*}}}*/
-void Element::ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum){/*{{{*/
+void       Element::ResultToPatch(IssmDouble* values,int nodesperelement,int output_enum){/*{{{*/
 
 	Input* input=this->inputs->GetInput(output_enum);
@@ -894,5 +939,5 @@
 
 } /*}}}*/
-void Element::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){/*{{{*/
+void       Element::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){/*{{{*/
 
 	/*Intermediaries*/
@@ -964,5 +1009,5 @@
 }
 /*}}}*/
-int  Element::Sid(){/*{{{*/
+int        Element::Sid(){/*{{{*/
 
 	return this->sid;
@@ -974,5 +1019,5 @@
 	return this->matpar->TMeltingPoint(pressure);
 }/*}}}*/
-void Element::ViscousHeatingCreateInput(void){/*{{{*/
+void       Element::ViscousHeatingCreateInput(void){/*{{{*/
 
 	/*Intermediaries*/
@@ -1016,5 +1061,5 @@
 }
 /*}}}*/
-void Element::ViscosityFS(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
+void       Element::ViscosityFS(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
 	/*The effective strain rate is defined in Paterson 3d Ed p 91 eq 9,
 	 * and Cuffey p 303 eq 8.18:
@@ -1055,5 +1100,5 @@
 }
 /*}}}*/
-void Element::ViscosityL1L2(IssmDouble* pviscosity,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* surface_input){/*{{{*/
+void       Element::ViscosityL1L2(IssmDouble* pviscosity,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* surface_input){/*{{{*/
 	/*Compute the L1L2 viscosity
 	 *
@@ -1084,5 +1129,5 @@
 	surface_input->GetInputValue(&s,gauss);
 	surface_input->GetInputDerivativeValue(&slope[0],xyz_list,gauss);
-	z=GetZcoord(gauss);
+	z=this->GetZcoord(xyz_list,gauss);
 	tau_perp = matpar->GetRhoIce() * matpar->GetG() * fabs(s-z)*sqrt(slope[0]*slope[0]+slope[1]*slope[1]);
 
@@ -1114,5 +1159,5 @@
 	*pviscosity = viscosity;
 }/*}}}*/
-void Element::ViscosityHO(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+void       Element::ViscosityHO(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
 
 	/*Intermediaries*/
@@ -1139,5 +1184,5 @@
 	*pviscosity=viscosity;
 }/*}}}*/
-void Element::ViscositySSA(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+void       Element::ViscositySSA(IssmDouble* pviscosity,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
 
 	/*Intermediaries*/
@@ -1164,14 +1209,14 @@
 	*pviscosity=viscosity;
 }/*}}}*/
-void Element::ViscositySSADerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
+void       Element::ViscositySSADerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
 	this->material->GetViscosity2dDerivativeEpsSquare(pmu_prime,epsilon);
 }/*}}}*/
-void Element::ViscosityHODerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
+void       Element::ViscosityHODerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
 	this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
 }/*}}}*/
-void Element::ViscosityFSDerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
+void       Element::ViscosityFSDerivativeEpsSquare(IssmDouble* pmu_prime,IssmDouble* epsilon){/*{{{*/
 	this->material->GetViscosityDerivativeEpsSquare(pmu_prime,epsilon);
 }/*}}}*/
-void Element::StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
+void       Element::StrainRateFS(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
 	/*Compute the 3d Strain Rate (6 components):
 	 *
@@ -1201,5 +1246,5 @@
 
 }/*}}}*/
-void Element::StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+void       Element::StrainRateHO(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
 	/*Compute the 3d Blatter/HOStrain Rate (5 components):
 	 *
@@ -1231,5 +1276,5 @@
 
 }/*}}}*/
-void Element::StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+void       Element::StrainRateHO2dvertical(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
 	/*Compute the 2d Blatter/HOStrain Rate (2 components):
 	 *
@@ -1255,5 +1300,5 @@
 
 }/*}}}*/
-void Element::StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
+void       Element::StrainRateSSA(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/
 
 	/*Intermediaries*/
@@ -1274,5 +1319,5 @@
 
 }/*}}}*/
-void Element::StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input){/*{{{*/
+void       Element::StrainRateSSA1d(IssmDouble* epsilon,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input){/*{{{*/
 
 	/*Intermediaries*/
@@ -1289,5 +1334,5 @@
 
 }/*}}}*/
-void Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
+void       Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
 
 	/*All nodes have the same Coordinate System*/
@@ -1302,5 +1347,5 @@
 	xDelete<int>(cs_array);
 }/*}}}*/
-void Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+void       Element::TransformInvStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
 
 	int         i,j;
@@ -1336,5 +1381,5 @@
 	xDelete<IssmDouble>(values);
 }/*}}}*/
-void Element::TransformLoadVectorCoord(ElementVector* pe,int transformenum){/*{{{*/
+void       Element::TransformLoadVectorCoord(ElementVector* pe,int transformenum){/*{{{*/
 
 	/*All nodes have the same Coordinate System*/
@@ -1349,10 +1394,10 @@
 	xDelete<int>(cs_array);
 }/*}}}*/
-void Element::TransformLoadVectorCoord(ElementVector* pe,int* cs_array){/*{{{*/
+void       Element::TransformLoadVectorCoord(ElementVector* pe,int* cs_array){/*{{{*/
 
 	this->TransformLoadVectorCoord(pe,this->nodes,this->GetNumberOfNodes(),cs_array);
 
 }/*}}}*/
-void Element::TransformLoadVectorCoord(ElementVector* pe,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+void       Element::TransformLoadVectorCoord(ElementVector* pe,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
 
 	int         i;
@@ -1387,5 +1432,5 @@
 	xDelete<IssmDouble>(values);
 }/*}}}*/
-void Element::TransformSolutionCoord(IssmDouble* values,int transformenum){/*{{{*/
+void       Element::TransformSolutionCoord(IssmDouble* values,int transformenum){/*{{{*/
 
 	/*All nodes have the same Coordinate System*/
@@ -1400,8 +1445,8 @@
 	xDelete<int>(cs_array);
 }/*}}}*/
-void Element::TransformSolutionCoord(IssmDouble* values,int* transformenum_list){/*{{{*/
+void       Element::TransformSolutionCoord(IssmDouble* values,int* transformenum_list){/*{{{*/
 	this->TransformSolutionCoord(values,this->nodes,this->GetNumberOfNodes(),transformenum_list);
 }/*}}}*/
-void Element::TransformSolutionCoord(IssmDouble* values,int numnodes,int transformenum){/*{{{*/
+void       Element::TransformSolutionCoord(IssmDouble* values,int numnodes,int transformenum){/*{{{*/
 
 	/*All nodes have the same Coordinate System*/
@@ -1415,8 +1460,8 @@
 	xDelete<int>(cs_array);
 }/*}}}*/
-void Element::TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array){/*{{{*/
+void       Element::TransformSolutionCoord(IssmDouble* solution,int numnodes,int* cs_array){/*{{{*/
 	this->TransformSolutionCoord(solution,this->nodes,numnodes,cs_array);
 }/*}}}*/
-void Element::TransformSolutionCoord(IssmDouble* values,Node** nodes_list,int numnodes,int transformenum){/*{{{*/
+void       Element::TransformSolutionCoord(IssmDouble* values,Node** nodes_list,int numnodes,int transformenum){/*{{{*/
 	/*NOT NEEDED*/
 	/*All nodes have the same Coordinate System*/
@@ -1430,5 +1475,5 @@
 	xDelete<int>(cs_array);
 }/*}}}*/
-void Element::TransformSolutionCoord(IssmDouble* solution,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+void       Element::TransformSolutionCoord(IssmDouble* solution,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
 
 	int         i;
@@ -1463,5 +1508,5 @@
 	xDelete<IssmDouble>(values);
 }/*}}}*/
-void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
+void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int transformenum){/*{{{*/
 
 	/*All nodes have the same Coordinate System*/
@@ -1476,8 +1521,8 @@
 	xDelete<int>(cs_array);
 }/*}}}*/
-void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* transformenum_list){/*{{{*/
+void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,int* transformenum_list){/*{{{*/
 	this->TransformStiffnessMatrixCoord(Ke,this->nodes,this->GetNumberOfNodes(),transformenum_list);
 }/*}}}*/
-void Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
+void       Element::TransformStiffnessMatrixCoord(ElementMatrix* Ke,Node** nodes_list,int numnodes,int* cs_array){/*{{{*/
 
 	int         numdofs = 0;
Index: /issm/trunk/src/c/classes/Elements/Element.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Element.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Element.h	(revision 17989)
@@ -91,4 +91,7 @@
 		void       GetVerticesSidList(int* sidlist);
 		void       GetVerticesConnectivityList(int* connectivitylist);
+		IssmDouble GetXcoord(IssmDouble* xyz_list,Gauss* gauss);
+		IssmDouble GetYcoord(IssmDouble* xyz_list,Gauss* gauss);
+		IssmDouble GetZcoord(IssmDouble* xyz_list,Gauss* gauss);
 		bool       HasNodeOnBase();
 		bool       HasNodeOnSurface();
@@ -97,4 +100,5 @@
 		void       InputChangeName(int enum_type,int enum_type_old);
 		void       InputCreate(IssmDouble* vector,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code);
+		void       InputDuplicate(int original_enum,int new_enum);
 		void       InputUpdateFromConstant(IssmDouble constant, int name);
 		void       InputUpdateFromConstant(int constant, int name);
@@ -170,6 +174,4 @@
 
 		virtual Element* GetUpperElement(void)=0;
-		virtual Element* GetLowerElement(void)=0;
-		virtual Element* GetSurfaceElement(void)=0;
 		virtual Element* GetBasalElement(void)=0;
 
@@ -193,7 +195,5 @@
 		virtual void   GetVerticesCoordinatesBase(IssmDouble** xyz_list)=0;
 		virtual void   GetVerticesCoordinatesTop(IssmDouble** xyz_list)=0;
-		virtual IssmDouble GetXcoord(Gauss* gauss)=0;
-		virtual IssmDouble GetYcoord(Gauss* gauss)=0;
-		virtual IssmDouble GetZcoord(Gauss* gauss)=0;
+
 		virtual int    GetElementType(void)=0;
 
@@ -202,4 +202,5 @@
 		virtual void   ComputeSigmaNN(void)=0;
 		virtual void   ComputeBasalStress(Vector<IssmDouble>* sigma_b)=0;
+		virtual void   ComputeStrainRate()=0;
 		virtual void   ComputeStrainRate(Vector<IssmDouble>* eps)=0;
 		virtual void   ComputeStressTensor(void)=0;
@@ -207,5 +208,5 @@
 
 		virtual void   Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finite_element)=0;
-		virtual void   InputDuplicate(int original_enum,int new_enum)=0;
+		virtual void   InputExtrude(int input_enum)=0;
 		virtual void   InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int inputenum)=0;
 		virtual void   InputUpdateFromSolutionOneDof(IssmDouble* solution,int inputenum)=0;
@@ -240,9 +241,10 @@
 		virtual int    VelocityInterpolation()=0;
 		virtual int    PressureInterpolation()=0;
+		virtual int    TensorInterpolation()=0;
 		virtual bool   IsZeroLevelset(int levelset_enum)=0;
 		virtual bool   IsIcefront(void)=0;
+		virtual bool   IsFaceOnBoundary(void)=0;
 		virtual void   ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0;
 		virtual void   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum)=0;
-		virtual void   GetNormalFromLSF(IssmDouble *pnormal)=0;
 
 		virtual void   AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part)=0;
@@ -274,16 +276,4 @@
 
 		virtual void   Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index)=0;
-		virtual IssmDouble ThicknessAbsMisfit(void)=0;
-		virtual IssmDouble SurfaceAbsVelMisfit(void)=0;
-		virtual IssmDouble SurfaceRelVelMisfit(void)=0;
-		virtual IssmDouble SurfaceLogVelMisfit(void)=0;
-		virtual IssmDouble SurfaceLogVxVyMisfit(void)=0;
-		virtual IssmDouble SurfaceAverageVelMisfit(void)=0;
-		virtual IssmDouble ThicknessAbsGradient(void)=0;
-		virtual IssmDouble ThicknessAlongGradient(void)=0;
-		virtual IssmDouble ThicknessAcrossGradient(void)=0;
-		virtual IssmDouble BalancethicknessMisfit(void)=0;
-		virtual IssmDouble RheologyBbarAbsGradient(void)=0;
-		virtual IssmDouble DragCoefficientAbsGradient(void)=0;
 		virtual void   ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index)=0;
 		virtual void   ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index)=0;
Index: /issm/trunk/src/c/classes/Elements/ElementHook.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/ElementHook.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/ElementHook.cpp	(revision 17989)
@@ -16,6 +16,5 @@
 
 /*Object constructors and destructor*/
-/*FUNCTION ElementHook::ElementHook(){{{*/
-ElementHook::ElementHook(){
+ElementHook::ElementHook(){/*{{{*/
 	numanalyses=UNDEF;
 	this->hnodes     = NULL;
@@ -26,6 +25,5 @@
 }
 /*}}}*/
-/*FUNCTION ElementHook::~ElementHook(){{{*/
-ElementHook::~ElementHook(){
+ElementHook::~ElementHook(){/*{{{*/
 
 	int i;
@@ -41,6 +39,5 @@
 }
 /*}}}*/
-/*FUNCTION ElementHook::ElementHook(int in_numanalyses,int element_id, int numvertices,IoModel* iomodel){{{*/
-ElementHook::ElementHook(int in_numanalyses,int element_id,int numvertices,IoModel* iomodel){
+ElementHook::ElementHook(int in_numanalyses,int element_id,int numvertices,IoModel* iomodel){/*{{{*/
 
 	/*intermediary: */
@@ -78,16 +75,13 @@
 /*}}}*/
 
-/*FUNCTION ElementHook::SetHookNodes{{{*/
-void ElementHook::SetHookNodes(int* node_ids,int numnodes,int analysis_counter){
+void ElementHook::SetHookNodes(int* node_ids,int numnodes,int analysis_counter){/*{{{*/
 	this->hnodes[analysis_counter]= new Hook(node_ids,numnodes);
 }
 /*}}}*/
-/*FUNCTION ElementHook::InitHookNeighbors{{{*/
-void ElementHook::InitHookNeighbors(int* element_ids){
+void ElementHook::InitHookNeighbors(int* element_ids){/*{{{*/
 	this->hneighbors=new Hook(element_ids,2);
 }
 /*}}}*/
-/*FUNCTION ElementHook::SpawnTriaHook{{{*/
-void ElementHook::SpawnTriaHook(ElementHook* triahook,int index1,int index2,int index3){
+void ElementHook::SpawnTriaHook(ElementHook* triahook,int index1,int index2,int index3){/*{{{*/
 
 	/*Create arrow of indices depending on location (0=base 1=surface)*/
@@ -117,6 +111,5 @@
 }
 /*}}}*/
-/*FUNCTION ElementHook::SpawnSegHook{{{*/
-void ElementHook::SpawnSegHook(ElementHook* triahook,int index1,int index2){
+void ElementHook::SpawnSegHook(ElementHook* triahook,int index1,int index2){/*{{{*/
 
 	triahook->numanalyses=this->numanalyses;
Index: /issm/trunk/src/c/classes/Elements/Elements.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Elements.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Elements.cpp	(revision 17989)
@@ -23,12 +23,10 @@
 
 /*Object constructors and destructor*/
-/*FUNCTION Elements::Elements(){{{*/
-Elements::Elements(){
+Elements::Elements(){/*{{{*/
 	enum_type=MeshElementsEnum;
 	return;
 }
 /*}}}*/
-/*FUNCTION Elements::~Elements(){{{*/
-Elements::~Elements(){
+Elements::~Elements(){/*{{{*/
 	return;
 }
@@ -36,6 +34,5 @@
 
 /*Object management*/
-/*FUNCTION Elements::Configure{{{*/
-void Elements::Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){
+void Elements::Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/
 
 	vector<Object*>::iterator object;
@@ -51,6 +48,5 @@
 }
 /*}}}*/
-/*FUNCTION Elements::SetCurrentConfiguration{{{*/
-void Elements::SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){
+void Elements::SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/
 
 	vector<Object*>::iterator object;
@@ -66,6 +62,5 @@
 }
 /*}}}*/
-/*FUNCTION Elements::MaxNumNodes{{{*/
-int Elements::MaxNumNodes(void){
+int  Elements::MaxNumNodes(void){/*{{{*/
 
 	int max=0;
@@ -88,6 +83,5 @@
 }
 /*}}}*/
-/*FUNCTION Elements::NumberOfElements{{{*/
-int Elements::NumberOfElements(void){
+int  Elements::NumberOfElements(void){/*{{{*/
 
 	int local_nelem;
@@ -100,6 +94,5 @@
 }
 /*}}}*/
-/*FUNCTION Elements::InputDuplicate{{{*/
-void Elements::InputDuplicate(int input_enum,int output_enum){
+void Elements::InputDuplicate(int input_enum,int output_enum){/*{{{*/
 
 	for(int i=0;i<this->Size();i++){
Index: /issm/trunk/src/c/classes/Elements/Penta.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Penta.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Penta.cpp	(revision 17989)
@@ -20,11 +20,9 @@
 
 /*Constructors/destructor/copy*/
-/*FUNCTION Penta::~Penta(){{{*/
-Penta::~Penta(){
+Penta::~Penta(){/*{{{*/
 	this->parameters=NULL;
 }
 /*}}}*/
-/*FUNCTION Penta::Penta(int id, int index, IoModel* iomodel,int nummodels) {{{*/
-Penta::Penta(int penta_id, int penta_sid, int index, IoModel* iomodel,int nummodels)
+Penta::Penta(int penta_id, int penta_sid, int index, IoModel* iomodel,int nummodels)/*{{{*/
 	:PentaRef(nummodels)
 	,ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
@@ -61,6 +59,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::copy {{{*/
-Object* Penta::copy() {
+Object* Penta::copy() {/*{{{*/
 
 	int i;
@@ -108,6 +105,5 @@
 
 /*Other*/
-/*FUNCTION Penta::AddInput{{{*/
-void  Penta::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){
+void       Penta::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
 
 	_assert_(this->inputs);
@@ -115,6 +111,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::AddBasalInput{{{*/
-void  Penta::AddBasalInput(int input_enum,IssmDouble* values, int interpolation_enum){
+void       Penta::AddBasalInput(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
 
 	_assert_(this->inputs);
@@ -141,53 +136,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::BasalFrictionCreateInput {{{*/
-void Penta::BasalFrictionCreateInput(void){
-
-	/*Intermediaries */
-	int         count;
-	IssmDouble  basalfriction[NUMVERTICES];
-	IssmDouble  alpha2                       ,vx,vy;
-	Friction   *friction                   = NULL;
-	GaussPenta *gauss                      = NULL;
-
-	/* Basal friction can only be found at the base of an ice sheet: */
-	if (!IsOnBase() || IsFloating()){
-		//empty friction: 
-		this->inputs->AddInput(new PentaInput(BasalFrictionEnum,&basalfriction[0],P1Enum));
-		return;
-	}
-
-	/*Retrieve all inputs and parameters*/
-	Input* vx_input=inputs->GetInput(VxEnum);                         _assert_(vx_input);
-	Input* vy_input=inputs->GetInput(VyEnum);                         _assert_(vy_input);
-	Input* vz_input=inputs->GetInput(VzEnum);                         _assert_(vz_input);
-
-	/*Build friction element, needed later: */
-	friction=new Friction(this,3);
-
-	/* Start looping on the number of gauss 2d (nodes on the bedrock) */
-	gauss=new GaussPenta(0,1,2,2);
-	count=0;
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		basalfriction[count]=alpha2*(pow(vx,2.0)+pow(vy,2.0));
-		count++;
-	}
-
-	/*Create PentaVertex input, which will hold the basal friction:*/
-	this->inputs->AddInput(new PentaInput(BasalFrictionEnum,&basalfriction[0],P1Enum));
-
-	/*Clean up and return*/
-	delete gauss;
-	delete friction;
-}
-/*}}}*/
-/*FUNCTION Penta::ComputeBasalStress {{{*/
-void  Penta::ComputeBasalStress(Vector<IssmDouble>* sigma_b){
+void       Penta::ComputeBasalStress(Vector<IssmDouble>* sigma_b){/*{{{*/
 
 	int         i,j;
@@ -276,13 +223,53 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ComputeStrainRate {{{*/
-void  Penta::ComputeStrainRate(Vector<IssmDouble>* eps){
-
-	_error_("Not implemented yet");
-
-}
-/*}}}*/
-/*FUNCTION Penta::ComputeStressTensor {{{*/
-void  Penta::ComputeStressTensor(){
+void       Penta::ComputeStrainRate(){/*{{{*/
+
+	IssmDouble      xyz_list[NUMVERTICES][3];
+	IssmDouble      epsilon[6]; /* epsilon=[exx,eyy,exy];*/
+	IssmDouble      eps_xx[NUMVERTICES];
+	IssmDouble		 eps_yy[NUMVERTICES];
+	IssmDouble		 eps_zz[NUMVERTICES];
+	IssmDouble      eps_xy[NUMVERTICES];
+	IssmDouble		 eps_xz[NUMVERTICES];
+	IssmDouble		 eps_yz[NUMVERTICES];
+	GaussPenta*     gauss=NULL;
+
+	/* Get node coordinates and dof list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* vx_input=inputs->GetInput(VxEnum);             _assert_(vx_input);
+	Input* vy_input=inputs->GetInput(VyEnum);             _assert_(vy_input);
+	Input* vz_input=inputs->GetInput(VzEnum);             _assert_(vz_input);
+
+	/* Start looping on the number of vertices: */
+	gauss=new GaussPenta();
+	for (int iv=0;iv<NUMVERTICES;iv++){
+		gauss->GaussVertex(iv);
+
+		/*Compute strain rate viscosity and pressure: */
+		this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
+
+		eps_xx[iv]=epsilon[0]; 
+		eps_yy[iv]=epsilon[1];
+		eps_zz[iv]=epsilon[2];
+		eps_xy[iv]=epsilon[3];
+		eps_xz[iv]=epsilon[4];
+		eps_yz[iv]=epsilon[5];
+	}
+
+	/*Add Stress tensor components into inputs*/
+	this->inputs->AddInput(new PentaInput(StrainRatexxEnum,&eps_xx[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StrainRatexyEnum,&eps_xy[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StrainRatexzEnum,&eps_xz[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StrainRateyyEnum,&eps_yy[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StrainRateyzEnum,&eps_yz[0],P1Enum));
+	this->inputs->AddInput(new PentaInput(StrainRatezzEnum,&eps_zz[0],P1Enum));
+
+	/*Clean up and return*/
+	delete gauss;
+}
+/*}}}*/
+void       Penta::ComputeStressTensor(){/*{{{*/
 
 	IssmDouble      xyz_list[NUMVERTICES][3];
@@ -337,6 +324,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ComputeDeviatoricStressTensor {{{*/
-void  Penta::ComputeDeviatoricStressTensor(){
+void       Penta::ComputeDeviatoricStressTensor(){/*{{{*/
 
 	IssmDouble      xyz_list[NUMVERTICES][3];
@@ -389,6 +375,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::Configure {{{*/
-void  Penta::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin){
+void       Penta::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin){/*{{{*/
 
 	int analysis_counter;
@@ -423,8 +408,8 @@
 }
 /*}}}*/
-/*FUNCTION Penta::Delta18oParameterization{{{*/
-void  Penta::Delta18oParameterization(void){
-        /*Are we on the base? If not, return*/
-        if(!IsOnBase()) return;
+void       Penta::Delta18oParameterization(void){/*{{{*/
+
+	/*Are we on the base? If not, return*/
+	if(!IsOnBase()) return;
 
 	int        i;
@@ -497,11 +482,9 @@
 }
 /*}}}*/
-/*FUNCTION Penta::FiniteElement{{{*/
-int Penta::FiniteElement(void){
+int        Penta::FiniteElement(void){/*{{{*/
 	return this->element_type;
 }
 /*}}}*/
-/*FUNCTION Penta::FSContactMigration{{{*/
-void Penta::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){
+void       Penta::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){/*{{{*/
 
 	if(!IsOnBase()) return;
@@ -584,6 +567,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ObjectEnum{{{*/
-int Penta::ObjectEnum(void){
+int        Penta::ObjectEnum(void){/*{{{*/
 
 	return PentaEnum;
@@ -591,6 +573,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetAreaCoordinates{{{*/
-void Penta::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){
+void       Penta::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){/*{{{*/
 	/*Computeportion of the element that is grounded*/ 
 
@@ -627,6 +608,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetUpperPenta{{{*/
-Penta* Penta::GetUpperPenta(void){
+Penta*     Penta::GetUpperPenta(void){/*{{{*/
 
 	Penta* upper_penta=NULL;
@@ -637,6 +617,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetLowerPenta{{{*/
-Penta* Penta::GetLowerPenta(void){
+Penta*     Penta::GetLowerPenta(void){/*{{{*/
 
 	Penta* lower_penta=NULL;
@@ -647,6 +626,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetSurfacePenta{{{*/
-Penta* Penta::GetSurfacePenta(void){
+Penta*     Penta::GetSurfacePenta(void){/*{{{*/
 
 	/*Output*/
@@ -668,6 +646,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetBasalPenta{{{*/
-Penta* Penta::GetBasalPenta(void){
+Penta*     Penta::GetBasalPenta(void){/*{{{*/
 
 	/*Output*/
@@ -689,6 +666,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetUpperElement{{{*/
-Element* Penta::GetUpperElement(void){
+Element*   Penta::GetUpperElement(void){/*{{{*/
 
 	/*Output*/
@@ -697,22 +673,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetLowerElement{{{*/
-Element* Penta::GetLowerElement(void){
-
-	/*Output*/
-	Element* lower_element=this->GetLowerPenta();
-	return lower_element;
-}
-/*}}}*/
-/*FUNCTION Penta::GetSurfaceElement{{{*/
-Element* Penta::GetSurfaceElement(void){
-
-	/*Output*/
-	Element* element=this->GetSurfacePenta();
-	return element;
-}
-/*}}}*/
-/*FUNCTION Penta::GetBasalElement{{{*/
-Element* Penta::GetBasalElement(void){
+Element*   Penta::GetBasalElement(void){/*{{{*/
 
 	/*Output*/
@@ -721,6 +680,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetGroundedPart{{{*/
-void Penta::GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating){
+void       Penta::GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating){/*{{{*/
 	/*Computeportion of the element that is grounded*/ 
 
@@ -775,6 +733,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetGroundedPortion{{{*/
-IssmDouble Penta::GetGroundedPortion(IssmDouble* xyz_list){
+IssmDouble Penta::GetGroundedPortion(IssmDouble* xyz_list){/*{{{*/
 	/*Computeportion of the element that is grounded*/ 
 
@@ -877,6 +834,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetElementType {{{*/
-int Penta::GetElementType(){
+int        Penta::GetElementType(){/*{{{*/
 
 	/*return PentaRef field*/
@@ -884,6 +840,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ElementSizes{{{*/
-void Penta::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){
+void       Penta::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){/*{{{*/
 
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -911,6 +866,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetNodeIndex {{{*/
-int Penta::GetNodeIndex(Node* node){
+int        Penta::GetNodeIndex(Node* node){/*{{{*/
 
 	_assert_(nodes);
@@ -924,16 +878,13 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetNumberOfNodes;{{{*/
-int Penta::GetNumberOfNodes(void){
+int        Penta::GetNumberOfNodes(void){/*{{{*/
 	return this->NumberofNodes();
 }
 /*}}}*/
-/*FUNCTION Penta::GetNumberOfVertices;{{{*/
-int Penta::GetNumberOfVertices(void){
+int        Penta::GetNumberOfVertices(void){/*{{{*/
 	return NUMVERTICES; 
 }
 /*}}}*/
-/*FUNCTION Penta::GetNode(int node_number) {{{*/
-Node* Penta::GetNode(int node_number){
+Node* Penta::GetNode(int node_number){/*{{{*/
 	_assert_(node_number>=0); 
 	_assert_(node_number<this->NumberofNodes()); 
@@ -941,6 +892,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype) {{{*/
-void Penta::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){
+void       Penta::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){/*{{{*/
 
 	Input* input=inputs->GetInput(enumtype);
@@ -954,6 +904,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){{{*/
-void Penta::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){
+void       Penta::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){/*{{{*/
 
 	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES2D*3);
@@ -964,6 +913,5 @@
 
 }/*}}}*/
-/*FUNCTION Penta::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){{{*/
-void Penta::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){
+void       Penta::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){/*{{{*/
 
 	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES2D*3);
@@ -974,6 +922,5 @@
 
 }/*}}}*/
-/*FUNCTION Penta::NormalSection{{{*/
-void Penta::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){
+void       Penta::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){/*{{{*/
 
 	/*Build unit outward pointing vector*/
@@ -995,6 +942,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::StabilizationParameter {{{*/
-IssmDouble Penta::StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){
+IssmDouble Penta::StabilizationParameter(IssmDouble u, IssmDouble v, IssmDouble w, IssmDouble diameter, IssmDouble kappa){/*{{{*/
 	/*Compute stabilization parameter*/
 	/*kappa=thermalconductivity/(rho_ice*hearcapacity) for thermal model*/
@@ -1013,51 +959,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GetXcoord {{{*/
-IssmDouble Penta::GetXcoord(Gauss* gauss){
-
-	int    i;
-	IssmDouble x;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble x_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) x_list[i]=xyz_list[i][0];
-	PentaRef::GetInputValue(&x,x_list,gauss,P1Enum);
-
-	return x;
-}
-/*}}}*/
-/*FUNCTION Penta::GetYcoord {{{*/
-IssmDouble Penta::GetYcoord(Gauss* gauss){
-
-	int    i;
-	IssmDouble y;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble y_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) y_list[i]=xyz_list[i][1];
-	PentaRef::GetInputValue(&y,y_list,gauss,P1Enum);
-
-	return y;
-}
-/*}}}*/
-/*FUNCTION Penta::GetZcoord {{{*/
-IssmDouble Penta::GetZcoord(Gauss* gauss){
-
-	int    i;
-	IssmDouble z;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble z_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2];
-	PentaRef::GetInputValue(&z,z_list,gauss,P1Enum);
-
-	return z;
-}
-/*}}}*/
-/*FUNCTION Penta::ZeroLevelsetCoordinates{{{*/
-void Penta::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){
+void       Penta::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
 	/*Compute portion of the element that is grounded*/ 
 
@@ -1214,6 +1114,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputDepthAverageAtBase{{{*/
-void  Penta::InputDepthAverageAtBase(int enum_type,int average_enum_type){
+void       Penta::InputDepthAverageAtBase(int enum_type,int average_enum_type){/*{{{*/
 
 	int  step,i;
@@ -1316,19 +1215,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputDuplicate{{{*/
-void  Penta::InputDuplicate(int original_enum,int new_enum){
-
-	/*Call inputs method*/
-	if (IsInput(original_enum)) inputs->DuplicateInput(original_enum,new_enum);
-
-}
-/*}}}*/
-/*FUNCTION Penta::InputExtrude {{{*/
-void  Penta::InputExtrude(int enum_type){
-
-	int     i,num_inputs;
-	Penta  *penta       = NULL;
-	Input  *copy        = NULL;
-	Input **base_inputs = NULL;
+void       Penta::InputExtrude(int enum_type){/*{{{*/
 
 	/*Are we on the base, not on the surface?:*/
@@ -1336,17 +1221,13 @@
 
 	/*Step1: Get and Extrude original input: */
-	num_inputs=1;
-	base_inputs=xNew<Input*>(num_inputs);
-	base_inputs[0]=(Input*)this->inputs->GetInput(enum_type);
-	for(i=0;i<num_inputs;i++){
-		if(!base_inputs[i]) _error_("could not find input with enum " << EnumToStringx(enum_type));
-		base_inputs[i]->Extrude();
-	}
+	Input* base_input=(Input*)this->inputs->GetInput(enum_type);
+	if(!base_input) _error_("could not find input with enum " << EnumToStringx(enum_type));
+	base_input->Extrude();
 
 	/*Stop if there is only one layer of element*/
-	if (this->IsOnSurface()) return;
+	if(this->IsOnSurface()) return;
 
 	/*Step 2: this input has been extruded for this element, now follow the upper element*/
-	penta=this;
+	Penta* penta=this;
 	for(;;){
 		/* get upper Penta*/
@@ -1355,19 +1236,13 @@
 
 		/*Add input of the basal element to penta->inputs*/
-		for(i=0;i<num_inputs;i++){
-			copy=(Input*)base_inputs[i]->copy();
-			penta->inputs->AddInput((Input*)copy);
-		}
+		Input* copy=(Input*)base_input->copy();
+		penta->inputs->AddInput((Input*)copy);
 
 		/*Stop if we have reached the surface*/
-		if (penta->IsOnSurface()) break;
-	}
-
-	/*clean-up and return*/
-	xDelete<Input*>(base_inputs);
-}
-/*}}}*/
-/*FUNCTION Penta::InputScale{{{*/
-void  Penta::InputScale(int enum_type,IssmDouble scale_factor){
+		if(penta->IsOnSurface()) break;
+	}
+}
+/*}}}*/
+void       Penta::InputScale(int enum_type,IssmDouble scale_factor){/*{{{*/
 
 	Input* input=NULL;
@@ -1381,6 +1256,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromIoModel {{{*/
-void Penta::InputUpdateFromIoModel(int index,IoModel* iomodel){ 
+void       Penta::InputUpdateFromIoModel(int index,IoModel* iomodel){ /*{{{*/
 
 	/*Intermediaries*/
@@ -1410,37 +1284,30 @@
 	if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
 		for(i=0;i<num_control_type;i++){
-			switch(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])){
+			int control = reCast<int>(iomodel->Data(InversionControlParametersEnum)[i]);
+			switch(control){
+				/*yts conversion*/
 				case BalancethicknessThickeningRateEnum:
-					if (iomodel->Data(BalancethicknessThickeningRateEnum)){
-						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(BalancethicknessThickeningRateEnum)[penta_vertex_ids[j]-1]/yts;
+				case VxEnum:
+				case VyEnum:
+					if(iomodel->Data(control)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(control)[penta_vertex_ids[j]-1];
 						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
 						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						this->inputs->AddInput(new ControlInput(BalancethicknessThickeningRateEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+						this->inputs->AddInput(new ControlInput(control,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
-				case VxEnum:
-					if (iomodel->Data(VxEnum)){
-						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(VxEnum)[penta_vertex_ids[j]-1]/yts;
-						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						this->inputs->AddInput(new ControlInput(VxEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+
+				/*No yts conversion*/
+				case ThicknessEnum:
+				case FrictionCoefficientEnum:
+					if(iomodel->Data(control)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(control)[penta_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(control,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
-				case VyEnum:
-					if (iomodel->Data(VyEnum)){
-						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(VyEnum)[penta_vertex_ids[j]-1]/yts;
-						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i]/yts;
-						this->inputs->AddInput(new ControlInput(VyEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-					}
-					break;
-				case FrictionCoefficientEnum:
-					if (iomodel->Data(FrictionCoefficientEnum)){
-						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(FrictionCoefficientEnum)[penta_vertex_ids[j]-1];
-						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
-						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(penta_vertex_ids[j]-1)*num_control_type+i];
-						this->inputs->AddInput(new ControlInput(FrictionCoefficientEnum,PentaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-					}
-					break;
+
+				/*Special cases (depth averaged quantities)*/
 				case MaterialsRheologyBbarEnum:
 					if(iomodel->Data(MaterialsRheologyBEnum)){
@@ -1460,5 +1327,5 @@
 					break;
 				default:
-					_error_("Control " << EnumToStringx(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])) << " not implemented yet");
+					_error_("Control " << EnumToStringx(control) << " not implemented yet");
 			}
 		}
@@ -1485,6 +1352,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionOneDof{{{*/
-void  Penta::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){
+void       Penta::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){/*{{{*/
 
 	/*Intermediary*/
@@ -1512,6 +1378,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromSolutionOneDofCollpased{{{*/
-void  Penta::InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int enum_type){
+void       Penta::InputUpdateFromSolutionOneDofCollapsed(IssmDouble* solution,int enum_type){/*{{{*/
 
 	const int  numdof   = NDOF1*NUMVERTICES;
@@ -1552,6 +1417,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromVector(IssmDouble* vector, int name, int type);{{{*/
-void  Penta::InputUpdateFromVector(IssmDouble* vector, int name, int type){
+void       Penta::InputUpdateFromVector(IssmDouble* vector, int name, int type){/*{{{*/
 
 	const int   numdof         = NDOF1 *NUMVERTICES;
@@ -1612,22 +1476,41 @@
 }
 /*}}}*/
-/*FUNCTION Penta::IsOnBase{{{*/
-bool Penta::IsOnBase(void){
-
-	bool onbase;
-	inputs->GetInputValue(&onbase,MeshElementonbaseEnum);
-	return onbase;
-}
-/*}}}*/
-/*FUNCTION Penta::IsOnSurface{{{*/
-bool Penta::IsOnSurface(void){
-
-	bool onsurface;
-	inputs->GetInputValue(&onsurface,MeshElementonsurfaceEnum);
-	return onsurface;
-}
-/*}}}*/
-/*FUNCTION Penta::IsNodeOnShelfFromFlags {{{*/
-bool   Penta::IsNodeOnShelfFromFlags(IssmDouble* flags){
+bool       Penta::IsOnBase(void){/*{{{*/
+
+	IssmDouble values[NUMVERTICES];
+	IssmDouble sum;
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonbaseEnum);
+	sum = values[0]+values[1]+values[2]+values[3]+values[4]+values[5];
+	_assert_(sum==0. || sum==3.);
+
+	if(sum==3){
+		return true;
+	}
+	else{
+		return false;
+	}
+}
+/*}}}*/
+bool       Penta::IsOnSurface(void){/*{{{*/
+
+	IssmDouble values[NUMVERTICES];
+	IssmDouble sum;
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonsurfaceEnum);
+	sum = values[0]+values[1]+values[2]+values[3]+values[4]+values[5];
+	_assert_(sum==0. || sum==3.);
+
+	if(sum==3){
+		return true;
+	}
+	else{
+		return false;
+	}
+}
+/*}}}*/
+bool   Penta::IsNodeOnShelfFromFlags(IssmDouble* flags){/*{{{*/
 
 	int  i;
@@ -1643,6 +1526,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::JacobianDeterminant{{{*/
-void Penta::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void       Penta::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1651,6 +1533,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::JacobianDeterminantBase{{{*/
-void Penta::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+void       Penta::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1659,6 +1540,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::JacobianDeterminantLine{{{*/
-void Penta::JacobianDeterminantLine(IssmDouble* pJdet,IssmDouble* xyz_list_line,Gauss* gauss){
+void       Penta::JacobianDeterminantLine(IssmDouble* pJdet,IssmDouble* xyz_list_line,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1667,6 +1547,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::JacobianDeterminantTop{{{*/
-void Penta::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){
+void       Penta::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1675,6 +1554,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::JacobianDeterminantSurface{{{*/
-void Penta::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list_quad,Gauss* gauss){
+void       Penta::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list_quad,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1683,6 +1561,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MinEdgeLength{{{*/
-IssmDouble Penta::MinEdgeLength(IssmDouble* xyz_list){
+IssmDouble Penta::MinEdgeLength(IssmDouble* xyz_list){/*{{{*/
 	/*Return the minimum lenght of the nine egdes of the penta*/
 
@@ -1705,6 +1582,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NodalValue {{{*/
-int    Penta::NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){
+int    Penta::NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){/*{{{*/
 
 	int i;
@@ -1737,16 +1613,13 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NewGauss(){{{*/
-Gauss* Penta::NewGauss(void){
+Gauss* Penta::NewGauss(void){/*{{{*/
 	return new GaussPenta();
 }
 /*}}}*/
-/*FUNCTION Penta::NewGauss(int order){{{*/
-Gauss* Penta::NewGauss(int order){
+Gauss* Penta::NewGauss(int order){/*{{{*/
 	return new GaussPenta(order,order);
 }
 /*}}}*/
-/*FUNCTION Penta::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){{{*/
-Gauss* Penta::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){
+Gauss* Penta::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){/*{{{*/
 
 	IssmDouble  area_coordinates[4][3];
@@ -1757,21 +1630,17 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NewGaussBase(int order){{{*/
-Gauss* Penta::NewGaussBase(int order){
+Gauss* Penta::NewGaussBase(int order){/*{{{*/
 	return new GaussPenta(0,1,2,order);
 }
 /*}}}*/
-/*FUNCTION Penta::NewGaussLine(int vertex1,int vertex2,int order){{{*/
-Gauss* Penta::NewGaussLine(int vertex1,int vertex2,int order){
+Gauss* Penta::NewGaussLine(int vertex1,int vertex2,int order){/*{{{*/
 	return new GaussPenta(vertex1,vertex2,order);
 }
 /*}}}*/
-/*FUNCTION Penta::NewGaussTop(int order){{{*/
-Gauss* Penta::NewGaussTop(int order){
+Gauss* Penta::NewGaussTop(int order){/*{{{*/
 	return new GaussPenta(3,4,5,order);
 }
 /*}}}*/
-/*FUNCTION Penta::NodalFunctions{{{*/
-void Penta::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+void       Penta::NodalFunctions(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1780,6 +1649,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NodalFunctionsP1{{{*/
-void Penta::NodalFunctionsP1(IssmDouble* basis, Gauss* gauss){
+void       Penta::NodalFunctionsP1(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1788,6 +1656,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NodalFunctionsDerivatives{{{*/
-void Penta::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Penta::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1796,6 +1663,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NodalFunctionsP1Derivatives{{{*/
-void Penta::NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Penta::NodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1804,6 +1670,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NodalFunctionsMINIDerivatives{{{*/
-void Penta::NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Penta::NodalFunctionsMINIDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
@@ -1812,38 +1677,33 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NodalFunctionsDerivativesVelocity{{{*/
-void Penta::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Penta::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
-	this->GetNodalFunctionsDerivativesVelocity(dbasis,xyz_list,(GaussPenta*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Penta::NodalFunctionsVelocity{{{*/
-void Penta::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussPenta*)gauss,this->VelocityInterpolation());
+
+}
+/*}}}*/
+void       Penta::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
-	this->GetNodalFunctionsVelocity(basis,(GaussPenta*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Penta::NodalFunctionsPressure{{{*/
-void Penta::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){
+	this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->VelocityInterpolation());
+
+}
+/*}}}*/
+void       Penta::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
-	this->GetNodalFunctionsPressure(basis,(GaussPenta*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Penta::NodalFunctionsTensor{{{*/
-void Penta::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){
+	this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->PressureInterpolation());
+
+}
+/*}}}*/
+void       Penta::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussPentaEnum);
-	this->GetNodalFunctionsTensor(basis,(GaussPenta*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Penta::NormalBase {{{*/
-void Penta::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){
+	this->GetNodalFunctions(basis,(GaussPenta*)gauss,this->TensorInterpolation());
+
+}
+/*}}}*/
+void       Penta::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){/*{{{*/
 
 	IssmDouble v13[3],v23[3];
@@ -1867,6 +1727,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NormalTop {{{*/
-void Penta::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){
+void       Penta::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){/*{{{*/
 
 	int i;
@@ -1890,16 +1749,13 @@
 }
 /*}}}*/
-/*FUNCTION Penta::NumberofNodesPressure{{{*/
-int Penta::NumberofNodesPressure(void){
-	return PentaRef::NumberofNodesPressure();
-}
-/*}}}*/
-/*FUNCTION Penta::NumberofNodesVelocity{{{*/
-int Penta::NumberofNodesVelocity(void){
-	return PentaRef::NumberofNodesVelocity();
-}
-/*}}}*/
-/*FUNCTION Penta::PositiveDegreeDay{{{*/
-void  Penta::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){
+int        Penta::NumberofNodesPressure(void){/*{{{*/
+	return PentaRef::NumberofNodes(this->PressureInterpolation());
+}
+/*}}}*/
+int        Penta::NumberofNodesVelocity(void){/*{{{*/
+	return PentaRef::NumberofNodes(this->VelocityInterpolation());
+}
+/*}}}*/
+void       Penta::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){/*{{{*/
 
    IssmDouble agd[NUMVERTICES];             // surface mass balance
@@ -1952,6 +1808,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ReduceMatrices{{{*/
-void Penta::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){
+void       Penta::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){/*{{{*/
 
 	int analysis_type;
@@ -2009,6 +1864,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ResetFSBasalBoundaryCondition{{{*/
-void  Penta::ResetFSBasalBoundaryCondition(void){
+void       Penta::ResetFSBasalBoundaryCondition(void){/*{{{*/
 
 	int          approximation;
@@ -2072,12 +1926,10 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SetClone {{{*/
-void  Penta::SetClone(int* minranks){
+void       Penta::SetClone(int* minranks){/*{{{*/
 
 	_error_("not implemented yet");
 }
 /*}}}*/
-/*FUNCTION Penta::SetCurrentConfiguration {{{*/
-void  Penta::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
+void       Penta::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){/*{{{*/
 
 	/*go into parameters and get the analysis_counter: */
@@ -2094,11 +1946,9 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SetTemporaryElementType{{{*/
-void Penta::SetTemporaryElementType(int element_type_in){
+void       Penta::SetTemporaryElementType(int element_type_in){/*{{{*/
 	this->element_type=element_type_in;
 }
 /*}}}*/
-/*FUNCTION Penta::SpawnTria {{{*/
-Tria*  Penta::SpawnTria(int index1,int index2,int index3){
+Tria*      Penta::SpawnTria(int index1,int index2,int index3){/*{{{*/
 
 	int analysis_counter;
@@ -2127,6 +1977,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SpawnBasalElement{{{*/
-Element*  Penta::SpawnBasalElement(void){
+Element*   Penta::SpawnBasalElement(void){/*{{{*/
 
 	_assert_(this->IsOnBase());
@@ -2145,6 +1994,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SpawnTopElement{{{*/
-Element*  Penta::SpawnTopElement(void){
+Element*   Penta::SpawnTopElement(void){/*{{{*/
 
 	_assert_(this->IsOnSurface());
@@ -2155,6 +2003,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SmbGradients{{{*/
-void Penta::SmbGradients(void){
+void       Penta::SmbGradients(void){/*{{{*/
 
 	int i;
@@ -2201,6 +2048,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SurfaceArea {{{*/
-IssmDouble Penta::SurfaceArea(void){
+IssmDouble Penta::SurfaceArea(void){/*{{{*/
 
 	int    approximation;
@@ -2238,6 +2084,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::TimeAdapt{{{*/
-IssmDouble  Penta::TimeAdapt(void){
+IssmDouble Penta::TimeAdapt(void){/*{{{*/
 
 	int    i;
@@ -2282,6 +2127,5 @@
 	return dt;
 }/*}}}*/
-/*FUNCTION Penta::Update {{{*/
-void Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){ 
+void       Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){ /*{{{*/
 
 	/*Intermediaries*/
@@ -2589,6 +2433,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::UpdateConstraintsExtrudeFromBase{{{*/
-void  Penta::UpdateConstraintsExtrudeFromBase(void){
+void       Penta::UpdateConstraintsExtrudeFromBase(void){/*{{{*/
 
 	if(!IsOnBase()) return;
@@ -2614,6 +2457,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::UpdateConstraintsExtrudeFromTop{{{*/
-void  Penta::UpdateConstraintsExtrudeFromTop(void){
+void       Penta::UpdateConstraintsExtrudeFromTop(void){/*{{{*/
 
 	if(!IsOnSurface()) return;
@@ -2636,22 +2478,18 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ValueP1OnGauss{{{*/
-void Penta::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){
+void       Penta::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){/*{{{*/
 	PentaRef::GetInputValue(pvalue,values,gauss,P1Enum);
 }
 /*}}}*/
-/*FUNCTION Penta::ValueP1DerivativesOnGauss{{{*/
-void Penta::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){
+void       Penta::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	PentaRef::GetInputDerivativeValue(dvalue,values,xyz_list,gauss);
 }
 /*}}}*/
-/*FUNCTION Penta::VertexConnectivity{{{*/
-int Penta::VertexConnectivity(int vertexindex){
+int        Penta::VertexConnectivity(int vertexindex){/*{{{*/
 	_assert_(this->vertices);
 	return this->vertices[vertexindex]->Connectivity();
 }
 /*}}}*/
-/*FUNCTION Penta::VerticalSegmentIndices{{{*/
-void Penta::VerticalSegmentIndices(int** pindices,int* pnumseg){
+void       Penta::VerticalSegmentIndices(int** pindices,int* pnumseg){/*{{{*/
 
 	/*output*/
@@ -2666,6 +2504,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ViscousHeating{{{*/
-void Penta::ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){
+void       Penta::ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
 
 	/*Intermediaries*/
@@ -2683,16 +2520,13 @@
 }
 /*}}}*/
-/*FUNCTION Penta::VelocityInterpolation{{{*/
-int Penta::VelocityInterpolation(void){
+int        Penta::VelocityInterpolation(void){/*{{{*/
 	return PentaRef::VelocityInterpolation();
 }
 /*}}}*/
-/*FUNCTION Penta::PressureInterpolation{{{*/
-int Penta::PressureInterpolation(void){
+int        Penta::PressureInterpolation(void){/*{{{*/
 	return PentaRef::PressureInterpolation();
 }
 /*}}}*/
-/*FUNCTION Penta::IsZeroLevelset{{{*/
-bool Penta::IsZeroLevelset(int levelset_enum){
+bool       Penta::IsZeroLevelset(int levelset_enum){/*{{{*/
 
 	bool        iszerols;
@@ -2712,5 +2546,5 @@
 }
 /*}}}*/
-bool  Penta::IsIcefront(void){/*{{{*/
+bool       Penta::IsIcefront(void){/*{{{*/
 
 	bool isicefront;
@@ -2731,11 +2565,9 @@
 	return isicefront;
 }/*}}}*/
-/*FUNCTION Penta::AverageOntoPartition {{{*/
-void  Penta::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){
+void       Penta::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){/*{{{*/
 	_error_("Not supported yet!");
 }
 /*}}}*/
-/*FUNCTION Penta::IceVolume {{{*/
-IssmDouble Penta::IceVolume(void){
+IssmDouble Penta::IceVolume(void){/*{{{*/
 
 	/*The volume of a troncated prism is base * 1/3 sum(length of edges)*/
@@ -2759,6 +2591,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::IceVolumeAboveFloatation {{{*/
-IssmDouble Penta::IceVolumeAboveFloatation(void){
+IssmDouble Penta::IceVolumeAboveFloatation(void){/*{{{*/
 
 	/*Volume above floatation: H + rho_water/rho_ice*bathymetry for nodes on the bed*/
@@ -2790,6 +2621,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MinVel{{{*/
-void  Penta::MinVel(IssmDouble* pminvel){
+void       Penta::MinVel(IssmDouble* pminvel){/*{{{*/
 
 	/*Get minimum:*/
@@ -2800,6 +2630,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MinVx{{{*/
-void  Penta::MinVx(IssmDouble* pminvx){
+void       Penta::MinVx(IssmDouble* pminvx){/*{{{*/
 
 	/*Get minimum:*/
@@ -2810,6 +2639,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MinVy{{{*/
-void  Penta::MinVy(IssmDouble* pminvy){
+void       Penta::MinVy(IssmDouble* pminvy){/*{{{*/
 
 	/*Get minimum:*/
@@ -2820,6 +2648,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MinVz{{{*/
-void  Penta::MinVz(IssmDouble* pminvz){
+void       Penta::MinVz(IssmDouble* pminvz){/*{{{*/
 
 	/*Get minimum:*/
@@ -2830,6 +2657,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MassFlux {{{*/
-IssmDouble Penta::MassFlux( IssmDouble* segment){
+IssmDouble Penta::MassFlux( IssmDouble* segment){/*{{{*/
 
 	IssmDouble mass_flux=0;
@@ -2854,6 +2680,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MassFlux {{{*/
-IssmDouble Penta::MassFlux( IssmDouble x1, IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){
+IssmDouble Penta::MassFlux( IssmDouble x1, IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){/*{{{*/
 
 	IssmDouble mass_flux=0;
@@ -2878,6 +2703,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxAbsVx{{{*/
-void  Penta::MaxAbsVx(IssmDouble* pmaxabsvx){
+void       Penta::MaxAbsVx(IssmDouble* pmaxabsvx){/*{{{*/
 
 	/*Get maximum:*/
@@ -2888,6 +2712,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxAbsVy{{{*/
-void  Penta::MaxAbsVy(IssmDouble* pmaxabsvy){
+void       Penta::MaxAbsVy(IssmDouble* pmaxabsvy){/*{{{*/
 
 	/*Get maximum:*/
@@ -2898,6 +2721,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxAbsVz{{{*/
-void  Penta::MaxAbsVz(IssmDouble* pmaxabsvz){
+void       Penta::MaxAbsVz(IssmDouble* pmaxabsvz){/*{{{*/
 
 	/*Get maximum:*/
@@ -2908,6 +2730,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxVel{{{*/
-void  Penta::MaxVel(IssmDouble* pmaxvel){
+void       Penta::MaxVel(IssmDouble* pmaxvel){/*{{{*/
 
 	/*Get maximum:*/
@@ -2919,6 +2740,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxVx{{{*/
-void  Penta::MaxVx(IssmDouble* pmaxvx){
+void       Penta::MaxVx(IssmDouble* pmaxvx){/*{{{*/
 
 	/*Get maximum:*/
@@ -2929,6 +2749,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxVy{{{*/
-void  Penta::MaxVy(IssmDouble* pmaxvy){
+void       Penta::MaxVy(IssmDouble* pmaxvy){/*{{{*/
 
 	/*Get maximum:*/
@@ -2939,6 +2758,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MaxVz{{{*/
-void  Penta::MaxVz(IssmDouble* pmaxvz){
+void       Penta::MaxVz(IssmDouble* pmaxvz){/*{{{*/
 
 	/*Get maximum:*/
@@ -2949,6 +2767,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::ElementResponse{{{*/
-void Penta::ElementResponse(IssmDouble* presponse,int response_enum){
+void       Penta::ElementResponse(IssmDouble* presponse,int response_enum){/*{{{*/
 
 	switch(response_enum){
@@ -2979,6 +2796,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::TotalSmb {{{*/
-IssmDouble Penta::TotalSmb(void){
+IssmDouble Penta::TotalSmb(void){/*{{{*/
 
 	/*The smb[Gt yr-1] of one element is area[m2] * smb [ m ice yr^-1] * rho_ice [kg m-3] / 1e+10^12 */
@@ -3011,6 +2827,5 @@
 
 #ifdef _HAVE_GIA_
-/*FUNCTION Penta::GiaDeflection {{{*/
-void Penta::GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x,IssmDouble* y){
+void       Penta::GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x,IssmDouble* y){/*{{{*/
 	_error_("GIA deflection not implemented yet!");
 }
@@ -3018,6 +2833,5 @@
 #endif
 
-/*FUNCTION Penta::ControlInputGetGradient{{{*/
-void Penta::ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){
+void       Penta::ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){/*{{{*/
 
 	int vertexpidlist[NUMVERTICES];
@@ -3042,6 +2856,5 @@
 
 }/*}}}*/
-/*FUNCTION Penta::ControlInputScaleGradient{{{*/
-void Penta::ControlInputScaleGradient(int enum_type,IssmDouble scale){
+void       Penta::ControlInputScaleGradient(int enum_type,IssmDouble scale){/*{{{*/
 
 	Input* input=NULL;
@@ -3061,6 +2874,5 @@
 	((ControlInput*)input)->ScaleGradient(scale);
 }/*}}}*/
-/*FUNCTION Penta::ControlInputSetGradient{{{*/
-void Penta::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){
+void       Penta::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){/*{{{*/
 
 	int    vertexpidlist[NUMVERTICES];
@@ -3087,6 +2899,5 @@
 
 }/*}}}*/
-/*FUNCTION Penta::ControlToVectors{{{*/
-void Penta::ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){
+void       Penta::ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){/*{{{*/
 
 	Input* input=NULL;
@@ -3129,6 +2940,5 @@
 
 }/*}}}*/
-/*FUNCTION Penta::GradientIndexing{{{*/
-void Penta::GradientIndexing(int* indexing,int control_index){
+void       Penta::GradientIndexing(int* indexing,int control_index){/*{{{*/
 
 	/*Get some parameters*/
@@ -3143,6 +2953,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::Gradj {{{*/
-void  Penta::Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){
+void       Penta::Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){/*{{{*/
 	/*dJ/dalpha = ∂L/∂alpha = ∂J/∂alpha + ∂/∂alpha(KU-F)*/
 
@@ -3236,6 +3045,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GradjDragSSA {{{*/
-void  Penta::GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){
+void       Penta::GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Gradient is 0 if on shelf or not on bed*/
@@ -3248,6 +3056,5 @@
 
 } /*}}}*/
-/*FUNCTION Penta::GradjDragHO {{{*/
-void  Penta::GradjDragHO(Vector<IssmDouble>* gradient,int control_index){
+void       Penta::GradjDragHO(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	int        i,j;
@@ -3292,5 +3099,5 @@
 
 		/*Build alpha_complement_list: */
-		friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,NULL);
+		friction->GetAlphaComplement(&alpha_complement,gauss);
 
 		dragcoefficient_input->GetInputValue(&drag, gauss);
@@ -3319,6 +3126,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GradjDragFS {{{*/
-void  Penta::GradjDragFS(Vector<IssmDouble>* gradient,int control_index){
+void       Penta::GradjDragFS(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	int        i,j;
@@ -3364,5 +3170,5 @@
 
 		/*Recover alpha_complement and drag: */
-		friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,vz_input);
+		friction->GetAlphaComplement(&alpha_complement,gauss);
 		drag_input->GetInputValue(&drag,gauss);
 
@@ -3411,6 +3217,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::GradjBbarSSA {{{*/
-void  Penta::GradjBbarSSA(Vector<IssmDouble>* gradient,int control_index){
+void       Penta::GradjBbarSSA(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*This element should be collapsed into a tria element at its base*/
@@ -3431,6 +3236,5 @@
 
 } /*}}}*/
-/*FUNCTION Penta::GradjBbarHO {{{*/
-void  Penta::GradjBbarHO(Vector<IssmDouble>* gradient,int control_index){
+void       Penta::GradjBbarHO(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Gradient is computed on bed only (Bbar)*/
@@ -3450,6 +3254,5 @@
 	this->inputs->DeleteInput(DamageDbarEnum);
 } /*}}}*/
-/*FUNCTION Penta::GradjBbarFS {{{*/
-void  Penta::GradjBbarFS(Vector<IssmDouble>* gradient,int control_index){
+void       Penta::GradjBbarFS(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Gradient is computed on bed only (Bbar)*/
@@ -3469,6 +3272,5 @@
 	this->inputs->DeleteInput(DamageDbarEnum);
 } /*}}}*/
-/*FUNCTION Penta::InputControlUpdate{{{*/
-void  Penta::InputControlUpdate(IssmDouble scalar,bool save_parameter){
+void       Penta::InputControlUpdate(IssmDouble scalar,bool save_parameter){/*{{{*/
 
 	/*Intermediary*/
@@ -3513,249 +3315,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SurfaceAverageVelMisfit {{{*/
-IssmDouble Penta::SurfaceAverageVelMisfit(void){
-
-	int    approximation;
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*retrieve inputs :*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/*Bail out if this element if:
-	 * -> Non SSA and not on the surface
-	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
-		return 0;
-	}
-	else if (approximation==SSAApproximationEnum){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute SurfaceAverageVelMisfit*/
-		tria=(Tria*)SpawnTria(0,1,2);
-		J=tria->SurfaceAverageVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5);
-		J=tria->SurfaceAverageVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::SurfaceAbsVelMisfit {{{*/
-IssmDouble Penta::SurfaceAbsVelMisfit(void){
-
-	int    approximation;
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*retrieve inputs :*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/*Bail out if this element if:
-	 * -> Non SSA and not on the surface
-	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
-		return 0;
-	}
-	else if (approximation==SSAApproximationEnum){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute SurfaceAbsVelMisfit*/
-		tria=(Tria*)SpawnTria(0,1,2);
-		J=tria->SurfaceAbsVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5);
-		J=tria->SurfaceAbsVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::SurfaceLogVelMisfit {{{*/
-IssmDouble Penta::SurfaceLogVelMisfit(void){
-
-	int    approximation;
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*retrieve inputs :*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/*Bail out if this element if:
-	 * -> Non SSA and not on the surface
-	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
-		return 0;
-	}
-	else if (approximation==SSAApproximationEnum){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute SurfaceLogVelMisfit*/
-		tria=(Tria*)SpawnTria(0,1,2); //lower face is 0, upper face is 1.
-		J=tria->SurfaceLogVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5); //lower face is 0, upper face is 1.
-		J=tria->SurfaceLogVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::SurfaceLogVxVyMisfit {{{*/
-IssmDouble Penta::SurfaceLogVxVyMisfit(void){
-
-	IssmDouble J;
-	Tria* tria=NULL;
-
-	/*inputs: */
-	int  approximation;
-
-	/*retrieve inputs :*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/*Bail out if this element if:
-	 * -> Non SSA and not on the surface
-	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
-		return 0;
-	}
-	else if (approximation==SSAApproximationEnum){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute SurfaceLogVxVyMisfit*/
-		tria=(Tria*)SpawnTria(0,1,2);
-		J=tria->SurfaceLogVxVyMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5);
-		J=tria->SurfaceLogVxVyMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::SurfaceRelVelMisfit {{{*/
-IssmDouble Penta::SurfaceRelVelMisfit(void){
-
-	int    approximation;
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*retrieve inputs :*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/*Bail out if this element if:
-	 * -> Non SSA and not on the surface
-	 * -> SSA (2d model) and not on bed) */
-	if ((approximation!=SSAApproximationEnum && !IsOnSurface()) || (approximation==SSAApproximationEnum && !IsOnBase())){
-		return 0;
-	}
-	else if (approximation==SSAApproximationEnum){
-
-		/*This element should be collapsed into a tria element at its base. Create this tria element, 
-		 * and compute SurfaceRelVelMisfit*/
-		tria=(Tria*)SpawnTria(0,1,2);
-		J=tria->SurfaceRelVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-	else{
-
-		tria=(Tria*)SpawnTria(3,4,5);
-		J=tria->SurfaceRelVelMisfit();
-		delete tria->material; delete tria;
-		return J;
-	}
-}
-/*}}}*/
-/*FUNCTION Penta::ThicknessAbsGradient{{{*/
-IssmDouble Penta::ThicknessAbsGradient(void){
-
-	_error_("Not implemented yet");
-}
-/*}}}*/
-/*FUNCTION Penta::ThicknessAbsMisfit {{{*/
-IssmDouble Penta::ThicknessAbsMisfit(void){
-
-	int    approximation;
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*retrieve inputs :*/
-	inputs->GetInputValue(&approximation,ApproximationEnum);
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-	_error_("Not implemented yet");
-
-	tria=(Tria*)SpawnTria(0,1,2);
-	J=tria->ThicknessAbsMisfit();
-	delete tria->material; delete tria;
-	return J;
-}
-/*}}}*/
-/*FUNCTION Penta::DragCoefficientAbsGradient{{{*/
-IssmDouble Penta::DragCoefficientAbsGradient(void){
-
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*If on water, on shelf or not on bed, skip: */
-	if(!IsIceInElement()|| IsFloating() || !IsOnBase()) return 0;
-
-	tria=(Tria*)SpawnTria(0,1,2); //lower face is 0, upper face is 1
-	J=tria->DragCoefficientAbsGradient();
-	delete tria->material; delete tria;
-	return J;
-}
-/*}}}*/
-/*FUNCTION Penta::RheologyBbarAbsGradient{{{*/
-IssmDouble Penta::RheologyBbarAbsGradient(void){
-
-	IssmDouble J;
-	Tria*  tria=NULL;
-
-	/*If on water, on shelf or not on bed, skip: */
-	if(!IsIceInElement() || !IsOnBase()) return 0;
-
-	tria=(Tria*)SpawnTria(0,1,2);
-	J=tria->RheologyBbarAbsGradient();
-	delete tria->material; delete tria;
-	return J;
-}
-/*}}}*/
-/*FUNCTION Penta::GetVectorFromControlInputs{{{*/
-void  Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){
+void       Penta::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/
 
 	int vertexpidlist[NUMVERTICES];
@@ -3779,6 +3337,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::SetControlInputsFromVector{{{*/
-void  Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){
+void       Penta::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){/*{{{*/
 
 	IssmDouble  values[NUMVERTICES];
@@ -3809,6 +3366,5 @@
 
 #ifdef _HAVE_DAKOTA_
-/*FUNCTION Penta::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type);{{{*/
-void  Penta::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){
+void       Penta::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){/*{{{*/
 
 	int i,j;
@@ -3910,6 +3466,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type);{{{*/
-void  Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){
+void       Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/
 
 	int             i,t,row;
@@ -3950,6 +3505,5 @@
 /*}}}*/
 #endif
-/*FUNCTION Penta::GetSolutionFromInputsOneDof {{{*/
-void Penta::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){
+void       Penta::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){/*{{{*/
 
 	const int    numdof=NDOF1*NUMVERTICES;
@@ -3981,6 +3535,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::MigrateGroundingLine{{{*/
-void  Penta::MigrateGroundingLine(IssmDouble* phi_ungrounding){
+void       Penta::MigrateGroundingLine(IssmDouble* phi_ungrounding){/*{{{*/
 
 	int        i,migration_style;
@@ -4019,10 +3572,10 @@
 		}
 		/*Ice sheet: if hydrostatic bed above bathymetry, ice sheet starts to unground, elso do nothing */
-		/*Change only if AgressiveMigration or if the ice sheet is in contact with the ocean*/
+		/*Change only if AggressiveMigration or if the ice sheet is in contact with the ocean*/
 		else{
 			bed_hydro=-density*h[i];
 			if(bed_hydro>r[i]){
 				/*Unground only if the element is connected to the ice shelf*/
-				if(migration_style==AgressiveMigrationEnum || migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){
+				if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){
 					s[i]        = (1-density)*h[i];
 					b[i]        = -density*h[i];
@@ -4086,6 +3639,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::PotentialUngrounding{{{*/
-void  Penta::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){
+void       Penta::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){/*{{{*/
 
 	IssmDouble  h[NUMVERTICES],r[NUMVERTICES],gl[NUMVERTICES];
@@ -4114,6 +3666,5 @@
 }
 /*}}}*/
-/*FUNCTION Penta::UpdatePotentialUngrounding{{{*/
-int Penta::UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){
+int        Penta::UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){/*{{{*/
 
 	int i;
Index: /issm/trunk/src/c/classes/Elements/Penta.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Penta.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Penta.h	(revision 17989)
@@ -52,8 +52,8 @@
 		/*}}}*/
 		/*Element virtual functions definitions: {{{*/
-		void   BasalFrictionCreateInput(void);
 		IssmDouble CharacteristicLength(void){_error_("not implemented yet");};
 		void   ComputeBasalStress(Vector<IssmDouble>* sigma_b);
-		void   ComputeStrainRate(Vector<IssmDouble>* eps);
+		void   ComputeStrainRate();
+		void   ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
 		void   ComputeSigmaNN(){_error_("not implemented yet");};
 		void   ComputeStressTensor();
@@ -70,6 +70,4 @@
 		Penta* GetBasalPenta(void);
 		Element* GetUpperElement(void);
-		Element* GetLowerElement(void);
-		Element* GetSurfaceElement(void);
 		Element* GetBasalElement(void);
 		void   GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
@@ -79,12 +77,8 @@
 		int    GetNumberOfVertices(void);
 		void   GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type);
-		IssmDouble GetXcoord(Gauss* gauss);
-		IssmDouble GetYcoord(Gauss* gauss);
-		IssmDouble GetZcoord(Gauss* gauss);
 		void   GetVerticesCoordinatesBase(IssmDouble** pxyz_list);
 		void   GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
 
 		void   InputDepthAverageAtBase(int enum_type,int average_enum_type);
-		void   InputDuplicate(int original_enum,int new_enum);
 		void   InputScale(int enum_type,IssmDouble scale_factor);
 		int    NumberofNodesVelocity(void);
@@ -92,9 +86,10 @@
 		int    VelocityInterpolation();
 		int    PressureInterpolation();
+		int    TensorInterpolation(){_error_("not implemented yet");};
 		bool   IsZeroLevelset(int levelset_enum);
 		bool   IsIcefront(void);
+		bool   IsFaceOnBoundary(void){_error_("not implemented yet");};
 		void   ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
 		void   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented yet");};
-		void   GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};
 		void   PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm);
 		void   ReduceMatrices(ElementMatrix* Ke,ElementVector* pe);
@@ -137,5 +132,4 @@
 		#endif
 
-		IssmDouble DragCoefficientAbsGradient(void);
 		void   GradientIndexing(int* indexing,int control_index);
 		void   Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index);
@@ -152,15 +146,4 @@
 		void   ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index);
 		void   ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum);
-		IssmDouble RheologyBbarAbsGradient(void);
-		IssmDouble ThicknessAbsMisfit(void);
-		IssmDouble SurfaceAbsVelMisfit(void);
-		IssmDouble SurfaceRelVelMisfit(void);
-		IssmDouble SurfaceLogVelMisfit(void);
-		IssmDouble SurfaceLogVxVyMisfit(void);
-		IssmDouble SurfaceAverageVelMisfit(void);
-		IssmDouble ThicknessAbsGradient(void);
-		IssmDouble ThicknessAlongGradient(void){_error_("not supported");};
-		IssmDouble ThicknessAcrossGradient(void){_error_("not supported");};
-		IssmDouble BalancethicknessMisfit(void){_error_("not supported");};
 		void   InputControlUpdate(IssmDouble scalar,bool save_parameter);
 		IssmDouble Misfit(int modelenum,int observationenum,int weightsenum){_error_("not implemented yet");};
Index: /issm/trunk/src/c/classes/Elements/PentaRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/PentaRef.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/PentaRef.cpp	(revision 17989)
@@ -27,11 +27,9 @@
 
 /*Object constructors and destructor*/
-/*FUNCTION PentaRef::PentaRef(){{{*/
-PentaRef::PentaRef(){
+PentaRef::PentaRef(){/*{{{*/
 	this->element_type_list=NULL;
 }
 /*}}}*/
-/*FUNCTION PentaRef::PentaRef(int* types,int nummodels){{{*/
-PentaRef::PentaRef(const int nummodels){
+PentaRef::PentaRef(const int nummodels){/*{{{*/
 
 	/*Only allocate pointer*/
@@ -40,6 +38,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::~PentaRef(){{{*/
-PentaRef::~PentaRef(){
+PentaRef::~PentaRef(){/*{{{*/
 	xDelete<int>(element_type_list);
 }
@@ -47,6 +44,5 @@
 
 /*Management*/
-/*FUNCTION PentaRef::SetElementType{{{*/
-void PentaRef::SetElementType(int type,int type_counter){
+void PentaRef::SetElementType(int type,int type_counter){/*{{{*/
 
 	/*initialize element type*/
@@ -56,6 +52,5 @@
 
 /*Reference Element numerics*/
-/*FUNCTION PentaRef::GetJacobian {{{*/
-void PentaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss_in){
+void PentaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss_in){/*{{{*/
 	/*The Jacobian is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -113,6 +108,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetJacobianDeterminant {{{*/
-void PentaRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){
+void PentaRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*On a penta, Jacobian varies according to coordinates. We need to get the Jacobian, and take 
 	 * the determinant of it: */
@@ -128,6 +122,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetTriaJacobianDeterminant{{{*/
-void PentaRef::GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){
+void PentaRef::GetTriaJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -148,6 +141,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetSegmentJacobianDeterminant{{{*/
-void PentaRef::GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){
+void PentaRef::GetSegmentJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -165,6 +157,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetJacobianInvert {{{*/
-void PentaRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,Gauss* gauss){
+void PentaRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	/*Jacobian*/
@@ -178,6 +169,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){{{*/
-void PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){
+void PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -187,6 +177,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){{{*/
-void PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){
+void PentaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -328,43 +317,13 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
 	}
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsVelocity{{{*/
-void PentaRef::GetNodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	int save = this->element_type;
-	this->element_type = VelocityInterpolation();
-	this->GetNodalFunctions(basis,gauss);
-	this->element_type = save;
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsPressure{{{*/
-void PentaRef::GetNodalFunctionsPressure(IssmDouble* basis,Gauss* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	int save = this->element_type;
-	this->element_type = PressureInterpolation();
-	this->GetNodalFunctions(basis,gauss);
-	this->element_type = save;
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsTensor{{{*/
-void PentaRef::GetNodalFunctionsTensor(IssmDouble* basis,Gauss* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	int save = this->element_type;
-	this->element_type = TensorInterpolation();
-	this->GetNodalFunctions(basis,gauss);
-	this->element_type = save;
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsDerivatives{{{*/
-void PentaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
+void PentaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
+	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss,this->element_type);
+}
+/*}}}*/
+void PentaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -373,9 +332,9 @@
 
 	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
+	int numnodes = this->NumberofNodes(finiteelement);
 
 	/*Get nodal functions derivatives in reference triangle*/
 	IssmDouble* dbasis_ref=xNew<IssmDouble>(3*numnodes);
-	GetNodalFunctionsDerivativesReference(dbasis_ref,gauss); 
+	GetNodalFunctionsDerivativesReference(dbasis_ref,gauss,finiteelement);
 
 	/*Get Jacobian invert: */
@@ -397,28 +356,11 @@
 	/*Clean up*/
 	xDelete<IssmDouble>(dbasis_ref);
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsDerivativesVelocity{{{*/
-void PentaRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
-
-	int save = this->element_type;
-	this->element_type = VelocityInterpolation();
-	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-	this->element_type = save;
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsDerivativesPressure{{{*/
-void PentaRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
-
-	int save = this->element_type;
-	this->element_type = PressureInterpolation();
-	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-	this->element_type = save;
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsDerivativesReference{{{*/
-void PentaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){
+}
+/*}}}*/
+void PentaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss){/*{{{*/
+	GetNodalFunctionsDerivativesReference(dbasis,gauss,this->element_type);
+}
+/*}}}*/
+void PentaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in,int finiteelement){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -434,5 +376,5 @@
 	IssmDouble zeta=gauss->coord4;
 
-	switch(this->element_type){
+	switch(finiteelement){
 		case P0Enum: 
 			/*Zero derivative*/
@@ -837,29 +779,10 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
 	}
 
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsMINI{{{*/
-void PentaRef::GetNodalFunctionsMINI(IssmDouble* l1l7, Gauss* gauss_in){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	/*Cast gauss to GaussPenta*/
-	_assert_(gauss_in->Enum()==GaussPentaEnum);
-	GaussPenta* gauss = dynamic_cast<GaussPenta*>(gauss_in);
-
-	l1l7[0]=gauss->coord1*(1.0-gauss->coord4)/2.0;
-	l1l7[1]=gauss->coord2*(1.0-gauss->coord4)/2.0;
-	l1l7[2]=gauss->coord3*(1.0-gauss->coord4)/2.0;
-	l1l7[3]=gauss->coord1*(1.0+gauss->coord4)/2.0;
-	l1l7[4]=gauss->coord2*(1.0+gauss->coord4)/2.0;
-	l1l7[5]=gauss->coord3*(1.0+gauss->coord4)/2.0;
-	l1l7[6]=27*gauss->coord1*gauss->coord2*gauss->coord3*(1.0+gauss->coord4)*(1.0-gauss->coord4);
-
-}
-/*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsMINIDerivatives{{{*/
-void PentaRef::GetNodalFunctionsMINIDerivatives(IssmDouble* dbasismini,IssmDouble* xyz_list, Gauss* gauss){
+void PentaRef::GetNodalFunctionsMINIDerivatives(IssmDouble* dbasismini,IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -890,6 +813,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsMINIDerivativesReference{{{*/
-void PentaRef::GetNodalFunctionsMINIDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){
+void PentaRef::GetNodalFunctionsMINIDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -932,6 +854,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsP1 {{{*/
-void PentaRef::GetNodalFunctionsP1(IssmDouble* basis, Gauss* gauss_in){
+void PentaRef::GetNodalFunctionsP1(IssmDouble* basis, Gauss* gauss_in){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -949,6 +870,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsP1Derivatives {{{*/
-void PentaRef::GetNodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
+void PentaRef::GetNodalFunctionsP1Derivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -978,6 +898,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetNodalFunctionsP1DerivativesReference {{{*/
-void PentaRef::GetNodalFunctionsP1DerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){
+void PentaRef::GetNodalFunctionsP1DerivativesReference(IssmDouble* dbasis,Gauss* gauss_in){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -1016,6 +935,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetQuadJacobianDeterminant{{{*/
-void PentaRef::GetQuadJacobianDeterminant(IssmDouble* Jdet,IssmDouble* xyz_list,Gauss* gauss){
+void PentaRef::GetQuadJacobianDeterminant(IssmDouble* Jdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -1042,6 +960,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss){{{*/
-void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss){
+void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss){/*{{{*/
 
 	GetInputValue(pvalue,plist,gauss,this->element_type);
@@ -1049,6 +966,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss,int finiteelement){{{*/
-void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss,int finiteelement){
+void PentaRef::GetInputValue(IssmDouble* pvalue,IssmDouble* plist,Gauss* gauss,int finiteelement){/*{{{*/
 
 	/*Output*/
@@ -1071,6 +987,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::GetInputDerivativeValue{{{*/
-void PentaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss){
+void PentaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
 	/*From node values of parameter p (p_list[0], p_list[1], p_list[2],
 	 * p_list[3], p_list[4] and p_list[4]), return parameter derivative value at
@@ -1108,12 +1023,10 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::NumberofNodes(){{{*/
-int PentaRef::NumberofNodes(void){
+int  PentaRef::NumberofNodes(void){/*{{{*/
 
 	return this->NumberofNodes(this->element_type);
 }
 /*}}}*/
-/*FUNCTION PentaRef::NumberofNodes(int finiteelement){{{*/
-int PentaRef::NumberofNodes(int finiteelement){
+int  PentaRef::NumberofNodes(int finiteelement){/*{{{*/
 
 	switch(finiteelement){
@@ -1139,38 +1052,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::NumberofNodesPressure{{{*/
-int PentaRef::NumberofNodesPressure(void){
-
-	switch(this->element_type){
-		case P1P1Enum:          return NUMNODESP1;
-		case P1P1GLSEnum:       return NUMNODESP1;
-		case MINIcondensedEnum: return NUMNODESP1;
-		case MINIEnum:          return NUMNODESP1;
-		case TaylorHoodEnum:    return NUMNODESP1;
-		case OneLayerP4zEnum:   return NUMNODESP1;
-		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-	return -1;
-}
-/*}}}*/
-/*FUNCTION PentaRef::NumberofNodesVelocity{{{*/
-int PentaRef::NumberofNodesVelocity(void){
-
-	switch(this->element_type){
-		case P1P1Enum:          return NUMNODESP1;
-		case P1P1GLSEnum:       return NUMNODESP1;
-		case MINIcondensedEnum: return NUMNODESP1b;
-		case MINIEnum:          return NUMNODESP1b;
-		case TaylorHoodEnum:    return NUMNODESP2;
-		case OneLayerP4zEnum:   return NUMNODESP2xP4;
-		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-	return -1;
-}
-/*}}}*/
-/*FUNCTION PentaRef::VelocityInterpolation{{{*/
-int PentaRef::VelocityInterpolation(void){
+int  PentaRef::VelocityInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -1187,6 +1067,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::PressureInterpolation{{{*/
-int PentaRef::PressureInterpolation(void){
+int  PentaRef::PressureInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -1203,6 +1082,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::TensorInterpolation{{{*/
-int PentaRef::TensorInterpolation(void){
+int  PentaRef::TensorInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -1214,6 +1092,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::BasalNodeIndices{{{*/
-void PentaRef::BasalNodeIndices(int* pnumindices,int** pindices,int finiteelement){
+void PentaRef::BasalNodeIndices(int* pnumindices,int** pindices,int finiteelement){/*{{{*/
 
 	/*Output*/
@@ -1289,6 +1166,5 @@
 }
 /*}}}*/
-/*FUNCTION PentaRef::SurfaceNodeIndices{{{*/
-void PentaRef::SurfaceNodeIndices(int* pnumindices,int** pindices,int finiteelement){
+void PentaRef::SurfaceNodeIndices(int* pnumindices,int** pindices,int finiteelement){/*{{{*/
 
 	/*Output*/
Index: /issm/trunk/src/c/classes/Elements/PentaRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/PentaRef.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/PentaRef.h	(revision 17989)
@@ -24,13 +24,9 @@
 		void GetNodalFunctions(IssmDouble* basis, Gauss* gauss);
 		void GetNodalFunctions(IssmDouble* basis, Gauss* gauss,int finiteelement);
-		void GetNodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss);
-		void GetNodalFunctionsPressure(IssmDouble* basis, Gauss* gauss);
-		void GetNodalFunctionsTensor(IssmDouble* basis, Gauss* gauss);
 		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
-		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
-		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
+		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss,int finiteelement);
 		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss);
+		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss,int finiteelement);
 		void GetNodalFunctionsP1(IssmDouble* l1l6, Gauss* gauss);
-		void GetNodalFunctionsMINI(IssmDouble* l1l7, Gauss* gauss);
 		void GetNodalFunctionsP1Derivatives(IssmDouble* dh1dh6,IssmDouble* xyz_list, Gauss* gauss);
 		void GetNodalFunctionsMINIDerivatives(IssmDouble* dh1dh7,IssmDouble* xyz_list, Gauss* gauss);
@@ -52,6 +48,4 @@
 		int  NumberofNodes(void);
 		int  NumberofNodes(int finiteelement);
-		int  NumberofNodesVelocity(void);
-		int  NumberofNodesPressure(void);
 		int  VelocityInterpolation(void);
 		int  PressureInterpolation(void);
Index: /issm/trunk/src/c/classes/Elements/Seg.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Seg.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Seg.cpp	(revision 17989)
@@ -19,6 +19,5 @@
 #define NUMVERTICES 2
 /*Constructors/destructor/copy*/
-/*FUNCTION Seg::Seg(int id, int sid,int index, IoModel* iomodel,int nummodels){{{*/
-Seg::Seg(int seg_id, int seg_sid, int index, IoModel* iomodel,int nummodels)
+Seg::Seg(int seg_id, int seg_sid, int index, IoModel* iomodel,int nummodels)/*{{{*/
 		:SegRef(nummodels),ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
 
@@ -40,17 +39,14 @@
 		}
 /*}}}*/
-/*FUNCTION Seg::~Seg(){{{*/
-Seg::~Seg(){
+Seg::~Seg(){/*{{{*/
 	this->parameters=NULL;
 }
 /*}}}*/
-/*FUNCTION Seg::copy {{{*/
-Object* Seg::copy() {
+Object* Seg::copy(){/*{{{*/
 	_error_("not implemented yet");
 }
 /*}}}*/
 
-/*FUNCTION Seg::CharacteristicLength{{{*/
-IssmDouble Seg::CharacteristicLength(void){
+IssmDouble Seg::CharacteristicLength(void){/*{{{*/
 
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -65,11 +61,9 @@
 }
 /*}}}*/
-/*FUNCTION Seg::FiniteElement{{{*/
-int Seg::FiniteElement(void){
+int        Seg::FiniteElement(void){/*{{{*/
 	return this->element_type;
 }
 /*}}}*/
-/*FUNCTION Seg::ObjectEnum{{{*/
-int Seg::ObjectEnum(void){
+int        Seg::ObjectEnum(void){/*{{{*/
 
 	return SegEnum;
@@ -77,6 +71,5 @@
 }
 /*}}}*/
-
-void  Seg::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
+void       Seg::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
 	
 	/* Intermediaries */
@@ -106,16 +99,13 @@
 	*pxyz_front=xyz_front;
 }/*}}}*/
-/*FUNCTION Seg::GetNumberOfNodes;{{{*/
-int Seg::GetNumberOfNodes(void){
+int        Seg::GetNumberOfNodes(void){/*{{{*/
 	return this->NumberofNodes();
 }
 /*}}}*/
-/*FUNCTION Seg::GetNumberOfVertices;{{{*/
-int Seg::GetNumberOfVertices(void){
+int        Seg::GetNumberOfVertices(void){/*{{{*/
 	return NUMVERTICES;
 }
 /*}}}*/
-/*FUNCTION Seg::GetVerticesCoordinates(IssmDouble** pxyz_list){{{*/
-void Seg::GetVerticesCoordinates(IssmDouble** pxyz_list){
+void       Seg::GetVerticesCoordinates(IssmDouble** pxyz_list){/*{{{*/
 
 	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES*3);
@@ -126,5 +116,127 @@
 
 }/*}}}*/
-bool Seg::IsIcefront(void){/*{{{*/
+void       Seg::GradientIndexing(int* indexing,int control_index){/*{{{*/
+
+	/*Get some parameters*/
+	int num_controls;
+	parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
+
+	/*get gradient indices*/
+	for(int i=0;i<NUMVERTICES;i++){
+		indexing[i]=num_controls*this->vertices[i]->Pid() + control_index;
+	}
+
+}
+/*}}}*/
+void       Seg::GradjDragFS(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
+
+	int        i;
+	int        analysis_type;
+	int        vertexpidlist[NUMVERTICES];
+	int        connectivity[NUMVERTICES];
+	IssmDouble vx,lambda,alpha_complement,drag,Jdet;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble dk[NDOF2]; 
+	IssmDouble grade_g[NUMVERTICES]={0.0};
+	IssmDouble grade_g_gaussian[NUMVERTICES];
+	IssmDouble basis[3];
+	Friction*  friction=NULL;
+	GaussSeg  *gauss=NULL;
+
+	if(IsFloating())return;
+
+	/*retrive parameters: */
+	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	GradientIndexing(&vertexpidlist[0],control_index);
+	this->GetVerticesConnectivityList(&connectivity[0]);
+
+	/*Build frictoin element, needed later: */
+	friction=new Friction(this,1);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* adjointx_input=inputs->GetInput(AdjointxEnum);                   _assert_(adjointx_input);
+	Input* vx_input=inputs->GetInput(VxEnum);                               _assert_(vx_input);
+	Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussSeg(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
+		GetNodalFunctions(basis, gauss);
+
+		/*Build alpha_complement_list: */
+		friction->GetAlphaComplement(&alpha_complement,gauss);
+
+		dragcoefficient_input->GetInputValue(&drag, gauss);
+		adjointx_input->GetInputValue(&lambda, gauss);
+		vx_input->GetInputValue(&vx,gauss);
+		dragcoefficient_input->GetInputDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
+
+		/*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
+		for (i=0;i<NUMVERTICES;i++){
+			grade_g_gaussian[i]=-2*drag*alpha_complement*(lambda*vx)*Jdet*gauss->weight*basis[i];
+		}
+
+		/*Add gradje_g_gaussian vector to gradje_g: */
+		for(i=0;i<NUMVERTICES;i++){
+			_assert_(!xIsNan<IssmDouble>(grade_g[i]));
+			grade_g[i]+=grade_g_gaussian[i];
+		}
+	}
+	gradient->SetValues(NUMVERTICES,vertexpidlist,grade_g,ADD_VAL);
+
+	/*Clean up and return*/
+	delete gauss;
+	delete friction;
+}
+/*}}}*/
+void       Seg::GradjDragGradient(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
+
+	int        i;
+	int        vertexpidlist[NUMVERTICES];
+	IssmDouble Jdet,weight;
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble dbasis[NDOF2][NUMVERTICES];
+	IssmDouble dk[NDOF2]; 
+	IssmDouble grade_g[NUMVERTICES]={0.0};
+	GaussSeg  *gauss=NULL;
+
+	/*Retrieve all inputs we will be needing: */
+	if(IsFloating())return;
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	GradientIndexing(&vertexpidlist[0],control_index);
+	Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
+	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);                 _assert_(weights_input);
+
+	/* Start  looping on the number of gaussian points: */
+	gauss=new GaussSeg(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
+		GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
+		weights_input->GetInputValue(&weight,gauss,DragCoefficientAbsGradientEnum);
+
+		/*Build alpha_complement_list: */
+		dragcoefficient_input->GetInputDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
+
+		/*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
+		for (i=0;i<NUMVERTICES;i++){
+			grade_g[i]+=-weight*Jdet*gauss->weight*dbasis[0][i]*dk[0];
+			_assert_(!xIsNan<IssmDouble>(grade_g[i]));
+		}
+	}
+	gradient->SetValues(NUMVERTICES,vertexpidlist,grade_g,ADD_VAL);
+
+	/*Clean up and return*/
+	delete gauss;
+}
+/*}}}*/
+bool       Seg::IsIcefront(void){/*{{{*/
 
 	bool isicefront;
@@ -145,6 +257,5 @@
 	return isicefront;
 }/*}}}*/
-/*FUNCTION Seg::JacobianDeterminant{{{*/
-void Seg::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void       Seg::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussSegEnum);
@@ -153,6 +264,5 @@
 }
 /*}}}*/
-/*FUNCTION Seg::JacobianDeterminantSurface{{{*/
-void Seg::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void       Seg::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	*pJdet = 1.;
@@ -160,16 +270,13 @@
 }
 /*}}}*/
-/*FUNCTION Seg::NewGauss(){{{*/
-Gauss* Seg::NewGauss(void){
+Gauss*     Seg::NewGauss(void){/*{{{*/
 	return new GaussSeg();
 }
 /*}}}*/
-/*FUNCTION Seg::NewGauss(int order){{{*/
-Gauss* Seg::NewGauss(int order){
+Gauss*     Seg::NewGauss(int order){/*{{{*/
 	return new GaussSeg(order);
 }
 /*}}}*/
-/*FUNCTION Seg::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){{{*/
-Gauss* Seg::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){
+Gauss*     Seg::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){/*{{{*/
 
 	/*Output*/
@@ -189,6 +296,5 @@
 }
 /*}}}*/
-/*FUNCTION Seg::NodalFunctions{{{*/
-void Seg::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+void       Seg::NodalFunctions(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussSegEnum);
@@ -197,6 +303,5 @@
 }
 /*}}}*/
-/*FUNCTION Seg::NodalFunctionsDerivatives{{{*/
-void Seg::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Seg::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussSegEnum);
@@ -205,6 +310,5 @@
 }
 /*}}}*/
-/*FUNCTION Seg::NormalSection{{{*/
-void Seg::NormalSection(IssmDouble* normal,IssmDouble* xyz_list_front){
+void       Seg::NormalSection(IssmDouble* normal,IssmDouble* xyz_list_front){/*{{{*/
 
 	IssmDouble* xyz_list = xNew<IssmDouble>(NUMVERTICES*3);
Index: /issm/trunk/src/c/classes/Elements/Seg.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Seg.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Seg.h	(revision 17989)
@@ -55,4 +55,5 @@
 		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b){_error_("not implemented yet");};
 		void        ComputeSigmaNN(){_error_("not implemented yet");};
+		void        ComputeStrainRate(){_error_("not implemented yet");};
 		void        ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
 		void        ComputeStressTensor(){_error_("not implemented yet");};
@@ -65,6 +66,4 @@
 		int         FiniteElement(void);
 		Element*    GetUpperElement(void){_error_("not implemented yet");};
-	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
-	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
 		Element*    GetBasalElement(void){_error_("not implemented yet");};
 		int         GetNodeIndex(Node* node){_error_("not implemented yet");};
@@ -104,11 +103,9 @@
 		void        ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
 		int         VelocityInterpolation(void){_error_("not implemented yet");};
+		int         TensorInterpolation(void){_error_("not implemented yet");};
 		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating){_error_("not implemented yet");};
 		IssmDouble  GetGroundedPortion(IssmDouble* xyz_list){_error_("not implemented yet");};
 		void        GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
 		Node*       GetNode(int node_number){_error_("Not implemented");};
-		IssmDouble  GetXcoord(Gauss* gauss){_error_("Not implemented");};
-		IssmDouble  GetYcoord(Gauss* gauss){_error_("Not implemented");};
-		IssmDouble  GetZcoord(Gauss* gauss){_error_("not implemented yet");};
 		int         GetElementType(void){_error_("not implemented yet");};
 		Gauss*      NewGauss(void);
@@ -125,11 +122,11 @@
 		bool        IsZeroLevelset(int levelset_enum){_error_("not implemented");};
 		bool		   IsIcefront(void);
+		bool   IsFaceOnBoundary(void){_error_("not implemented yet");};
 		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");};
 		void		   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum);
-		void        GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};
 
 		void        GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type){_error_("not implemented yet");};
 		void        InputDepthAverageAtBase(int enum_type,int average_enum_type){_error_("not implemented yet");};
-		void        InputDuplicate(int original_enum,int new_enum){_error_("not implemented yet");};
+		void        InputExtrude(int enum_type){_error_("not implemented"); /*For penta only*/};
 		void        InputScale(int enum_type,IssmDouble scale_factor){_error_("not implemented yet");};
 		void        MaterialUpdateFromTemperature(void){_error_("not implemented yet");};
@@ -171,6 +168,5 @@
 #endif
 
-		IssmDouble DragCoefficientAbsGradient(void){_error_("not implemented yet");};
-		void       GradientIndexing(int* indexing,int control_index){_error_("not implemented yet");};
+		void       GradientIndexing(int* indexing,int control_index);
 		void       Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){_error_("not implemented yet");};
 		void       GradjBGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
@@ -179,6 +175,6 @@
 		void       GradjDSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
 		void       GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
-		void       GradjDragFS(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
-		void       GradjDragGradient(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
+		void       GradjDragFS(Vector<IssmDouble>* gradient,int control_index);
+		void       GradjDragGradient(Vector<IssmDouble>* gradient,int control_index);
 		void       GradjDhDtBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
 		void       GradjVxBalancedthickness(Vector<IssmDouble>* gradient,int control_index){_error_("not implemented yet");};
@@ -191,15 +187,4 @@
 		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){_error_("not implemented yet");};
 		void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){_error_("not implemented yet");};
-		IssmDouble RheologyBbarAbsGradient(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAbsMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceAbsVelMisfit(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAbsGradient(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAlongGradient(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAcrossGradient(void){_error_("not implemented yet");};
-		IssmDouble BalancethicknessMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceRelVelMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceLogVelMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceLogVxVyMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceAverageVelMisfit(void){_error_("not implemented yet");};
 		void       InputControlUpdate(IssmDouble scalar,bool save_parameter){_error_("not implemented yet");};
 
Index: /issm/trunk/src/c/classes/Elements/SegRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/SegRef.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/SegRef.cpp	(revision 17989)
@@ -20,11 +20,9 @@
 
 /*Object constructors and destructor*/
-/*FUNCTION SegRef::SegRef(){{{*/
-SegRef::SegRef(){
+SegRef::SegRef(){/*{{{*/
 	this->element_type_list=NULL;
 }
 /*}}}*/
-/*FUNCTION SegRef::SegRef(int* types,int nummodels){{{*/
-SegRef::SegRef(const int nummodels){
+SegRef::SegRef(const int nummodels){/*{{{*/
 
 	/*Only allocate pointer*/
@@ -33,6 +31,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::~SegRef(){{{*/
-SegRef::~SegRef(){
+SegRef::~SegRef(){/*{{{*/
 	xDelete<int>(element_type_list);
 }
@@ -40,6 +37,5 @@
 
 /*Management*/
-/*FUNCTION SegRef::SetElementType{{{*/
-void SegRef::SetElementType(int type,int type_counter){
+void SegRef::SetElementType(int type,int type_counter){/*{{{*/
 
 	/*initialize element type*/
@@ -49,33 +45,5 @@
 
 /*Reference Element numerics*/
-/*FUNCTION SegRef::GetBprimeMasstransport{{{*/
-void SegRef::GetBprimeMasstransport(IssmDouble* Bprime, IssmDouble* xyz_list, GaussSeg* gauss){
-	/*Compute B'  matrix. B'=[B1' B2' B3'] where Bi' is of size 3*NDOF2. 
-	 * For node i, Bi' can be expressed in the actual coordinate system
-	 * by: 
-	 *       Bi_prime=[ dN/dx ]
-	 * where N is the finiteelement function for node i.
-	 *
-	 * We assume B' has been allocated already, of size: 3x(NDOF2*numnodes)
-	 */
-
-	/*Fetch number of nodes for this finite element*/
-	int numnodes = this->NumberofNodes();
-
-	/*Get nodal functions derivatives*/
-	IssmDouble* dbasis=xNew<IssmDouble>(2*numnodes);
-	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-
-	/*Build B': */
-	for(int i=0;i<numnodes;i++){
-		Bprime[i] = dbasis[i];
-	}
-
-	/*Clean-up*/
-	xDelete<IssmDouble>(dbasis);
-}
-/*}}}*/
-/*FUNCTION SegRef::GetNodalFunctions(IssmDouble* basis,GaussSeg* gauss){{{*/
-void SegRef::GetNodalFunctions(IssmDouble* basis,GaussSeg* gauss){
+void SegRef::GetNodalFunctions(IssmDouble* basis,GaussSeg* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -85,11 +53,10 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetNodalFunctions(IssmDouble* basis,GaussSeg* gauss,int finiteelement){{{*/
-void SegRef::GetNodalFunctions(IssmDouble* basis,GaussSeg* gauss,int finiteelement){
+void SegRef::GetNodalFunctions(IssmDouble* basis,GaussSeg* gauss,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
 	_assert_(basis);
 
-	switch(element_type){
+	switch(finiteelement){
 		case P0Enum:
 			basis[0]=1.;
@@ -105,10 +72,9 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION SegRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss){{{*/
-void SegRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss){
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
+	}
+}
+/*}}}*/
+void SegRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss){/*{{{*/
 
 	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss,this->element_type);
@@ -116,6 +82,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss,int finiteelement){{{*/
-void SegRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss,int finiteelement){
+void SegRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss,int finiteelement){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -145,6 +110,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss){{{*/
-void SegRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss){
+void SegRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -154,6 +118,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss,int finiteelement){{{*/
-void SegRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss,int finiteelement){
+void SegRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -179,11 +142,10 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION SegRef::GetInputDerivativeValue{{{*/
-void SegRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussSeg* gauss){
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
+	}
+
+}
+/*}}}*/
+void SegRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussSeg* gauss){/*{{{*/
 
 	/*From node values of parameter p (plist[0],plist[1]), return parameter derivative value at gaussian 
@@ -213,12 +175,10 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussSeg* gauss){{{*/
-void SegRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussSeg* gauss){
+void SegRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussSeg* gauss){/*{{{*/
 
 	GetInputValue(p,plist,gauss,this->element_type);
 }
 /*}}}*/
-/*FUNCTION SegRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussSeg* gauss,int finiteelement){{{*/
-void SegRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussSeg* gauss,int finiteelement){
+void SegRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussSeg* gauss,int finiteelement){/*{{{*/
 
 	/*Output*/
@@ -240,6 +200,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetJacobian{{{*/
-void SegRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussSeg* gauss){
+void SegRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussSeg* gauss){/*{{{*/
 	/*The Jacobian is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size 1*/
@@ -251,6 +210,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetJacobianDeterminant{{{*/
-void SegRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussSeg* gauss){
+void SegRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussSeg* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -262,6 +220,5 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::GetJacobianInvert {{{*/
-void SegRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussSeg* gauss){
+void SegRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussSeg* gauss){/*{{{*/
 
 	/*Jacobian*/
@@ -275,12 +232,10 @@
 }
 /*}}}*/
-/*FUNCTION SegRef::NumberofNodes(){{{*/
-int SegRef::NumberofNodes(void){
+int  SegRef::NumberofNodes(void){/*{{{*/
 
 	return this->NumberofNodes(this->element_type);
 }
 /*}}}*/
-/*FUNCTION SegRef::NumberofNodes(int finiteelement){{{*/
-int SegRef::NumberofNodes(int finiteelement){
+int  SegRef::NumberofNodes(int finiteelement){/*{{{*/
 
 	switch(finiteelement){
Index: /issm/trunk/src/c/classes/Elements/SegRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/SegRef.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/SegRef.h	(revision 17989)
@@ -22,5 +22,4 @@
 		/*Management*/
 		void SetElementType(int type,int type_counter);
-		void GetBprimeMasstransport(IssmDouble* Bprime, IssmDouble* xyz_list, GaussSeg* gauss);
 		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussSeg* gauss);
 		void GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussSeg* gauss);
Index: /issm/trunk/src/c/classes/Elements/Tetra.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tetra.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Tetra.cpp	(revision 17989)
@@ -20,6 +20,5 @@
 
 /*Constructors/destructor/copy*/
-/*FUNCTION Tetra::Tetra(int id, int sid,int index, IoModel* iomodel,int nummodels){{{*/
-Tetra::Tetra(int seg_id, int seg_sid, int index, IoModel* iomodel,int nummodels)
+Tetra::Tetra(int seg_id, int seg_sid, int index, IoModel* iomodel,int nummodels)/*{{{*/
 		:TetraRef(nummodels),ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
 
@@ -41,28 +40,22 @@
 		}
 /*}}}*/
-/*FUNCTION Tetra::~Tetra(){{{*/
-Tetra::~Tetra(){
+Tetra::~Tetra(){/*{{{*/
 	this->parameters=NULL;
 }
 /*}}}*/
-/*FUNCTION Tetra::copy {{{*/
-Object* Tetra::copy() {
+Object* Tetra::copy() {/*{{{*/
 	_error_("not implemented yet");
 }
 /*}}}*/
 
-/*FUNCTION Tetra::FiniteElement{{{*/
-int Tetra::FiniteElement(void){
+int      Tetra::FiniteElement(void){/*{{{*/
 	return this->element_type;
 } /*}}}*/
-/*FUNCTION Tetra::ObjectEnum{{{*/
-int Tetra::ObjectEnum(void){
+int      Tetra::ObjectEnum(void){/*{{{*/
 
 	return TetraEnum;
 
 }/*}}}*/
-
-/*FUNCTION Tetra::AddInput{{{*/
-void  Tetra::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){
+void     Tetra::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
 
 	/*Call inputs method*/
@@ -71,6 +64,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::Configure {{{*/
-void  Tetra::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin){
+void     Tetra::Configure(Elements* elementsin, Loads* loadsin, Nodes* nodesin,Vertices* verticesin, Materials* materialsin, Parameters* parametersin){/*{{{*/
 
 	int analysis_counter;
@@ -103,6 +95,31 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::FaceOnBaseIndices{{{*/
-void Tetra::FaceOnBaseIndices(int* pindex1,int* pindex2,int* pindex3){
+void     Tetra::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){/*{{{*/
+
+	IssmDouble xyz_list[NUMVERTICES][3];
+	IssmDouble xmin,ymin,zmin;
+	IssmDouble xmax,ymax,zmax;
+
+	/*Get xyz list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+	xmin=xyz_list[0][0]; xmax=xyz_list[0][0];
+	ymin=xyz_list[0][1]; ymax=xyz_list[0][1];
+	zmin=xyz_list[0][2]; zmax=xyz_list[0][2];
+
+	for(int i=1;i<NUMVERTICES;i++){
+		if(xyz_list[i][0]<xmin) xmin=xyz_list[i][0];
+		if(xyz_list[i][0]>xmax) xmax=xyz_list[i][0];
+		if(xyz_list[i][1]<ymin) ymin=xyz_list[i][1];
+		if(xyz_list[i][1]>ymax) ymax=xyz_list[i][1];
+		if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];
+		if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];
+	}
+
+	*hx=xmax-xmin;
+	*hy=ymax-ymin;
+	*hz=zmax-zmin;
+}
+/*}}}*/
+void     Tetra::FaceOnBaseIndices(int* pindex1,int* pindex2,int* pindex3){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -124,6 +141,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::FaceOnSurfaceIndices{{{*/
-void Tetra::FaceOnSurfaceIndices(int* pindex1,int* pindex2,int* pindex3){
+void     Tetra::FaceOnSurfaceIndices(int* pindex1,int* pindex2,int* pindex3){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -145,6 +161,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::FaceOnFrontIndices{{{*/
-void Tetra::FaceOnFrontIndices(int* pindex1,int* pindex2,int* pindex3){
+void     Tetra::FaceOnFrontIndices(int* pindex1,int* pindex2,int* pindex3){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -166,6 +181,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::GetElementType {{{*/
-int Tetra::GetElementType(){
+int      Tetra::GetElementType(){/*{{{*/
 
 	/*return TetraRef field*/
@@ -173,16 +187,37 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::GetNumberOfNodes;{{{*/
-int Tetra::GetNumberOfNodes(void){
+void     Tetra::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){/*{{{*/
+
+	Input* input=inputs->GetInput(enumtype);
+	if(!input) _error_("No input of type " << EnumToStringx(enumtype) << " found in tria");
+
+	GaussTetra* gauss=new GaussTetra();
+	gauss->GaussVertex(this->GetNodeIndex(node));
+
+	input->GetInputValue(pvalue,gauss);
+	delete gauss;
+}
+/*}}}*/
+int      Tetra::GetNodeIndex(Node* node){/*{{{*/
+
+	_assert_(nodes);
+	int numnodes = this->NumberofNodes();
+
+	for(int i=0;i<numnodes;i++){
+		if(node==nodes[i]) return i;
+	}
+	_error_("Node provided not found among element nodes");
+
+}
+/*}}}*/
+int      Tetra::GetNumberOfNodes(void){/*{{{*/
 	return this->NumberofNodes();
 }
 /*}}}*/
-/*FUNCTION Tetra::GetNumberOfVertices;{{{*/
-int Tetra::GetNumberOfVertices(void){
+int      Tetra::GetNumberOfVertices(void){/*{{{*/
 	return NUMVERTICES;
 }
 /*}}}*/
-/*FUNCTION Tetra::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){{{*/
-void Tetra::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){
+void     Tetra::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){/*{{{*/
 
 	int        indices[3];
@@ -201,6 +236,5 @@
 
 }/*}}}*/
-/*FUNCTION Tetra::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){{{*/
-void Tetra::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){
+void     Tetra::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){/*{{{*/
 
 	int        indices[3];
@@ -219,51 +253,5 @@
 
 }/*}}}*/
-/*FUNCTION Tetra::GetXcoord {{{*/
-IssmDouble Tetra::GetXcoord(Gauss* gauss){
-
-	int    i;
-	IssmDouble z;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble z_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][0];
-	TetraRef::GetInputValue(&z,&z_list[0],(GaussTetra*)gauss,P1Enum);
-
-	return z;
-}
-/*}}}*/
-/*FUNCTION Tetra::GetYcoord {{{*/
-IssmDouble Tetra::GetYcoord(Gauss* gauss){
-
-	int    i;
-	IssmDouble z;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble z_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][1];
-	TetraRef::GetInputValue(&z,&z_list[0],(GaussTetra*)gauss,P1Enum);
-
-	return z;
-}
-/*}}}*/
-/*FUNCTION Tetra::GetZcoord {{{*/
-IssmDouble Tetra::GetZcoord(Gauss* gauss){
-
-	int    i;
-	IssmDouble z;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble z_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2];
-	TetraRef::GetInputValue(&z,&z_list[0],(GaussTetra*)gauss,P1Enum);
-
-	return z;
-}
-/*}}}*/
-/*FUNCTION Tetra::HasFaceOnBase{{{*/
-bool Tetra::HasFaceOnBase(){
+bool     Tetra::HasFaceOnBase(){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -284,6 +272,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::HasFaceOnSurface{{{*/
-bool Tetra::HasFaceOnSurface(){
+bool     Tetra::HasFaceOnSurface(){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -304,6 +291,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::InputUpdateFromIoModel {{{*/
-void Tetra::InputUpdateFromIoModel(int index,IoModel* iomodel){ 
+void     Tetra::InputUpdateFromIoModel(int index,IoModel* iomodel){ /*{{{*/
 
 	/*Intermediaries*/
@@ -408,6 +394,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::InputUpdateFromSolutionOneDof{{{*/
-void  Tetra::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){
+void     Tetra::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){/*{{{*/
 
 	/*Intermediary*/
@@ -435,15 +420,13 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::IsOnBase {{{*/
-bool Tetra::IsOnBase(){
+bool     Tetra::IsOnBase(){/*{{{*/
 	return HasFaceOnBase();
 }
 /*}}}*/
-/*FUNCTION Tetra::IsOnSurface {{{*/
-bool Tetra::IsOnSurface(){
+bool     Tetra::IsOnSurface(){/*{{{*/
 	return HasFaceOnSurface();
 }
 /*}}}*/
-bool Tetra::IsIcefront(void){/*{{{*/
+bool     Tetra::IsIcefront(void){/*{{{*/
 
 	/*Retrieve all inputs and parameters*/
@@ -459,6 +442,5 @@
 	return false;
 }/*}}}*/
-/*FUNCTION Tetra::JacobianDeterminant{{{*/
-void Tetra::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void     Tetra::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTetraEnum);
@@ -467,6 +449,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::JacobianDeterminantSurface{{{*/
-void Tetra::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void     Tetra::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTetraEnum);
@@ -475,6 +456,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::JacobianDeterminantBase{{{*/
-void Tetra::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+void     Tetra::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTetraEnum);
@@ -483,6 +463,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::JacobianDeterminantTop{{{*/
-void Tetra::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+void     Tetra::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTetraEnum);
@@ -491,16 +470,13 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NewGauss(){{{*/
-Gauss* Tetra::NewGauss(void){
+Gauss*   Tetra::NewGauss(void){/*{{{*/
 	return new GaussTetra();
 }
 /*}}}*/
-/*FUNCTION Tetra::NewGauss(int order){{{*/
-Gauss* Tetra::NewGauss(int order){
+Gauss*   Tetra::NewGauss(int order){/*{{{*/
 	return new GaussTetra(order);
 }
 /*}}}*/
-/*FUNCTION Tetra::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){{{*/
-Gauss* Tetra::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){
+Gauss*   Tetra::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){/*{{{*/
 	/*FIXME: this is messed up, should provide indices and not xyz_list!*/
 	int indices[3];
@@ -509,6 +485,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NewGaussBase(int order){{{*/
-Gauss* Tetra::NewGaussBase(int order){
+Gauss*   Tetra::NewGaussBase(int order){/*{{{*/
 
 	int indices[3];
@@ -517,6 +492,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NewGaussTop(int order){{{*/
-Gauss* Tetra::NewGaussTop(int order){
+Gauss*   Tetra::NewGaussTop(int order){/*{{{*/
 
 	int indices[3];
@@ -525,6 +499,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NodalFunctions{{{*/
-void Tetra::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+void     Tetra::NodalFunctions(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTetraEnum);
@@ -533,30 +506,26 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NodalFunctionsVelocity{{{*/
-void Tetra::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){
-
-	_assert_(gauss->Enum()==GaussTetraEnum);
-	this->GetNodalFunctionsVelocity(basis,(GaussTetra*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tetra::NodalFunctionsPressure{{{*/
-void Tetra::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){
-
-	_assert_(gauss->Enum()==GaussTetraEnum);
-	this->GetNodalFunctionsPressure(basis,(GaussTetra*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tetra::NodalFunctionsTensor{{{*/
-void Tetra::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){
-
-	_assert_(gauss->Enum()==GaussTetraEnum);
-	this->GetNodalFunctionsTensor(basis,(GaussTetra*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tetra::NodalFunctionsDerivatives{{{*/
-void Tetra::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void     Tetra::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){/*{{{*/
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctions(basis,(GaussTetra*)gauss,this->VelocityInterpolation());
+
+}
+/*}}}*/
+void     Tetra::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){/*{{{*/
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctions(basis,(GaussTetra*)gauss,this->PressureInterpolation());
+
+}
+/*}}}*/
+void     Tetra::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){/*{{{*/
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctions(basis,(GaussTetra*)gauss,this->TensorInterpolation());
+
+}
+/*}}}*/
+void     Tetra::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTetraEnum);
@@ -565,14 +534,12 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NodalFunctionsDerivativesVelocity{{{*/
-void Tetra::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
-
-	_assert_(gauss->Enum()==GaussTetraEnum);
-	this->GetNodalFunctionsDerivativesVelocity(dbasis,xyz_list,(GaussTetra*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tetra::NormalSection{{{*/
-void Tetra::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){
+void     Tetra::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussTetra*)gauss,this->VelocityInterpolation());
+
+}
+/*}}}*/
+void     Tetra::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){/*{{{*/
 
 	/*Build unit outward pointing vector*/
@@ -594,6 +561,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::NormalBase (THIS ONE){{{*/
-void Tetra::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){
+void     Tetra::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){/*{{{*/
 
 	IssmDouble v13[3],v23[3];
@@ -615,8 +581,9 @@
 	bed_normal[1]=-normal[1]/normal_norm;
 	bed_normal[2]=-normal[2]/normal_norm;
-}
-/*}}}*/
-/*FUNCTION Tetra::NormalTop (THIS ONE){{{*/
-void Tetra::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){
+
+	_assert_(bed_normal[2]<0.);
+}
+/*}}}*/
+void     Tetra::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){/*{{{*/
 
 	IssmDouble v13[3],v23[3];
@@ -637,18 +604,16 @@
 	top_normal[1]=normal[1]/normal_norm;
 	top_normal[2]=normal[2]/normal_norm;
-}
-/*}}}*/
-/*FUNCTION Tetra::NumberofNodesPressure{{{*/
-int Tetra::NumberofNodesPressure(void){
-	return TetraRef::NumberofNodesPressure();
-}
-/*}}}*/
-/*FUNCTION Tetra::NumberofNodesVelocity{{{*/
-int Tetra::NumberofNodesVelocity(void){
-	return TetraRef::NumberofNodesVelocity();
-}
-/*}}}*/
-/*FUNCTION Tetra::ReduceMatrices{{{*/
-void Tetra::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){
+	_assert_(top_normal[2]>0.);
+}
+/*}}}*/
+int      Tetra::NumberofNodesPressure(void){/*{{{*/
+	return TetraRef::NumberofNodes(this->PressureInterpolation());
+}
+/*}}}*/
+int      Tetra::NumberofNodesVelocity(void){/*{{{*/
+	return TetraRef::NumberofNodes(this->VelocityInterpolation());
+}
+/*}}}*/
+void     Tetra::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){/*{{{*/
 
 	if(pe){
@@ -685,6 +650,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::ResetFSBasalBoundaryCondition {{{*/
-void  Tetra::ResetFSBasalBoundaryCondition(void){
+void     Tetra::ResetFSBasalBoundaryCondition(void){/*{{{*/
 
 	int numnodes = this->GetNumberOfNodes();
@@ -745,6 +709,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::SetCurrentConfiguration {{{*/
-void  Tetra::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
+void     Tetra::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){/*{{{*/
 
 	/*go into parameters and get the analysis_counter: */
@@ -761,6 +724,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::SpawnBasalElement{{{*/
-Element*  Tetra::SpawnBasalElement(void){
+Element* Tetra::SpawnBasalElement(void){/*{{{*/
 
 	_assert_(HasFaceOnBase());
@@ -770,6 +732,5 @@
 	return SpawnTria(index1,index2,index3);
 }/*}}}*/
-/*FUNCTION Tetra::SpawnTopElement{{{*/
-Element*  Tetra::SpawnTopElement(void){
+Element* Tetra::SpawnTopElement(void){/*{{{*/
 
 	_assert_(HasFaceOnSurface());
@@ -779,6 +740,5 @@
 	return SpawnTria(index1,index2,index3);
 }/*}}}*/
-/*FUNCTION Tetra::SpawnTria{{{*/
-Tria*  Tetra::SpawnTria(int index1,int index2,int index3){
+Tria*    Tetra::SpawnTria(int index1,int index2,int index3){/*{{{*/
 
 	int analysis_counter;
@@ -807,6 +767,5 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::Update {{{*/
-void Tetra::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){ 
+void     Tetra::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){ /*{{{*/
 
 	/*Intermediaries*/
@@ -912,16 +871,33 @@
 }
 /*}}}*/
-/*FUNCTION Tetra::VelocityInterpolation{{{*/
-int Tetra::VelocityInterpolation(void){
+int      Tetra::VelocityInterpolation(void){/*{{{*/
 	return TetraRef::VelocityInterpolation();
 }
 /*}}}*/
-/*FUNCTION Tetra::PressureInterpolation{{{*/
-int Tetra::PressureInterpolation(void){
+void     Tetra::ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/
+
+	/*Intermediaries*/
+	IssmDouble phi;
+	IssmDouble viscosity;
+	IssmDouble epsilon[6];
+
+	_assert_(gauss->Enum()==GaussTetraEnum);
+	this->StrainRateFS(&epsilon[0],xyz_list,(GaussTetra*)gauss,vx_input,vy_input,vz_input);
+	this->ViscosityFS(&viscosity,3,xyz_list,(GaussTetra*)gauss,vx_input,vy_input,vz_input);
+	GetPhi(&phi,&epsilon[0],viscosity);
+
+	/*Assign output pointer*/
+	*pphi = phi;
+}
+/*}}}*/
+int      Tetra::PressureInterpolation(void){/*{{{*/
 	return TetraRef::PressureInterpolation();
 }
 /*}}}*/
-/*FUNCTION Tetra::ZeroLevelsetCoordinates{{{*/
-void Tetra::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){
+int      Tetra::TensorInterpolation(void){/*{{{*/
+	return TetraRef::TensorInterpolation();
+}
+/*}}}*/
+void     Tetra::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
 	/*Compute portion of the element that is grounded*/ 
 
Index: /issm/trunk/src/c/classes/Elements/Tetra.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tetra.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Tetra.h	(revision 17989)
@@ -55,4 +55,5 @@
 		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b){_error_("not implemented yet");};
 		void        ComputeSigmaNN(){_error_("not implemented yet");};
+		void        ComputeStrainRate(){_error_("not implemented yet");};
 		void        ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
 		void        ComputeStressTensor(){_error_("not implemented yet");};
@@ -61,5 +62,5 @@
 		void        SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters);
 		void        Delta18oParameterization(void){_error_("not implemented yet");};
-		void        ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){_error_("not implemented yet");};
+		void        ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz);
 		void        FaceOnFrontIndices(int* pindex1,int* pindex2,int* pindex3);
 		void        FaceOnBaseIndices(int* pindex1,int* pindex2,int* pindex3);
@@ -68,8 +69,6 @@
 		int         FiniteElement(void);
 		Element*    GetUpperElement(void){_error_("not implemented yet");};
-	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
-	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
 		Element*    GetBasalElement(void){_error_("not implemented yet");};
-		int         GetNodeIndex(Node* node){_error_("not implemented yet");};
+		int         GetNodeIndex(Node* node);
 		int         GetNumberOfNodes(void);
 		int         GetNumberOfVertices(void);
@@ -109,11 +108,9 @@
 		void        ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){_error_("not implemented yet");};
 		int         VelocityInterpolation(void);
+		int         TensorInterpolation(void);
 		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating){_error_("not implemented yet");};
 		IssmDouble  GetGroundedPortion(IssmDouble* xyz_list){_error_("not implemented yet");};
-		void        GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){_error_("not implemented yet");};
+		void        GetInputValue(IssmDouble* pvalue,Node* node,int enumtype);
 		Node*       GetNode(int node_number){_error_("Not implemented");};
-		IssmDouble  GetXcoord(Gauss* gauss);
-		IssmDouble  GetYcoord(Gauss* gauss);
-		IssmDouble  GetZcoord(Gauss* gauss);
 		int         GetElementType(void);
 		Gauss*      NewGauss(void);
@@ -127,14 +124,13 @@
 		int         VertexConnectivity(int vertexindex){_error_("not implemented yet");};
 		void        VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");};
-		void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){_error_("not implemented yet");};
+		void        ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
 		bool        IsZeroLevelset(int levelset_enum){_error_("not implemented");};
 		bool		   IsIcefront(void);
+		bool   IsFaceOnBoundary(void){_error_("not implemented yet");};
 		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
 		void		   GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented yet");};
-		void        GetNormalFromLSF(IssmDouble *pnormal){_error_("not implemented yet");};
-
 		void        GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution,int enum_type){_error_("not implemented yet");};
 		void        InputDepthAverageAtBase(int enum_type,int average_enum_type){_error_("not implemented yet");};
-		void        InputDuplicate(int original_enum,int new_enum){_error_("not implemented yet");};
+		void        InputExtrude(int enum_type){_error_("not implemented"); /*For penta only*/};
 		void        InputScale(int enum_type,IssmDouble scale_factor){_error_("not implemented yet");};
 		void        MaterialUpdateFromTemperature(void){_error_("not implemented yet");};
@@ -196,15 +192,4 @@
 		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){_error_("not implemented yet");};
 		void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){_error_("not implemented yet");};
-		IssmDouble RheologyBbarAbsGradient(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAbsMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceAbsVelMisfit(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAbsGradient(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAlongGradient(void){_error_("not implemented yet");};
-		IssmDouble ThicknessAcrossGradient(void){_error_("not implemented yet");};
-		IssmDouble BalancethicknessMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceRelVelMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceLogVelMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceLogVxVyMisfit(void){_error_("not implemented yet");};
-		IssmDouble SurfaceAverageVelMisfit(void){_error_("not implemented yet");};
 		void       InputControlUpdate(IssmDouble scalar,bool save_parameter){_error_("not implemented yet");};
 
Index: /issm/trunk/src/c/classes/Elements/TetraRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/TetraRef.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/TetraRef.cpp	(revision 17989)
@@ -4,5 +4,5 @@
 
 /*Headers:*/
-/*{{{*/
+/*{{{*//*{{{*/
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -22,11 +22,9 @@
 
 /*Object constructors and destructor*/
-/*FUNCTION TetraRef::TetraRef(){{{*/
-TetraRef::TetraRef(){
+TetraRef::TetraRef(){/*{{{*/
 	this->element_type_list=NULL;
 }
 /*}}}*/
-/*FUNCTION TetraRef::TetraRef(int* types,int nummodels){{{*/
-TetraRef::TetraRef(const int nummodels){
+TetraRef::TetraRef(const int nummodels){/*{{{*/
 
 	/*Only allocate pointer*/
@@ -35,6 +33,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::~TetraRef(){{{*/
-TetraRef::~TetraRef(){
+TetraRef::~TetraRef(){/*{{{*/
 	xDelete<int>(element_type_list);
 }
@@ -42,6 +39,5 @@
 
 /*Management*/
-/*FUNCTION TetraRef::SetElementType{{{*/
-void TetraRef::SetElementType(int type,int type_counter){
+void TetraRef::SetElementType(int type,int type_counter){/*{{{*/
 
 	/*initialize element type*/
@@ -51,6 +47,5 @@
 
 /*Reference Element numerics*/
-/*FUNCTION TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss){{{*/
-void TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss){
+void TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 	_assert_(basis);
@@ -58,6 +53,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement){{{*/
-void TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement){
+void TetraRef::GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -98,100 +92,13 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsVelocity{{{*/
-void TetraRef::GetNodalFunctionsVelocity(IssmDouble* basis,GaussTetra* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsPressure{{{*/
-void TetraRef::GetNodalFunctionsPressure(IssmDouble* basis,GaussTetra* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsTensor{{{*/
-void TetraRef::GetNodalFunctionsTensor(IssmDouble* basis,GaussTetra* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	switch(this->element_type){
-		case XTaylorHoodEnum:
-			this->element_type = P1DGEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = XTaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){{{*/
-void TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
+	}
+}
+/*}}}*/
+void TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){/*{{{*/
 	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss,this->element_type);
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement){{{*/
-void TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement){
+void TetraRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -226,72 +133,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsDerivativesPressure         (THIS ONE and following ones){{{*/
-void TetraRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsDerivativesVelocity{{{*/
-void TetraRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss){
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss){{{*/
-void TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss){
+void TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -301,6 +141,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement){{{*/
-void TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement){
+void TetraRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -395,11 +234,10 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION TetraRef::GetInputDerivativeValue{{{*/
-void TetraRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussTetra* gauss){
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
+	}
+
+}
+/*}}}*/
+void TetraRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, GaussTetra* gauss){/*{{{*/
 	/*From node values of parameter p (p_list[0], p_list[1], p_list[2],
 	 * p_list[3], p_list[4] and p_list[4]), return parameter derivative value at
@@ -436,12 +274,10 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss){{{*/
-void TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss){
+void TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss){/*{{{*/
 
 	GetInputValue(p,plist,gauss,this->element_type);
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss,int finiteelement){{{*/
-void TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss,int finiteelement){
+void TetraRef::GetInputValue(IssmDouble* p, IssmDouble* plist, GaussTetra* gauss,int finiteelement){/*{{{*/
 
 	/*Output*/
@@ -463,6 +299,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetJacobian{{{*/
-void TetraRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTetra* gauss){
+void TetraRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTetra* gauss){/*{{{*/
 	/*The Jacobian is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size 1*/
@@ -496,6 +331,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetJacobianDeterminant{{{*/
-void TetraRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss){
+void TetraRef::GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -511,6 +345,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetJacobianDeterminantFace{{{*/
-void TetraRef::GetJacobianDeterminantFace(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss){
+void TetraRef::GetJacobianDeterminantFace(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -531,6 +364,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::GetJacobianInvert {{{*/
-void TetraRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussTetra* gauss){
+void TetraRef::GetJacobianInvert(IssmDouble* Jinv, IssmDouble* xyz_list,GaussTetra* gauss){/*{{{*/
 
 	/*Jacobian*/
@@ -544,12 +376,10 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::NumberofNodes(){{{*/
-int TetraRef::NumberofNodes(void){
+int  TetraRef::NumberofNodes(void){/*{{{*/
 
 	return this->NumberofNodes(this->element_type);
 }
 /*}}}*/
-/*FUNCTION TetraRef::NumberofNodes(int finiteelement){{{*/
-int TetraRef::NumberofNodes(int finiteelement){
+int  TetraRef::NumberofNodes(int finiteelement){/*{{{*/
 
 	switch(finiteelement){
@@ -571,36 +401,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::NumberofNodesPressure{{{*/
-int TetraRef::NumberofNodesPressure(void){
-
-	switch(this->element_type){
-		case P1P1Enum:          return NUMNODESP1;
-		case P1P1GLSEnum:       return NUMNODESP1;
-		case MINIcondensedEnum: return NUMNODESP1;
-		case MINIEnum:          return NUMNODESP1;
-		case TaylorHoodEnum:    return NUMNODESP1;
-		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-	return -1;
-}
-/*}}}*/
-/*FUNCTION TetraRef::NumberofNodesVelocity{{{*/
-int TetraRef::NumberofNodesVelocity(void){
-
-	switch(this->element_type){
-		case P1P1Enum:          return NUMNODESP1;
-		case P1P1GLSEnum:       return NUMNODESP1;
-		case MINIcondensedEnum: return NUMNODESP1b;
-		case MINIEnum:          return NUMNODESP1b;
-		case TaylorHoodEnum:    return NUMNODESP2;
-		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-	return -1;
-}
-/*}}}*/
-/*FUNCTION TetraRef::VelocityInterpolation{{{*/
-int TetraRef::VelocityInterpolation(void){
+int  TetraRef::VelocityInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -616,6 +415,5 @@
 }
 /*}}}*/
-/*FUNCTION TetraRef::PressureInterpolation{{{*/
-int TetraRef::PressureInterpolation(void){
+int TetraRef::PressureInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -629,4 +427,12 @@
 
 	return -1;
-}
-/*}}}*/
+}/*}}}*/
+int  TetraRef::TensorInterpolation(void){/*{{{*/
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	switch(this->element_type){
+		case XTaylorHoodEnum: return P1DGEnum;
+		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
Index: /issm/trunk/src/c/classes/Elements/TetraRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/TetraRef.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/TetraRef.h	(revision 17989)
@@ -22,5 +22,4 @@
 		/*Management*/
 		void SetElementType(int type,int type_counter);
-		void GetBprimeMasstransport(IssmDouble* Bprime, IssmDouble* xyz_list, GaussTetra* gauss);
 		void GetJacobian(IssmDouble* J, IssmDouble* xyz_list,GaussTetra* gauss);
 		void GetJacobianDeterminant(IssmDouble*  Jdet, IssmDouble* xyz_list,GaussTetra* gauss);
@@ -29,11 +28,6 @@
 		void GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss);
 		void GetNodalFunctions(IssmDouble* basis,GaussTetra* gauss,int finiteelement);
-		void GetNodalFunctionsVelocity(IssmDouble* basis, GaussTetra* gauss);
-		void GetNodalFunctionsPressure(IssmDouble* basis, GaussTetra* gauss);
-		void GetNodalFunctionsTensor(IssmDouble* basis, GaussTetra* gauss);
 		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss);
 		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement);
-		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,GaussTetra* gauss);
-		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,GaussTetra* gauss);
 		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss);
 		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement);
@@ -44,8 +38,7 @@
 		int  NumberofNodes(void);
 		int  NumberofNodes(int finiteelement);
-		int  NumberofNodesVelocity(void);
-		int  NumberofNodesPressure(void);
 		int  VelocityInterpolation(void);
 		int  PressureInterpolation(void);
+		int  TensorInterpolation(void);
 };
 #endif
Index: /issm/trunk/src/c/classes/Elements/Tria.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tria.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Tria.cpp	(revision 17989)
@@ -24,6 +24,5 @@
 
 /*Constructors/destructor/copy*/
-/*FUNCTION Tria::Tria(int id, int sid,int index, IoModel* iomodel,int nummodels){{{*/
-Tria::Tria(int tria_id, int tria_sid, int index, IoModel* iomodel,int nummodels)
+Tria::Tria(int tria_id, int tria_sid, int index, IoModel* iomodel,int nummodels)/*{{{*/
 	:TriaRef(nummodels),ElementHook(nummodels,index+1,NUMVERTICES,iomodel){
 
@@ -45,11 +44,9 @@
 }
 /*}}}*/
-/*FUNCTION Tria::~Tria(){{{*/
-Tria::~Tria(){
+Tria::~Tria(){/*{{{*/
 	this->parameters=NULL;
 }
 /*}}}*/
-/*FUNCTION Tria::copy {{{*/
-Object* Tria::copy() {
+Object* Tria::copy() {/*{{{*/
 
 	int i;
@@ -95,6 +92,5 @@
 
 /*Other*/
-/*FUNCTION Tria::AddBasalInput{{{*/
-void  Tria::AddBasalInput(int input_enum,IssmDouble* values, int interpolation_enum){
+void       Tria::AddBasalInput(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
 
 	/*Call inputs method*/
@@ -128,6 +124,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::AddInput{{{*/
-void  Tria::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){
+void       Tria::AddInput(int input_enum,IssmDouble* values, int interpolation_enum){/*{{{*/
 
 	/*Call inputs method*/
@@ -136,19 +131,16 @@
 }
 /*}}}*/
-/*FUNCTION Tria::CharacteristicLength{{{*/
-IssmDouble Tria::CharacteristicLength(void){
+IssmDouble Tria::CharacteristicLength(void){/*{{{*/
 
 	return sqrt(2*this->GetArea());
 }
 /*}}}*/
-/*FUNCTION Tria::ComputeBasalStress {{{*/
-void  Tria::ComputeBasalStress(Vector<IssmDouble>* eps){
+void       Tria::ComputeBasalStress(Vector<IssmDouble>* eps){/*{{{*/
 	_error_("Not Implemented yet");
 }
 /*}}}*/
-/*FUNCTION Tria::ComputeSigmaNN {{{*/
-void  Tria::ComputeSigmaNN(){
-
-	if(~IsOnBase()){
+void       Tria::ComputeSigmaNN(){/*{{{*/
+
+	if(!IsOnBase()){
 		IssmDouble sigma_nn=0;
 		this->inputs->AddInput(new TriaInput(SigmaNNEnum,&sigma_nn,P0Enum));
@@ -157,4 +149,5 @@
 	else{
 		IssmDouble* xyz_list=NULL;
+		IssmDouble *xyz_list_base=NULL;
 		IssmDouble  pressure,viscosity,sigma_nn;
 		IssmDouble  sigma_xx,sigma_xy,sigma_yy;
@@ -165,4 +158,5 @@
 		/* Get node coordinates and dof list: */
 		GetVerticesCoordinates(&xyz_list);
+	   GetVerticesCoordinatesBase(&xyz_list_base);
 
 		/*Retrieve all inputs we will be needing: */
@@ -188,8 +182,8 @@
 
 		/*Get normal vector to the bed */
-		NormalBase(&base_normal[0],xyz_list);
+		NormalBase(&base_normal[0],xyz_list_base);
 
 		/*Compute sigma_nn*/
-		sigma_nn=sigma_xx*base_normal[0]*base_normal[0] + sigma_xy*base_normal[0]*base_normal[1] + sigma_yy*base_normal[1]*base_normal[1];
+		sigma_nn=sigma_xx*base_normal[0]*base_normal[0] + 2*sigma_xy*base_normal[0]*base_normal[1] + sigma_yy*base_normal[1]*base_normal[1];
 
 		/*Add Stress tensor components into inputs*/
@@ -198,15 +192,55 @@
 		/*Clean up and return*/
 		xDelete<IssmDouble>(xyz_list);
+		xDelete<IssmDouble>(xyz_list_base);
 		delete gauss;
 	}
 }
 /*}}}*/
-/*FUNCTION Tria::ComputeStrainRate {{{*/
-void  Tria::ComputeStrainRate(Vector<IssmDouble>* eps){
-	_error_("Not Implemented yet");
-}
-/*}}}*/
-/*FUNCTION Tria::ComputeStressTensor {{{*/
-void  Tria::ComputeStressTensor(){
+void       Tria::ComputeStrainRate(){/*{{{*/
+
+	IssmDouble      xyz_list[NUMVERTICES][3];
+	IssmDouble      epsilon[6]; /* epsilon=[exx,eyy,exy];*/
+	IssmDouble      eps_xx[NUMVERTICES];
+	IssmDouble		 eps_yy[NUMVERTICES];
+	IssmDouble		 eps_zz[NUMVERTICES]={0,0,0};
+	IssmDouble      eps_xy[NUMVERTICES];
+	IssmDouble		 eps_xz[NUMVERTICES]={0,0,0};
+	IssmDouble		 eps_yz[NUMVERTICES]={0,0,0};
+	GaussTria*     gauss=NULL;
+
+	/* Get node coordinates and dof list: */
+	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* vx_input=inputs->GetInput(VxEnum);             _assert_(vx_input);
+	Input* vy_input=inputs->GetInput(VyEnum);             _assert_(vy_input);
+
+	/* Start looping on the number of vertices: */
+	gauss=new GaussTria();
+	for (int iv=0;iv<NUMVERTICES;iv++){
+		gauss->GaussVertex(iv);
+
+		/*Compute strain rate viscosity and pressure: */
+		this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
+
+		eps_xx[iv]=epsilon[0]; 
+		eps_yy[iv]=epsilon[1];
+		eps_xy[iv]=epsilon[2];
+	}
+
+	/*Add Stress tensor components into inputs*/
+	this->inputs->AddInput(new TriaInput(StrainRatexxEnum,&eps_xx[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(StrainRatexyEnum,&eps_xy[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(StrainRatexzEnum,&eps_xz[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(StrainRateyyEnum,&eps_yy[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(StrainRateyzEnum,&eps_yz[0],P1Enum));
+	this->inputs->AddInput(new TriaInput(StrainRatezzEnum,&eps_zz[0],P1Enum));
+
+	/*Clean up and return*/
+	delete gauss;
+
+}
+/*}}}*/
+void       Tria::ComputeStressTensor(){/*{{{*/
 
 	IssmDouble  xyz_list[NUMVERTICES][3];
@@ -260,6 +294,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ComputeDeviatoricStressTensor {{{*/
-void  Tria::ComputeDeviatoricStressTensor(){
+void       Tria::ComputeDeviatoricStressTensor(){/*{{{*/
 
 	IssmDouble  xyz_list[NUMVERTICES][3];
@@ -311,6 +344,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::Configure {{{*/
-void  Tria::Configure(Elements* elementsin, Loads* loadsin,Nodes* nodesin,Vertices *verticesin,Materials* materialsin, Parameters* parametersin){
+void       Tria::Configure(Elements* elementsin, Loads* loadsin,Nodes* nodesin,Vertices *verticesin,Materials* materialsin, Parameters* parametersin){/*{{{*/
 
 	/*go into parameters and get the analysis_counter: */
@@ -343,6 +375,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::Delta18oParameterization{{{*/
-void  Tria::Delta18oParameterization(void){
+void       Tria::Delta18oParameterization(void){/*{{{*/
 
 	int        i;
@@ -414,6 +445,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ElementSizes{{{*/
-void Tria::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){
+void       Tria::ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){/*{{{*/
 
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -438,11 +468,9 @@
 }
 /*}}}*/
-/*FUNCTION Tria::FiniteElement{{{*/
-int Tria::FiniteElement(void){
+int        Tria::FiniteElement(void){/*{{{*/
 	return this->element_type;
 }
 /*}}}*/
-/*FUNCTION Tria::ObjectEnum{{{*/
-int Tria::ObjectEnum(void){
+int        Tria::ObjectEnum(void){/*{{{*/
 
 	return TriaEnum;
@@ -450,6 +478,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetArea {{{*/
-IssmDouble Tria::GetArea(void){
+IssmDouble Tria::GetArea(void){/*{{{*/
 
 	IssmDouble xyz_list[NUMVERTICES][3];
@@ -466,6 +493,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetAreaCoordinates{{{*/
-void Tria::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){
+void       Tria::GetAreaCoordinates(IssmDouble* area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints){/*{{{*/
 	/*Computeportion of the element that is grounded*/ 
 
@@ -502,6 +528,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetElementType {{{*/
-int Tria::GetElementType(){
+int        Tria::GetElementType(){/*{{{*/
 
 	/*return TriaRef field*/
@@ -510,6 +535,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetGroundedPart{{{*/
-void Tria::GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating){
+void       Tria::GetGroundedPart(int* point1,IssmDouble* fraction1,IssmDouble* fraction2, bool* mainlyfloating){/*{{{*/
 	/*Computeportion of the element that is grounded*/ 
 
@@ -564,6 +588,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetGroundedPortion{{{*/
-IssmDouble Tria::GetGroundedPortion(IssmDouble* xyz_list){
+IssmDouble Tria::GetGroundedPortion(IssmDouble* xyz_list){/*{{{*/
 	/*Computeportion of the element that is grounded*/ 
 
@@ -683,6 +706,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){{{*/
-void Tria::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){
+void       Tria::GetVerticesCoordinatesBase(IssmDouble** pxyz_list){/*{{{*/
 
 	int        indices[2];
@@ -701,6 +723,5 @@
 
 }/*}}}*/
-/*FUNCTION Tria::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){{{*/
-void Tria::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){
+void       Tria::GetVerticesCoordinatesTop(IssmDouble** pxyz_list){/*{{{*/
 
 	int        indices[2];
@@ -719,6 +740,5 @@
 
 }/*}}}*/
-/*FUNCTION Tria::NormalSection{{{*/
-void Tria::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){
+void       Tria::NormalSection(IssmDouble* normal,IssmDouble* xyz_list){/*{{{*/
 
 	/*Build unit outward pointing vector*/
@@ -735,6 +755,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ZeroLevelsetCoordinates{{{*/
-void Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){
+void       Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
 
 	int         normal_orientation=0;
@@ -830,5 +849,5 @@
 }
 /*}}}*/
-void  Tria::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
+void       Tria::GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum){/*{{{*/
 	
 	/* Intermediaries */
@@ -870,38 +889,5 @@
 	xDelete<int>(indicesfront);
 }/*}}}*/
-void  Tria::GetNormalFromLSF(IssmDouble *pnormal){/*{{{*/
-
-	/* Intermediaries */
-	int         i;
-	const int   dim=2;
-	IssmDouble* xyz_list = NULL;
-	IssmDouble  dlevelset[dim], norm_dlevelset;
-	IssmDouble  normal[dim]={0.};
-
-	/*Retrieve all inputs and parameters*/
-	Input* levelset_input=this->GetInput(MaskIceLevelsetEnum); _assert_(levelset_input);
-	this->GetVerticesCoordinates(&xyz_list);
-	
-	IssmDouble counter=0.;
-	Gauss* gauss = this->NewGauss(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-		/* Get normal on node */
-		levelset_input->GetInputDerivativeValue(&dlevelset[0],xyz_list,gauss);
-		norm_dlevelset=0.;
-		for(i=0;i<dim;i++) norm_dlevelset+=dlevelset[i]*dlevelset[i]; 
-		norm_dlevelset=sqrt(norm_dlevelset)+1.e-14;
-		for(i=0;i<dim;i++) normal[i]+=dlevelset[i]/norm_dlevelset;
-		counter++;
-	}
-	_assert_(counter>0.);
-	for(i=0;i<dim;i++) normal[i] = normal[i]/counter;
-	
-	pnormal=&normal[0];
-
-	delete gauss;
-	xDelete<IssmDouble>(xyz_list);
-}/*}}}*/
-/*FUNCTION Tria::GetNodeIndex {{{*/
-int Tria::GetNodeIndex(Node* node){
+int        Tria::GetNodeIndex(Node* node){/*{{{*/
 
 	_assert_(nodes);
@@ -913,16 +899,13 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GetNumberOfNodes;{{{*/
-int Tria::GetNumberOfNodes(void){
+int        Tria::GetNumberOfNodes(void){/*{{{*/
 	return this->NumberofNodes();
 }
 /*}}}*/
-/*FUNCTION Tria::GetNumberOfVertices;{{{*/
-int Tria::GetNumberOfVertices(void){
+int        Tria::GetNumberOfVertices(void){/*{{{*/
 	return NUMVERTICES;
 }
 /*}}}*/
-/*FUNCTION Tria::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype) {{{*/
-void Tria::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){
+void       Tria::GetInputValue(IssmDouble* pvalue,Node* node,int enumtype){/*{{{*/
 
 	Input* input=inputs->GetInput(enumtype);
@@ -936,5 +919,5 @@
 }
 /*}}}*/
-Node* Tria::GetNode(int node_number){/*{{{*/
+Node*      Tria::GetNode(int node_number){/*{{{*/
 	_assert_(node_number>=0); 
 	_assert_(node_number<this->NumberofNodes()); 
@@ -942,34 +925,5 @@
 
 }/*}}}*/
-/*FUNCTION Tria::GetXcoord {{{*/
-IssmDouble Tria::GetXcoord(Gauss* gauss){
-
-	IssmDouble x;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble x_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(int i=0;i<NUMVERTICES;i++) x_list[i]=xyz_list[i][0];
-	TriaRef::GetInputValue(&x,x_list,gauss,P1Enum);
-
-	return x;
-}
-/*}}}*/
-/*FUNCTION Tria::GetYcoord {{{*/
-IssmDouble Tria::GetYcoord(Gauss* gauss){
-
-	IssmDouble y;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble y_list[NUMVERTICES];
-
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	for(int i=0;i<NUMVERTICES;i++) y_list[i]=xyz_list[i][1];
-	TriaRef::GetInputValue(&y,y_list,gauss,P1Enum);
-
-	return y;
-}
-/*}}}*/
-/*FUNCTION Tria::InputDepthAverageAtBase {{{*/
-void  Tria::InputDepthAverageAtBase(int enum_type,int average_enum_type){
+void       Tria::InputDepthAverageAtBase(int enum_type,int average_enum_type){/*{{{*/
 
 	/*New input*/
@@ -989,15 +943,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputDuplicate{{{*/
-void  Tria::InputDuplicate(int original_enum,int new_enum){
-
-	/*Call inputs method*/
-	if (IsInput(original_enum)) {
-		inputs->DuplicateInput(original_enum,new_enum);
-	}
-}
-/*}}}*/
-/*FUNCTION Tria::InputScale{{{*/
-void  Tria::InputScale(int enum_type,IssmDouble scale_factor){
+void       Tria::InputScale(int enum_type,IssmDouble scale_factor){/*{{{*/
 
 	Input* input=NULL;
@@ -1011,6 +955,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputUpdateFromIoModel{{{*/
-void Tria::InputUpdateFromIoModel(int index, IoModel* iomodel){ //i is the element index
+void       Tria::InputUpdateFromIoModel(int index, IoModel* iomodel){ //i is the element index/*{{{*/
 
 	/*Intermediaries*/
@@ -1044,50 +987,37 @@
 	if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
 		for(i=0;i<num_control_type;i++){
-			switch(reCast<int>(iomodel->Data(InversionControlParametersEnum)[i])){
+			int control = reCast<int>(iomodel->Data(InversionControlParametersEnum)[i]);
+			switch(control){
+				/*yts conversion*/
 				case BalancethicknessThickeningRateEnum:
-					if (iomodel->Data(BalancethicknessThickeningRateEnum)){
-						for(j=0;j<3;j++)nodeinputs[j]=iomodel->Data(BalancethicknessThickeningRateEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
-						this->inputs->AddInput(new ControlInput(BalancethicknessThickeningRateEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+				case VxEnum:
+				case VyEnum:
+					if(iomodel->Data(control)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(control)[tria_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
+						this->inputs->AddInput(new ControlInput(control,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
-				case VxEnum:
-					if (iomodel->Data(VxEnum)){
-						for(j=0;j<3;j++)nodeinputs[j]=iomodel->Data(VxEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
-						this->inputs->AddInput(new ControlInput(VxEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
+
+				/*No yts conversion*/
+				case ThicknessEnum:
+				case FrictionCoefficientEnum:
+				case BalancethicknessNuxEnum:
+				case BalancethicknessNuyEnum:
+					if(iomodel->Data(control)){
+						for(j=0;j<NUMVERTICES;j++)nodeinputs[j]=iomodel->Data(control)[tria_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						this->inputs->AddInput(new ControlInput(control,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
-				case VyEnum:
-					if (iomodel->Data(VyEnum)){
-						for(j=0;j<3;j++)nodeinputs[j]=iomodel->Data(VyEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i]/yts;
-						this->inputs->AddInput(new ControlInput(VyEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-					}
-					break;
-				case ThicknessEnum:
-					if (iomodel->Data(ThicknessEnum)){
-						for(j=0;j<3;j++)nodeinputs[j]=iomodel->Data(ThicknessEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
-						this->inputs->AddInput(new ControlInput(ThicknessEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-					}
-					break;
-				case FrictionCoefficientEnum:
-					if (iomodel->Data(FrictionCoefficientEnum)){
-						for(j=0;j<3;j++)nodeinputs[j]=iomodel->Data(FrictionCoefficientEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
-						this->inputs->AddInput(new ControlInput(FrictionCoefficientEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
-					}
-					break;
+
+				/*Special cases (depth averaged quantities)*/
 				case MaterialsRheologyBbarEnum:
 					if(iomodel->Data(MaterialsRheologyBEnum)){
-						for(j=0;j<3;j++) nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++) nodeinputs[j]=iomodel->Data(MaterialsRheologyBEnum)[tria_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
 						this->inputs->AddInput(new ControlInput(MaterialsRheologyBbarEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
@@ -1095,12 +1025,12 @@
 				case DamageDbarEnum:
 					if(iomodel->Data(DamageDEnum)){
-						for(j=0;j<3;j++) nodeinputs[j]=iomodel->Data(DamageDEnum)[tria_vertex_ids[j]-1];
-						for(j=0;j<3;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
-						for(j=0;j<3;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++) nodeinputs[j]=iomodel->Data(DamageDEnum)[tria_vertex_ids[j]-1];
+						for(j=0;j<NUMVERTICES;j++)cmmininputs[j]=iomodel->Data(InversionMinParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
+						for(j=0;j<NUMVERTICES;j++)cmmaxinputs[j]=iomodel->Data(InversionMaxParametersEnum)[(tria_vertex_ids[j]-1)*num_control_type+i];
 						this->inputs->AddInput(new ControlInput(DamageDbarEnum,TriaInputEnum,nodeinputs,cmmininputs,cmmaxinputs,i+1));
 					}
 					break;
 				default:
-					_error_("Control " << EnumToStringx(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])) << " not implemented yet");
+					_error_("Control " << EnumToStringx(control) << " not implemented yet");
 			}
 		}
@@ -1122,6 +1052,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputUpdateFromSolutionOneDof{{{*/
-void  Tria::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){
+void       Tria::InputUpdateFromSolutionOneDof(IssmDouble* solution,int enum_type){/*{{{*/
 
 	/*Intermediary*/
@@ -1149,6 +1078,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputUpdateFromVector(IssmDouble* vector, int name, int type);{{{*/
-void  Tria::InputUpdateFromVector(IssmDouble* vector, int name, int type){
+void       Tria::InputUpdateFromVector(IssmDouble* vector, int name, int type){/*{{{*/
 
 	/*Check that name is an element input*/
@@ -1215,6 +1143,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::IsOnBase {{{*/
-bool Tria::IsOnBase(){
+bool       Tria::IsOnBase(){/*{{{*/
 
 	int domaintype;
@@ -1229,6 +1156,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::IsOnSurface {{{*/
-bool Tria::IsOnSurface(){
+bool       Tria::IsOnSurface(){/*{{{*/
 
 	int domaintype;
@@ -1243,6 +1169,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::JacobianDeterminant{{{*/
-void Tria::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void       Tria::JacobianDeterminant(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
@@ -1251,6 +1176,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::JacobianDeterminantBase{{{*/
-void Tria::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){
+void       Tria::JacobianDeterminantBase(IssmDouble* pJdet,IssmDouble* xyz_list_base,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
@@ -1259,6 +1183,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::JacobianDeterminantSurface{{{*/
-void Tria::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){
+void       Tria::JacobianDeterminantSurface(IssmDouble* pJdet,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
@@ -1267,6 +1190,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::JacobianDeterminantTop{{{*/
-void Tria::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){
+void       Tria::JacobianDeterminantTop(IssmDouble* pJdet,IssmDouble* xyz_list_top,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
@@ -1275,6 +1197,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::HasEdgeOnBase {{{*/
-bool Tria::HasEdgeOnBase(){
+bool       Tria::HasEdgeOnBase(){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -1297,6 +1218,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::HasEdgeOnSurface {{{*/
-bool Tria::HasEdgeOnSurface(){
+bool       Tria::HasEdgeOnSurface(){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -1319,6 +1239,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::EdgeOnBaseIndices{{{*/
-void Tria::EdgeOnBaseIndices(int* pindex1,int* pindex2){
+void       Tria::EdgeOnBaseIndices(int* pindex1,int* pindex2){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -1340,6 +1259,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::EdgeOnSurfaceIndices{{{*/
-void Tria::EdgeOnSurfaceIndices(int* pindex1,int* pindex2){
+void       Tria::EdgeOnSurfaceIndices(int* pindex1,int* pindex2){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -1361,6 +1279,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::EdgeOnBaseIndex{{{*/
-int Tria::EdgeOnBaseIndex(void){
+int        Tria::EdgeOnBaseIndex(void){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -1380,6 +1297,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::EdgeOnSurfaceIndex{{{*/
-int Tria::EdgeOnSurfaceIndex(void){
+int        Tria::EdgeOnSurfaceIndex(void){/*{{{*/
 
 	IssmDouble values[NUMVERTICES];
@@ -1399,6 +1315,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::FSContactMigration{{{*/
-void Tria::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){
+void       Tria::FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){/*{{{*/
 
 	if(!IsOnBase()) return;
@@ -1406,4 +1321,5 @@
 	/*Intermediaries*/
 	IssmDouble* xyz_list = NULL;
+	IssmDouble* xyz_list_base = NULL;
 	IssmDouble  pressure,water_pressure,sigma_nn,viscosity,bed,base;
 	IssmDouble  bed_normal[2];
@@ -1414,4 +1330,5 @@
 	/* Get node coordinates and dof list: */
 	GetVerticesCoordinates(&xyz_list);
+	GetVerticesCoordinatesBase(&xyz_list_base);
 
 	/*Retrieve all inputs we will be needing: */
@@ -1440,5 +1357,5 @@
 
 			/*Get normal vector to the bed */
-			NormalBase(&bed_normal[0],xyz_list);
+			NormalBase(&bed_normal[0],xyz_list_base);
 
 			/*basalforce*/
@@ -1474,8 +1391,8 @@
 	delete gauss;
 	xDelete<IssmDouble>(xyz_list);
-}
-/*}}}*/
-/*FUNCTION Tria::IsNodeOnShelfFromFlags {{{*/
-bool   Tria::IsNodeOnShelfFromFlags(IssmDouble* flags){
+	xDelete<IssmDouble>(xyz_list_base);
+}
+/*}}}*/
+bool       Tria::IsNodeOnShelfFromFlags(IssmDouble* flags){/*{{{*/
 
 	int  i;
@@ -1491,16 +1408,13 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NewGauss(){{{*/
-Gauss* Tria::NewGauss(void){
+Gauss*     Tria::NewGauss(void){/*{{{*/
 	return new GaussTria();
 }
 /*}}}*/
-/*FUNCTION Tria::NewGauss(int order){{{*/
-Gauss* Tria::NewGauss(int order){
+Gauss*     Tria::NewGauss(int order){/*{{{*/
 	return new GaussTria(order);
 }
 /*}}}*/
-/*FUNCTION Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){{{*/
-Gauss* Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){
+Gauss*     Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order){/*{{{*/
 
 	IssmDouble  area_coordinates[2][3];
@@ -1509,12 +1423,10 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating){{{*/
-Gauss* Tria::NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){
+Gauss*     Tria::NewGauss(int point1,IssmDouble fraction1,IssmDouble fraction2,bool mainlyfloating,int order){/*{{{*/
 
 	return new GaussTria(point1,fraction1,fraction2,mainlyfloating,order);
 }
 /*}}}*/
-/*FUNCTION Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){{{*/
-Gauss* Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){
+Gauss*     Tria::NewGauss(IssmDouble* xyz_list, IssmDouble* xyz_list_front,int order_horiz,int order_vert){/*{{{*/
 
 	IssmDouble  area_coordinates[2][3];
@@ -1523,6 +1435,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NewGaussBase(int order){{{*/
-Gauss* Tria::NewGaussBase(int order){
+Gauss*     Tria::NewGaussBase(int order){/*{{{*/
 
 	int indices[2];
@@ -1531,6 +1442,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NewGaussTop(int order){{{*/
-Gauss* Tria::NewGaussTop(int order){
+Gauss*     Tria::NewGaussTop(int order){/*{{{*/
 
 	int indices[2];
@@ -1539,6 +1449,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NodalFunctions{{{*/
-void Tria::NodalFunctions(IssmDouble* basis, Gauss* gauss){
+void       Tria::NodalFunctions(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
@@ -1547,6 +1456,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NodalFunctionsDerivatives{{{*/
-void Tria::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Tria::NodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
@@ -1555,38 +1463,33 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NodalFunctionsDerivativesVelocity{{{*/
-void Tria::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){
+void       Tria::NodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
-	this->GetNodalFunctionsDerivativesVelocity(dbasis,xyz_list,(GaussTria*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tria::NodalFunctionsVelocity{{{*/
-void Tria::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){
+	this->GetNodalFunctionsDerivatives(dbasis,xyz_list,(GaussTria*)gauss,this->VelocityInterpolation());
+
+}
+/*}}}*/
+void       Tria::NodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
-	this->GetNodalFunctionsVelocity(basis,(GaussTria*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tria::NodalFunctionsPressure{{{*/
-void Tria::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){
+	this->GetNodalFunctions(basis,(GaussTria*)gauss,this->VelocityInterpolation());
+
+}
+/*}}}*/
+void       Tria::NodalFunctionsPressure(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
-	this->GetNodalFunctionsPressure(basis,(GaussTria*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tria::NodalFunctionsTensor{{{*/
-void Tria::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){
+	this->GetNodalFunctions(basis,(GaussTria*)gauss,this->PressureInterpolation());
+
+}
+/*}}}*/
+void       Tria::NodalFunctionsTensor(IssmDouble* basis, Gauss* gauss){/*{{{*/
 
 	_assert_(gauss->Enum()==GaussTriaEnum);
-	this->GetNodalFunctionsTensor(basis,(GaussTria*)gauss);
-
-}
-/*}}}*/
-/*FUNCTION Tria::NodalValue {{{*/
-int    Tria::NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){
+	this->GetNodalFunctions(basis,(GaussTria*)gauss,this->TensorInterpolation());
+
+}
+/*}}}*/
+int        Tria::NodalValue(IssmDouble* pvalue, int index, int natureofdataenum){/*{{{*/
 
 	int         found = 0;
@@ -1620,6 +1523,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::NormalBase {{{*/
-void Tria::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){
+void       Tria::NormalBase(IssmDouble* bed_normal,IssmDouble* xyz_list){/*{{{*/
 
 	/*Build unit outward pointing vector*/
@@ -1634,13 +1536,15 @@
 	bed_normal[0]= + vector[1]/norm;
 	bed_normal[1]= - vector[0]/norm;
-}
-/*}}}*/
-/*FUNCTION Tria::NormalTop {{{*/
-void Tria::NormalTop(IssmDouble* bed_normal,IssmDouble* xyz_list){
+	_assert_(bed_normal[1]<0); 
+}
+/*}}}*/
+void       Tria::NormalTop(IssmDouble* top_normal,IssmDouble* xyz_list){/*{{{*/
 
 	/*Build unit outward pointing vector*/
+	int index1,index2;
 	IssmDouble vector[2];
 	IssmDouble norm;
 
+	this->EdgeOnSurfaceIndices(&index1,&index2);
 	vector[0]=xyz_list[1*3+0] - xyz_list[0*3+0];
 	vector[1]=xyz_list[1*3+1] - xyz_list[0*3+1];
@@ -1648,30 +1552,30 @@
 	norm=sqrt(vector[0]*vector[0] + vector[1]*vector[1]);
 
-	bed_normal[0]= + vector[1]/norm;
-	bed_normal[1]= - vector[0]/norm;
-}
-/*}}}*/
-/*FUNCTION Tria::VelocityInterpolation{{{*/
-int Tria::VelocityInterpolation(void){
+	top_normal[0]= + vector[1]/norm;
+	top_normal[1]= - vector[0]/norm;
+	_assert_(top_normal[1]>0); 
+}
+/*}}}*/
+int        Tria::VelocityInterpolation(void){/*{{{*/
 	return TriaRef::VelocityInterpolation();
 }
 /*}}}*/
-/*FUNCTION Tria::PressureInterpolation{{{*/
-int Tria::PressureInterpolation(void){
+int        Tria::PressureInterpolation(void){/*{{{*/
 	return TriaRef::PressureInterpolation();
 }
 /*}}}*/
-/*FUNCTION Tria::NumberofNodesPressure{{{*/
-int Tria::NumberofNodesPressure(void){
-	return TriaRef::NumberofNodesPressure();
-}
-/*}}}*/
-/*FUNCTION Tria::NumberofNodesVelocity{{{*/
-int Tria::NumberofNodesVelocity(void){
-	return TriaRef::NumberofNodesVelocity();
-}
-/*}}}*/
-/*FUNCTION Tria::PositiveDegreeDay{{{*/
-void  Tria::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){
+int        Tria::TensorInterpolation(void){/*{{{*/
+	return TriaRef::TensorInterpolation();
+}
+/*}}}*/
+int        Tria::NumberofNodesPressure(void){/*{{{*/
+	return TriaRef::NumberofNodes(this->PressureInterpolation());
+}
+/*}}}*/
+int        Tria::NumberofNodesVelocity(void){/*{{{*/
+	return TriaRef::NumberofNodes(this->VelocityInterpolation());
+}
+/*}}}*/
+void       Tria::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm){/*{{{*/
 
    IssmDouble agd[NUMVERTICES];             // surface mass balance
@@ -1722,6 +1626,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ReduceMatrices {{{*/
-void Tria::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){
+void       Tria::ReduceMatrices(ElementMatrix* Ke,ElementVector* pe){/*{{{*/
 
 	/*Static condensation if requested*/
@@ -1761,6 +1664,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ResetFSBasalBoundaryCondition{{{*/
-void  Tria::ResetFSBasalBoundaryCondition(void){
+void       Tria::ResetFSBasalBoundaryCondition(void){/*{{{*/
 
 	int numnodes = this->NumberofNodesVelocity();
@@ -1812,12 +1714,10 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SetClone {{{*/
-void  Tria::SetClone(int* minranks){
+void       Tria::SetClone(int* minranks){/*{{{*/
 
 	_error_("not implemented yet");
 }
 /*}}}*/
-/*FUNCTION Tria::SmbGradients{{{*/
-void Tria::SmbGradients(void){
+void       Tria::SmbGradients(void){/*{{{*/
 
 	int i;
@@ -1864,6 +1764,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SpawnSeg {{{*/
-Seg*  Tria::SpawnSeg(int index1,int index2){
+Seg*       Tria::SpawnSeg(int index1,int index2){/*{{{*/
 
 	int analysis_counter;
@@ -1892,6 +1791,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SpawnBasalElement{{{*/
-Element*  Tria::SpawnBasalElement(void){
+Element*   Tria::SpawnBasalElement(void){/*{{{*/
 
 	int index1,index2;
@@ -1911,6 +1809,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SpawnTopElement{{{*/
-Element*  Tria::SpawnTopElement(void){
+Element*   Tria::SpawnTopElement(void){/*{{{*/
 
 	int index1,index2;
@@ -1930,6 +1827,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SetCurrentConfiguration {{{*/
-void  Tria::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){
+void       Tria::SetCurrentConfiguration(Elements* elementsin, Loads* loadsin, Nodes* nodesin, Materials* materialsin, Parameters* parametersin){/*{{{*/
 
 	/*go into parameters and get the analysis_counter: */
@@ -1946,6 +1842,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SurfaceArea {{{*/
-IssmDouble Tria::SurfaceArea(void){
+IssmDouble Tria::SurfaceArea(void){/*{{{*/
 
 	IssmDouble S;
@@ -1974,6 +1869,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::TimeAdapt{{{*/
-IssmDouble  Tria::TimeAdapt(void){
+IssmDouble Tria::TimeAdapt(void){/*{{{*/
 
 	/*intermediary: */
@@ -2016,6 +1910,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::Update{{{*/
-void Tria::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){
+void       Tria::Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finiteelement_type){/*{{{*/
 
 	/*Intermediaries*/
@@ -2113,6 +2006,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::UpdateConstraintsExtrudeFromBase{{{*/
-void  Tria::UpdateConstraintsExtrudeFromBase(void){
+void       Tria::UpdateConstraintsExtrudeFromBase(void){/*{{{*/
 
 	if(!HasEdgeOnBase()) return;
@@ -2138,6 +2030,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::UpdateConstraintsExtrudeFromTop{{{*/
-void  Tria::UpdateConstraintsExtrudeFromTop(void){
+void       Tria::UpdateConstraintsExtrudeFromTop(void){/*{{{*/
 
 	if(!HasEdgeOnSurface()) return;
@@ -2161,22 +2052,18 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ValueP1OnGauss{{{*/
-void Tria::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){
+void       Tria::ValueP1OnGauss(IssmDouble* pvalue,IssmDouble* values,Gauss* gauss){/*{{{*/
 	TriaRef::GetInputValue(pvalue,values,gauss,P1Enum);
 }
 /*}}}*/
-/*FUNCTION Tria::ValueP1DerivativesOnGauss{{{*/
-void Tria::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){
+void       Tria::ValueP1DerivativesOnGauss(IssmDouble* dvalue,IssmDouble* values,IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	TriaRef::GetInputDerivativeValue(dvalue,values,xyz_list,gauss);
 }
 /*}}}*/
-/*FUNCTION Tria::VertexConnectivity{{{*/
-int Tria::VertexConnectivity(int vertexindex){
+int        Tria::VertexConnectivity(int vertexindex){/*{{{*/
 	_assert_(this->vertices);
 	return this->vertices[vertexindex]->Connectivity();
 }
 /*}}}*/
-/*FUNCTION Tria::IsZeroLevelset{{{*/
-bool Tria::IsZeroLevelset(int levelset_enum){
+bool       Tria::IsZeroLevelset(int levelset_enum){/*{{{*/
 
 	bool iszerols;
@@ -2197,5 +2084,5 @@
 }
 /*}}}*/
-bool Tria::IsIcefront(void){/*{{{*/
+bool       Tria::IsIcefront(void){/*{{{*/
 
 	bool isicefront;
@@ -2216,6 +2103,25 @@
 	return isicefront;
 }/*}}}*/
-/*FUNCTION Tria::AverageOntoPartition {{{*/
-void  Tria::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){
+bool       Tria::IsFaceOnBoundary(void){/*{{{*/
+
+	IssmDouble values[NUMVERTICES];
+	IssmDouble sum;
+
+	/*Retrieve all inputs and parameters*/
+	GetInputListOnVertices(&values[0],MeshVertexonboundaryEnum);
+	sum = values[0]+values[1]+values[2];
+
+	_assert_(sum==0. || sum==1. || sum==2.);
+
+	if(sum==3.)  _error_("Two edges on boundary not supported yet...");
+
+	if(sum>1.){
+		return true;
+	}
+	else{
+		return false;
+	}
+}/*}}}*/
+void       Tria::AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part){/*{{{*/
 
 	bool       already = false;
@@ -2255,6 +2161,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::IceVolume {{{*/
-IssmDouble Tria::IceVolume(void){
+IssmDouble Tria::IceVolume(void){/*{{{*/
 
 	/*The volume of a troncated prism is base * 1/3 sum(length of edges)*/
@@ -2284,6 +2189,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::IceVolumeAboveFloatation {{{*/
-IssmDouble Tria::IceVolumeAboveFloatation(void){
+IssmDouble Tria::IceVolumeAboveFloatation(void){/*{{{*/
 
 	/*The volume above floatation: H + rho_water/rho_ice * bathymetry */
@@ -2315,6 +2219,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MassFlux {{{*/
-IssmDouble Tria::MassFlux( IssmDouble x1, IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){
+IssmDouble Tria::MassFlux( IssmDouble x1, IssmDouble y1, IssmDouble x2, IssmDouble y2,int segment_id){/*{{{*/
 
 	int        domaintype;
@@ -2379,6 +2282,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MassFlux {{{*/
-IssmDouble Tria::MassFlux( IssmDouble* segment){
+IssmDouble Tria::MassFlux( IssmDouble* segment){/*{{{*/
 
 	int        domaintype;
@@ -2446,6 +2348,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxAbsVx{{{*/
-void  Tria::MaxAbsVx(IssmDouble* pmaxabsvx){
+void       Tria::MaxAbsVx(IssmDouble* pmaxabsvx){/*{{{*/
 
 	/*Get maximum:*/
@@ -2456,6 +2357,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxAbsVy{{{*/
-void  Tria::MaxAbsVy(IssmDouble* pmaxabsvy){
+void       Tria::MaxAbsVy(IssmDouble* pmaxabsvy){/*{{{*/
 
 	/*Get maximum:*/
@@ -2466,6 +2366,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxAbsVz{{{*/
-void  Tria::MaxAbsVz(IssmDouble* pmaxabsvz){
+void       Tria::MaxAbsVz(IssmDouble* pmaxabsvz){/*{{{*/
 
 	/*Get maximum:*/
@@ -2476,6 +2375,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxVel{{{*/
-void  Tria::MaxVel(IssmDouble* pmaxvel){
+void       Tria::MaxVel(IssmDouble* pmaxvel){/*{{{*/
 
 	/*Get maximum:*/
@@ -2486,6 +2384,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxVx{{{*/
-void  Tria::MaxVx(IssmDouble* pmaxvx){
+void       Tria::MaxVx(IssmDouble* pmaxvx){/*{{{*/
 
 	/*Get maximum:*/
@@ -2496,6 +2393,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxVy{{{*/
-void  Tria::MaxVy(IssmDouble* pmaxvy){
+void       Tria::MaxVy(IssmDouble* pmaxvy){/*{{{*/
 
 	/*Get maximum:*/
@@ -2507,6 +2403,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MaxVz{{{*/
-void  Tria::MaxVz(IssmDouble* pmaxvz){
+void       Tria::MaxVz(IssmDouble* pmaxvz){/*{{{*/
 
 	/*Get maximum:*/
@@ -2517,6 +2412,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MinVel{{{*/
-void  Tria::MinVel(IssmDouble* pminvel){
+void       Tria::MinVel(IssmDouble* pminvel){/*{{{*/
 
 	/*Get minimum:*/
@@ -2527,6 +2421,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MinVx{{{*/
-void  Tria::MinVx(IssmDouble* pminvx){
+void       Tria::MinVx(IssmDouble* pminvx){/*{{{*/
 
 	/*Get minimum:*/
@@ -2537,6 +2430,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MinVy{{{*/
-void  Tria::MinVy(IssmDouble* pminvy){
+void       Tria::MinVy(IssmDouble* pminvy){/*{{{*/
 
 	/*Get minimum:*/
@@ -2547,6 +2439,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MinVz{{{*/
-void  Tria::MinVz(IssmDouble* pminvz){
+void       Tria::MinVz(IssmDouble* pminvz){/*{{{*/
 
 	/*Get minimum:*/
@@ -2557,6 +2448,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ElementResponse{{{*/
-void Tria::ElementResponse(IssmDouble* presponse,int response_enum){
+void       Tria::ElementResponse(IssmDouble* presponse,int response_enum){/*{{{*/
 
 	switch(response_enum){
@@ -2583,6 +2473,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::TotalSmb {{{*/
-IssmDouble Tria::TotalSmb(void){
+IssmDouble Tria::TotalSmb(void){/*{{{*/
 
 	/*The smb[kg yr-1] of one element is area[m2] * smb [kg m^-2 yr^-1]*/
@@ -2612,6 +2501,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::MisfitArea{{{*/
-IssmDouble Tria::MisfitArea(int weightsenum){
+IssmDouble Tria::MisfitArea(int weightsenum){/*{{{*/
 
 	/*Intermediaries*/
@@ -2650,6 +2538,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::Misfit{{{*/
-IssmDouble Tria::Misfit(int modelenum,int observationenum,int weightsenum){
+IssmDouble Tria::Misfit(int modelenum,int observationenum,int weightsenum){/*{{{*/
 
 	/*Intermediaries*/
@@ -2694,6 +2581,5 @@
 
 #ifdef _HAVE_GIA_
-/*FUNCTION Tria::GiaDeflection {{{*/
-void Tria::GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x, IssmDouble* y){
+void       Tria::GiaDeflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt,IssmDouble* x, IssmDouble* y){/*{{{*/
 
 	int i;
@@ -2822,64 +2708,5 @@
 #endif
 
-/*FUNCTION Tria::BalancethicknessMisfit{{{*/
-IssmDouble Tria::BalancethicknessMisfit(void){
-
-	/* Intermediaries */
-	IssmDouble Jelem = 0;
-	IssmDouble weight;
-	IssmDouble Jdet,temp;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dH[2];
-	IssmDouble vx,vy,H;
-	IssmDouble dvx[2],dvy[2];
-	IssmDouble dhdt,basal_melting,surface_mass_balance;
-	GaussTria *gauss = NULL;
-
-	/*If on water, return 0: */
-	if(!IsIceInElement()) return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* weights_input              = inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* thickness_input            = inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-	Input* vx_input                   = inputs->GetInput(VxEnum);                                 _assert_(vx_input);
-	Input* vy_input                   = inputs->GetInput(VyEnum);                                 _assert_(vy_input);
-	Input* surface_mass_balance_input = inputs->GetInput(SurfaceforcingsMassBalanceEnum);         _assert_(surface_mass_balance_input);
-	Input* basal_melting_input        = inputs->GetInput(BasalforcingsMeltingRateEnum);           _assert_(basal_melting_input);
-	Input* dhdt_input                 = inputs->GetInput(BalancethicknessThickeningRateEnum);     _assert_(dhdt_input);
-
-	/* Start looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum);
-		thickness_input->GetInputValue(&H, gauss);
-		thickness_input->GetInputDerivativeValue(&dH[0],&xyz_list[0][0],gauss);
-		surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss);
-		basal_melting_input->GetInputValue(&basal_melting,gauss);
-		dhdt_input->GetInputValue(&dhdt,gauss);
-		vx_input->GetInputValue(&vx,gauss);
-		vx_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vy_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
-
-		/*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/
-		temp  = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-basal_melting-dhdt);
-		Jelem+=weight*1/2*temp*temp*Jdet*gauss->weight;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::InputControlUpdate{{{*/
-void  Tria::InputControlUpdate(IssmDouble scalar,bool save_parameter){
+void       Tria::InputControlUpdate(IssmDouble scalar,bool save_parameter){/*{{{*/
 
 	/*Intermediary*/
@@ -2908,6 +2735,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::ControlInputGetGradient{{{*/
-void Tria::ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){
+void       Tria::ControlInputGetGradient(Vector<IssmDouble>* gradient,int enum_type,int control_index){/*{{{*/
 
 	int vertexpidlist[NUMVERTICES];
@@ -2921,6 +2747,5 @@
 
 }/*}}}*/
-/*FUNCTION Tria::ControlInputScaleGradient{{{*/
-void Tria::ControlInputScaleGradient(int enum_type,IssmDouble scale){
+void       Tria::ControlInputScaleGradient(int enum_type,IssmDouble scale){/*{{{*/
 
 	Input* input=inputs->GetInput(enum_type);
@@ -2930,6 +2755,5 @@
 	((ControlInput*)input)->ScaleGradient(scale);
 }/*}}}*/
-/*FUNCTION Tria::ControlInputSetGradient{{{*/
-void Tria::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){
+void       Tria::ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index){/*{{{*/
 
 	int    vertexpidlist[NUMVERTICES];
@@ -2948,6 +2772,5 @@
 
 }/*}}}*/
-/*FUNCTION Tria::ControlToVectors{{{*/
-void Tria::ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){
+void       Tria::ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum){/*{{{*/
 
 	Input* input=inputs->GetInput(control_enum);
@@ -2980,7 +2803,9 @@
 
 }/*}}}*/
-/*FUNCTION Tria::Gradj {{{*/
-void  Tria::Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){
+void       Tria::Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index){/*{{{*/
 	/*dJ/dalpha = ∂L/∂alpha = ∂J/∂alpha + ∂/∂alpha(KU-F)*/
+
+	int   approximation;
+	Seg*  seg=NULL;
 
 	/*If on water, grad = 0: */
@@ -2990,5 +2815,18 @@
 	switch(control_type){
 		case FrictionCoefficientEnum:
-			GradjDragSSA(gradient,control_index);
+			inputs->GetInputValue(&approximation,ApproximationEnum);
+			switch(approximation){
+				case SSAApproximationEnum:
+					GradjDragSSA(gradient,control_index);
+					break;
+				case FSApproximationEnum:
+					GradjDragFS(gradient,control_index);
+					break;
+				case NoneApproximationEnum:
+					/*Gradient is 0*/
+					break;
+				default:
+					_error_("approximation " << EnumToStringx(approximation) << " not supported yet");
+			}
 			break;
 		case MaterialsRheologyBbarEnum:
@@ -3036,5 +2874,24 @@
 			break;
 		case DragCoefficientAbsGradientEnum:
-			GradjDragGradient(gradient,control_index);
+			inputs->GetInputValue(&approximation,ApproximationEnum);
+			switch(approximation){
+				case SSAApproximationEnum:
+					GradjDragGradient(gradient,control_index);
+					break;
+				case FSApproximationEnum:{
+					if(IsFloating() || !IsOnBase()) return;
+					int index1,index2;
+					this->EdgeOnBaseIndices(&index1,&index2);
+					Seg* seg = SpawnSeg(index1,index2);
+					seg->GradjDragGradient(gradient,control_index);
+					seg->DeleteMaterials(); delete seg;
+					break;
+												 }
+				case NoneApproximationEnum:
+					/*Gradient is 0*/
+					break;
+				default:
+					_error_("approximation " << EnumToStringx(approximation) << " not supported yet");
+			}
 			break;
 		case RheologyBbarAbsGradientEnum:
@@ -3048,6 +2905,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjBGradient{{{*/
-void  Tria::GradjBGradient(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjBGradient(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	int        i;
@@ -3088,6 +2944,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjBSSA{{{*/
-void  Tria::GradjBSSA(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjBSSA(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Intermediaries*/
@@ -3145,6 +3000,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjDSSA{{{*/
-void  Tria::GradjDSSA(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjDSSA(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Intermediaries*/
@@ -3203,6 +3057,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjDragSSA {{{*/
-void  Tria::GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjDragSSA(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	int        i;
@@ -3248,5 +3101,5 @@
 
 		/*Build alpha_complement_list: */
-		friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,NULL);
+		friction->GetAlphaComplement(&alpha_complement,gauss);
 
 		dragcoefficient_input->GetInputValue(&drag, gauss);
@@ -3273,5 +3126,5 @@
 	//for (int iv=0;iv<NUMVERTICES;iv++){
 	//	gauss->GaussVertex(iv);
-	//	friction->GetAlphaComplement(&alpha_complement,gauss,vx_input,vy_input,vz_input);
+	//	friction->GetAlphaComplement(&alpha_complement,gauss);
 	//	dragcoefficient_input->GetInputValue(&drag, gauss);
 	//	adjointx_input->GetInputValue(&lambda, gauss);
@@ -3290,6 +3143,17 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjDragGradient{{{*/
-void  Tria::GradjDragGradient(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjDragFS(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
+
+	/*Gradient is 0 if on shelf or not on bed*/
+	if(IsFloating() || !IsOnBase()) return;
+
+	int index1,index2;
+	this->EdgeOnBaseIndices(&index1,&index2);
+	Seg* seg = SpawnSeg(index1,index2);
+	seg->GradjDragFS(gradient,control_index);
+	seg->DeleteMaterials(); delete seg;
+}
+/*}}}*/
+void       Tria::GradjDragGradient(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	int        i;
@@ -3334,6 +3198,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjDhDtBalancedthickness{{{*/
-void  Tria::GradjDhDtBalancedthickness(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjDhDtBalancedthickness(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Intermediaries*/
@@ -3350,6 +3213,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjVxBalancedthickness{{{*/
-void  Tria::GradjVxBalancedthickness(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjVxBalancedthickness(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Intermediaries*/
@@ -3393,6 +3255,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjVyBalancedthickness{{{*/
-void  Tria::GradjVyBalancedthickness(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjVyBalancedthickness(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Intermediaries*/
@@ -3435,6 +3296,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradjThicknessBalancethicknessSoft{{{*/
-void  Tria::GradjThicknessBalancethicknessSoft(Vector<IssmDouble>* gradient,int control_index){
+void       Tria::GradjThicknessBalancethicknessSoft(Vector<IssmDouble>* gradient,int control_index){/*{{{*/
 
 	/*Intermediaries */
@@ -3544,6 +3404,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::GradientIndexing{{{*/
-void  Tria::GradientIndexing(int* indexing,int control_index){
+void       Tria::GradientIndexing(int* indexing,int control_index){/*{{{*/
 
 	/*Get some parameters*/
@@ -3558,574 +3417,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::RheologyBbarAbsGradient{{{*/
-IssmDouble Tria::RheologyBbarAbsGradient(void){
-
-	/* Intermediaries */
-	IssmDouble Jelem = 0;
-	IssmDouble weight;
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dp[NDOF2];
-	GaussTria *gauss = NULL;
-
-	/*retrieve parameters and inputs*/
-
-	/*If on water, return 0: */
-	if(!IsIceInElement()) return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);              _assert_(weights_input);
-	Input* rheologyb_input=inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
-
-	/* Start looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,RheologyBbarAbsGradientEnum);
-		rheologyb_input->GetInputDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
-
-		/*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
-		Jelem+=weight*1/2*(dp[0]*dp[0] + dp[1]*dp[1])*Jdet*gauss->weight;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceAverageVelMisfit {{{*/
-IssmDouble Tria::SurfaceAverageVelMisfit(void){
-
-	IssmDouble Jelem=0,S,Jdet;
-	IssmDouble misfit;
-	IssmDouble vx,vy,vxobs,vyobs,weight;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	GaussTria *gauss=NULL;
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/* Get node coordinates and dof list: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Retrieve all inputs we will be needing: */
-	inputs->GetInputValue(&S,SurfaceAreaEnum);
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(3);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,SurfaceAverageVelMisfitEnum);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-
-		/*Compute SurfaceAverageVelMisfitEnum:
-		 *
-		 *      1                    2              2
-		 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
-		 *      S                obs            obs
-		 */
-		misfit=1/S*sqrt( pow(vx-vxobs,2) + pow(vy-vyobs,2));
-
-		/*Add to cost function*/
-		Jelem+=misfit*weight*Jdet*gauss->weight;
-	}
-
-	/*clean-up and Return: */
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceLogVelMisfit {{{*/
-IssmDouble Tria::SurfaceLogVelMisfit(void){
-
-	IssmDouble Jelem=0.;
-	IssmDouble misfit,Jdet;
-	IssmDouble epsvel=2.220446049250313e-16;
-	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
-	IssmDouble velocity_mag,obs_velocity_mag;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble vx,vy,vxobs,vyobs,weight;
-	GaussTria *gauss=NULL;
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/* Get node coordinates and dof list: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Retrieve all inputs we will be needing: */
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(4);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,SurfaceLogVelMisfitEnum);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-
-		/*Compute SurfaceLogVelMisfit:
-		 *        4         [        vel + eps     ] 2
-		 * J = 4 \bar{v}^2 | log ( -----------  ) |  
-		 *                 [       vel   + eps    ]
-		 *                            obs
-		 */
-		velocity_mag    =sqrt(pow(vx,   2)+pow(vy,   2))+epsvel;
-		obs_velocity_mag=sqrt(pow(vxobs,2)+pow(vyobs,2))+epsvel;
-		misfit=4*pow(meanvel,2)*pow(log(velocity_mag/obs_velocity_mag),2);
-
-		/*Add to cost function*/
-		Jelem+=misfit*weight*Jdet*gauss->weight;
-	}
-
-	/*clean-up and Return: */
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceLogVxVyMisfit {{{*/
-IssmDouble Tria::SurfaceLogVxVyMisfit(void){
-
-	IssmDouble Jelem=0, S=0;
-	IssmDouble epsvel=2.220446049250313e-16;
-	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
-	IssmDouble misfit, Jdet;
-	IssmDouble vx,vy,vxobs,vyobs,weight;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	GaussTria *gauss=NULL;
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/* Get node coordinates and dof list: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Retrieve all inputs we will be needing: */
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(4);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,SurfaceLogVxVyMisfitEnum);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-
-		/*Compute SurfaceRelVelMisfit:
-		 *
-		 *      1            [        |u| + eps     2          |v| + eps     2  ]
-		 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
-		 *      2            [       |u    |+ eps              |v    |+ eps     ]
-		 *                              obs                       obs
-		 */
-		misfit=0.5*pow(meanvel,2)*(
-					pow(log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)),2) +
-					pow(log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)),2) );
-
-		/*Add to cost function*/
-		Jelem+=misfit*weight*Jdet*gauss->weight;
-	}
-
-	/*clean-up and Return: */
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceAbsVelMisfit {{{*/
-IssmDouble Tria::SurfaceAbsVelMisfit(void){
-
-	IssmDouble Jelem=0;
-	IssmDouble misfit,Jdet;
-	IssmDouble vx,vy,vxobs,vyobs,weight;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	GaussTria *gauss=NULL;
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/* Get node coordinates and dof list: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Retrieve all inputs we will be needing: */
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,SurfaceAbsVelMisfitEnum);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-
-		/*Compute SurfaceAbsVelMisfitEnum:
-		 *
-		 *      1  [           2              2 ]
-		 * J = --- | (u - u   )  +  (v - v   )  |
-		 *      2  [       obs            obs   ]
-		 *
-		 */
-		misfit=0.5*( pow(vx-vxobs,2) + pow(vy-vyobs,2) );
-
-		/*Add to cost function*/
-		Jelem+=misfit*weight*Jdet*gauss->weight;
-	}
-
-	/*clean up and Return: */
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::SurfaceRelVelMisfit {{{*/
-IssmDouble Tria::SurfaceRelVelMisfit(void){
-
-	IssmDouble  Jelem=0;
-	IssmDouble  scalex=1,scaley=1;
-	IssmDouble  misfit,Jdet;
-	IssmDouble  epsvel=2.220446049250313e-16;
-	IssmDouble  meanvel=3.170979198376458e-05; /*1000 m/yr*/
-	IssmDouble  vx,vy,vxobs,vyobs,weight;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	GaussTria *gauss=NULL;
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/* Get node coordinates and dof list: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-
-	/*Retrieve all inputs we will be needing: */
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
-	Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
-	Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
-	Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(4);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,SurfaceRelVelMisfitEnum);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vxobs_input->GetInputValue(&vxobs,gauss);
-		vyobs_input->GetInputValue(&vyobs,gauss);
-
-		/*Compute SurfaceRelVelMisfit:
-		 *                        
-		 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
-		 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
-		 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
-		 *              obs                        obs                      
-		 */
-		scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
-		scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
-		misfit=0.5*(scalex*pow((vx-vxobs),2)+scaley*pow((vy-vyobs),2));
-
-		/*Add to cost function*/
-		Jelem+=misfit*weight*Jdet*gauss->weight;
-	}
-
-	/*clean up and Return: */
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::ThicknessAbsGradient{{{*/
-IssmDouble Tria::ThicknessAbsGradient(void){
-
-	/* Intermediaries */
-	IssmDouble Jelem = 0;
-	IssmDouble weight;
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dp[NDOF2];
-	GaussTria *gauss = NULL;
-
-	/*retrieve parameters and inputs*/
-
-	/*If on water, return 0: */
-	if(!IsIceInElement()) return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
-	Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
-
-	/* Start looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,ThicknessAbsGradientEnum);
-		thickness_input->GetInputDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
-
-		/*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
-		Jelem+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::ThicknessAlongGradient{{{*/
-IssmDouble Tria::ThicknessAlongGradient(void){
-
-	/* Intermediaries */
-	IssmDouble  Jelem = 0;
-	IssmDouble  weight;
-	IssmDouble  Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  dp[NDOF2];
-	IssmDouble  vx,vy,vel;
-	GaussTria  *gauss                    = NULL;
-
-	/*retrieve parameters and inputs*/
-
-	/*If on water, return 0: */
-	if(!IsIceInElement()) return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* weights_input  = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
-	Input* thickness_input= inputs->GetInput(ThicknessEnum);                          _assert_(thickness_input);
-	Input* vx_input       = inputs->GetInput(VxEnum);                                 _assert_(vx_input);
-	Input* vy_input       = inputs->GetInput(VyEnum);                                 _assert_(vy_input);
-
-	/* Start looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,ThicknessAlongGradientEnum);
-		thickness_input->GetInputDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vel = sqrt(vx*vx+vy*vy);
-		vx  = vx/(vel+1.e-9);
-		vy  = vy/(vel+1.e-9);
-
-		/*J = 1/2 ( vx*dH/dx + vy*dH/dy )^2 */
-		Jelem+=weight*1/2*(vx*dp[0] + vy*dp[1])*(vx*dp[0] + vy*dp[1])*Jdet*gauss->weight;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::ThicknessAcrossGradient{{{*/
-IssmDouble Tria::ThicknessAcrossGradient(void){
-
-	/* Intermediaries */
-	IssmDouble  Jelem = 0;
-	IssmDouble  weight;
-	IssmDouble  Jdet;
-	IssmDouble  xyz_list[NUMVERTICES][3];
-	IssmDouble  dp[NDOF2];
-	IssmDouble  vx,vy,vel;
-	GaussTria  *gauss                    = NULL;
-
-	/*retrieve parameters and inputs*/
-
-	/*If on water, return 0: */
-	if(!IsIceInElement()) return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* weights_input  = inputs->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
-	Input* thickness_input= inputs->GetInput(ThicknessEnum);                          _assert_(thickness_input);
-	Input* vx_input       = inputs->GetInput(VxEnum);                                 _assert_(vx_input);
-	Input* vy_input       = inputs->GetInput(VyEnum);                                 _assert_(vy_input);
-
-	/* Start looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,ThicknessAcrossGradientEnum);
-		thickness_input->GetInputDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
-		vx_input->GetInputValue(&vx,gauss);
-		vy_input->GetInputValue(&vy,gauss);
-		vel = sqrt(vx*vx+vy*vy);
-		vx  = vx/(vel+1.e-9);
-		vy  = vy/(vel+1.e-9);
-
-		/*J = 1/2 ( -vy*dH/dx + vx*dH/dy )^2 */
-		Jelem+=weight*1/2*(-vy*dp[0] + vx*dp[1])*(-vy*dp[0] + vx*dp[1])*Jdet*gauss->weight;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::ThicknessAbsMisfit {{{*/
-IssmDouble Tria::ThicknessAbsMisfit(void){
-
-	/*Intermediaries*/
-	IssmDouble thickness,thicknessobs,weight;
-	IssmDouble Jdet;
-	IssmDouble Jelem = 0;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	GaussTria *gauss = NULL;
-	IssmDouble dH[2];
-
-	/*If on water, return 0: */
-	if(!IsIceInElement())return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* thickness_input   =inputs->GetInput(ThicknessEnum);   _assert_(thickness_input);
-	Input* thicknessobs_input=inputs->GetInput(InversionThicknessObsEnum);_assert_(thicknessobs_input);
-	Input* weights_input     =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);     _assert_(weights_input);
-
-	/* Start  looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get parameters at gauss point*/
-		thickness_input->GetInputValue(&thickness,gauss);
-		thickness_input->GetInputDerivativeValue(&dH[0],&xyz_list[0][0],gauss);
-		thicknessobs_input->GetInputValue(&thicknessobs,gauss);
-		weights_input->GetInputValue(&weight,gauss,ThicknessAbsMisfitEnum);
-
-		/*compute ThicknessAbsMisfit*/
-		Jelem+=0.5*(thickness-thicknessobs)*(thickness-thicknessobs)*weight*Jdet*gauss->weight;
-	}
-
-	/* clean up and Return: */
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::DragCoefficientAbsGradient{{{*/
-IssmDouble Tria::DragCoefficientAbsGradient(void){
-
-	/* Intermediaries */
-	IssmDouble Jelem = 0;
-	IssmDouble weight;
-	IssmDouble Jdet;
-	IssmDouble xyz_list[NUMVERTICES][3];
-	IssmDouble dp[NDOF2];
-	GaussTria *gauss = NULL;
-
-	/*retrieve parameters and inputs*/
-
-	/*If on water, return 0: */
-	if(!IsIceInElement()) return 0;
-
-	/*Retrieve all inputs we will be needing: */
-	::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);
-	Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);         _assert_(weights_input);
-	Input* drag_input   =inputs->GetInput(FrictionCoefficientEnum); _assert_(drag_input);
-
-	/* Start looping on the number of gaussian points: */
-	gauss=new GaussTria(2);
-	for(int ig=gauss->begin();ig<gauss->end();ig++){
-
-		gauss->GaussPoint(ig);
-
-		/* Get Jacobian determinant: */
-		GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
-
-		/*Get all parameters at gaussian point*/
-		weights_input->GetInputValue(&weight,gauss,DragCoefficientAbsGradientEnum);
-		drag_input->GetInputDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
-
-		/*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
-		Jelem+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
-	}
-
-	/*Clean up and return*/
-	delete gauss;
-	return Jelem;
-}
-/*}}}*/
-/*FUNCTION Tria::GetVectorFromControlInputs{{{*/
-void  Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){
+void       Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){/*{{{*/
 
 	int vertexpidlist[NUMVERTICES];
@@ -4149,6 +3439,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::SetControlInputsFromVector{{{*/
-void  Tria::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){
+void       Tria::SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index){/*{{{*/
 
 	IssmDouble  values[NUMVERTICES];
@@ -4177,60 +3466,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::CreateHydrologyWaterVelocityInput {{{*/
-void Tria::CreateHydrologyWaterVelocityInput(void){
-
-	/*material parameters: */
-	IssmDouble mu_water;
-	IssmDouble VelocityFactor;  // This factor represents the number 12 in laminar flow velocity which can vary by differnt hydrology.CR
-	IssmDouble n_man,CR;
-	IssmDouble w;
-	IssmDouble rho_ice, rho_water, g;
-	IssmDouble dsdx,dsdy,dbdx,dbdy;
-	IssmDouble vx[NUMVERTICES];
-	IssmDouble vy[NUMVERTICES];
-	GaussTria *gauss = NULL;
-
-	/*Retrieve all inputs and parameters*/
-	rho_ice=matpar->GetRhoIce();
-	rho_water=matpar->GetRhoWater();
-	g=matpar->GetG();
-	CR=matpar->GetHydrologyCR(); // To have Lebrocq equavalent equation: CR=0.01,n_man=0.02
-	n_man=matpar->GetHydrologyN(); 
-	mu_water=matpar->GetMuWater();
-	Input* surfaceslopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(surfaceslopex_input);
-	Input* surfaceslopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(surfaceslopey_input);
-	Input* bedslopex_input=inputs->GetInput(BedSlopeXEnum);         _assert_(bedslopex_input);
-	Input* bedslopey_input=inputs->GetInput(BedSlopeYEnum);         _assert_(bedslopey_input);
-	Input* watercolumn_input=inputs->GetInput(WatercolumnEnum);     _assert_(watercolumn_input);
-
-	/* compute VelocityFactor */
-	VelocityFactor= n_man*CR*CR*rho_water*g/mu_water;
-
-	gauss=new GaussTria();
-	for(int iv=0;iv<NUMVERTICES;iv++){
-		gauss->GaussVertex(iv);
-		surfaceslopex_input->GetInputValue(&dsdx,gauss);
-		surfaceslopey_input->GetInputValue(&dsdy,gauss);
-		bedslopex_input->GetInputValue(&dbdx,gauss);
-		bedslopey_input->GetInputValue(&dbdy,gauss);
-		watercolumn_input->GetInputValue(&w,gauss);
-
-		/* Water velocity x and y components */
-	//	vx[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
-	//	vy[iv]= - w*w/(12 * mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
-		vx[iv]= - w*w/(VelocityFactor* mu_water)*(rho_ice*g*dsdx+(rho_water-rho_ice)*g*dbdx);
-		vy[iv]= - w*w/(VelocityFactor* mu_water)*(rho_ice*g*dsdy+(rho_water-rho_ice)*g*dbdy);
-	}
-
-	/*clean-up*/
-	delete gauss;
-
-	/*Add to inputs*/
-	this->inputs->AddInput(new TriaInput(HydrologyWaterVxEnum,vx,P1Enum));
-	this->inputs->AddInput(new TriaInput(HydrologyWaterVyEnum,vy,P1Enum));
-}
-/*}}}*/
-/*FUNCTION Tria::GetSolutionFromInputsOneDof{{{*/
-void  Tria::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){
+void       Tria::GetSolutionFromInputsOneDof(Vector<IssmDouble>* solution, int enum_type){/*{{{*/
 
 	int        *doflist = NULL;
@@ -4266,6 +3500,5 @@
 
 #ifdef _HAVE_DAKOTA_
-/*FUNCTION Tria::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type);{{{*/
-void  Tria::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){
+void       Tria::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){/*{{{*/
 
 	int i,j;
@@ -4358,6 +3591,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type);{{{*/
-void  Tria::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){
+void       Tria::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/
 
 	int             i,t,row;
@@ -4399,6 +3631,5 @@
 #endif
 
-/*FUNCTION Tria::MigrateGroundingLine{{{*/
-void  Tria::MigrateGroundingLine(IssmDouble* phi_ungrounding){
+void       Tria::MigrateGroundingLine(IssmDouble* phi_ungrounding){/*{{{*/
 
 	int        i,migration_style;
@@ -4466,10 +3697,10 @@
 		}
 		/*Ice sheet: if hydrostatic bed above bathymetry, ice sheet starts to unground, elso do nothing */
-		/*Change only if AgressiveMigration or if the ice sheet is in contact with the ocean*/
+		/*Change only if AggressiveMigration or if the ice sheet is in contact with the ocean*/
 		else{ // phi>0
 			bed_hydro=-density*h[i];
 			if (bed_hydro>r[i]){
 				/*Unground only if the element is connected to the ice shelf*/
-				if(migration_style==AgressiveMigrationEnum || migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){
+				if(migration_style==AggressiveMigrationEnum || migration_style==SubelementMigrationEnum || migration_style==SubelementMigration2Enum){
 					s[i]        = (1-density)*h[i];
 					b[i]        = -density*h[i];
@@ -4530,6 +3761,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::PotentialUngrounding{{{*/
-void  Tria::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){
+void       Tria::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){/*{{{*/
 
 	IssmDouble  h[NUMVERTICES],r[NUMVERTICES],gl[NUMVERTICES];
@@ -4558,6 +3788,5 @@
 }
 /*}}}*/
-/*FUNCTION Tria::UpdatePotentialUngrounding{{{*/
-int Tria::UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){
+int        Tria::UpdatePotentialUngrounding(IssmDouble* vertices_potentially_ungrounding,Vector<IssmDouble>* vec_nodes_on_iceshelf,IssmDouble* nodes_on_iceshelf){/*{{{*/
 
 	int i;
Index: /issm/trunk/src/c/classes/Elements/Tria.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/Tria.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/Tria.h	(revision 17989)
@@ -53,5 +53,6 @@
 		void        ComputeBasalStress(Vector<IssmDouble>* sigma_b);
 		void        ComputeSigmaNN();
-		void        ComputeStrainRate(Vector<IssmDouble>* eps);
+		void		   ComputeStrainRate();
+		void		   ComputeStrainRate(Vector<IssmDouble>* eps){_error_("not implemented yet");};
 		void        ComputeStressTensor();
 		void        ComputeDeviatoricStressTensor();
@@ -64,6 +65,4 @@
 		int         FiniteElement(void);
 		Element*    GetUpperElement(void){_error_("not implemented yet");};
-	  	Element*    GetLowerElement(void){_error_("not implemented yet");};
-	  	Element*    GetSurfaceElement(void){_error_("not implemented yet");};
 		Element*    GetBasalElement(void){_error_("not implemented yet");};
 		void        GetGroundedPart(int* point1,IssmDouble* fraction1, IssmDouble* fraction2,bool* mainlyfloating);
@@ -87,5 +86,5 @@
 		void        GetVerticesCoordinatesTop(IssmDouble** pxyz_list);
 		void        InputDepthAverageAtBase(int enum_type,int average_enum_type);
-		void        InputDuplicate(int original_enum,int new_enum);
+		void        InputExtrude(int enum_type){_error_("not implemented"); /*For penta only*/};
 		void        InputScale(int enum_type,IssmDouble scale_factor);
 		void        MaterialUpdateFromTemperature(void){_error_("not implemented yet");};
@@ -99,4 +98,5 @@
 		int         VelocityInterpolation();
 		int         PressureInterpolation();
+		int         TensorInterpolation();
 		IssmDouble  SurfaceArea(void);
 		void        Update(int index, IoModel* iomodel,int analysis_counter,int analysis_type,int finitelement);
@@ -108,7 +108,7 @@
 		void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum);
 		void	    GetIcefrontCoordinates(IssmDouble** pxyz_front,IssmDouble* xyz_list,int levelsetenum);
-	    void        GetNormalFromLSF(IssmDouble *pnormal);
 		bool        IsZeroLevelset(int levelset_enum);
 		bool		IsIcefront(void);
+		bool		IsFaceOnBoundary(void);
 
 		void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part);
@@ -137,5 +137,4 @@
 		#endif
 
-		IssmDouble DragCoefficientAbsGradient(void);
 		void       GradientIndexing(int* indexing,int control_index);
 		void       Gradj(Vector<IssmDouble>* gradient,int control_type,int control_index);
@@ -157,15 +156,4 @@
 		void       ControlInputSetGradient(IssmDouble* gradient,int enum_type,int control_index);
 		void       ControlToVectors(Vector<IssmPDouble>* vector_control, Vector<IssmPDouble>* vector_gradient,int control_enum);
-		IssmDouble RheologyBbarAbsGradient(void);
-		IssmDouble ThicknessAbsMisfit(void);
-		IssmDouble SurfaceAbsVelMisfit(void);
-		IssmDouble ThicknessAbsGradient(void);
-		IssmDouble ThicknessAlongGradient(void);
-		IssmDouble ThicknessAcrossGradient(void);
-		IssmDouble BalancethicknessMisfit(void);
-		IssmDouble SurfaceRelVelMisfit(void);
-		IssmDouble SurfaceLogVelMisfit(void);
-		IssmDouble SurfaceLogVxVyMisfit(void);
-		IssmDouble SurfaceAverageVelMisfit(void);
 		void       InputControlUpdate(IssmDouble scalar,bool save_parameter);
 
@@ -181,7 +169,4 @@
 		void           GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints);
 		int            GetElementType(void);
-		IssmDouble     GetXcoord(Gauss* gauss);
-		IssmDouble     GetYcoord(Gauss* gauss);
-		IssmDouble     GetZcoord(Gauss* gauss){_error_("not implemented");};
 		void           NormalSection(IssmDouble* normal,IssmDouble* xyz_list);
 		void           NormalTop(IssmDouble* normal,IssmDouble* xyz_list);
@@ -223,6 +208,4 @@
 		void UpdateConstraintsExtrudeFromBase(void);
 		void UpdateConstraintsExtrudeFromTop(void);
-
-		void           CreateHydrologyWaterVelocityInput(void);
 		/*}}}*/
 
Index: /issm/trunk/src/c/classes/Elements/TriaRef.cpp
===================================================================
--- /issm/trunk/src/c/classes/Elements/TriaRef.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/TriaRef.cpp	(revision 17989)
@@ -4,5 +4,5 @@
 
 /*Headers:*/
-/*{{{*/
+/*{{{*//*{{{*/
 #ifdef HAVE_CONFIG_H
 	#include <config.h>
@@ -22,11 +22,9 @@
 
 /*Object constructors and destructor*/
-/*FUNCTION TriaRef::TriaRef(){{{*/
-TriaRef::TriaRef(){
+TriaRef::TriaRef(){/*{{{*/
 	this->element_type_list=NULL;
 }
 /*}}}*/
-/*FUNCTION TriaRef::TriaRef(int* types,int nummodels){{{*/
-TriaRef::TriaRef(const int nummodels){
+TriaRef::TriaRef(const int nummodels){/*{{{*/
 
 	/*Only allocate pointer*/
@@ -35,6 +33,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::~TriaRef(){{{*/
-TriaRef::~TriaRef(){
+TriaRef::~TriaRef(){/*{{{*/
 	xDelete<int>(element_type_list);
 }
@@ -42,6 +39,5 @@
 
 /*Management*/
-/*FUNCTION TriaRef::SetElementType{{{*/
-void TriaRef::SetElementType(int type,int type_counter){
+void TriaRef::SetElementType(int type,int type_counter){/*{{{*/
 
 	/*initialize element type*/
@@ -51,6 +47,5 @@
 
 /*Reference Element numerics*/
-/*FUNCTION TriaRef::GetSegmentBFlux{{{*/
-void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2){
+void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2){/*{{{*/
 	/*Compute B  matrix. B=[phi1 phi2 -phi3 -phi4]
 	 *
@@ -77,6 +72,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetSegmentBprimeFlux{{{*/
-void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2){
+void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2){/*{{{*/
 	/*Compute Bprime  matrix. Bprime=[phi1 phi2 phi3 phi4]
 	 *
@@ -103,6 +97,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetJacobian{{{*/
-void TriaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss){
+void TriaRef::GetJacobian(IssmDouble* J, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*The Jacobian is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -121,6 +114,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetSegmentJacobianDeterminant{{{*/
-void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){
+void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated*/
@@ -136,6 +128,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetJacobianDeterminant{{{*/
-void TriaRef::GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){
+void TriaRef::GetJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 	/*The Jacobian determinant is constant over the element, discard the gaussian points. 
 	 * J is assumed to have been allocated of size NDOF2xNDOF2.*/
@@ -151,6 +142,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetJacobianInvert{{{*/
-void TriaRef::GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,Gauss* gauss){
+void TriaRef::GetJacobianInvert(IssmDouble*  Jinv, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/
 
 	/*Jacobian*/
@@ -165,6 +155,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){{{*/
-void TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){
+void TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -174,6 +163,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss,int finiteelement){{{*/
-void TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){
+void TriaRef::GetNodalFunctions(IssmDouble* basis,Gauss* gauss_in,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -212,105 +200,9 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsVelocity{{{*/
-void TriaRef::GetNodalFunctionsVelocity(IssmDouble* basis,Gauss* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		case XTaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = XTaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsPressure{{{*/
-void TriaRef::GetNodalFunctionsPressure(IssmDouble* basis,Gauss* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		case XTaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = XTaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsTensor{{{*/
-void TriaRef::GetNodalFunctionsTensor(IssmDouble* basis,Gauss* gauss){
-	/*This routine returns the values of the nodal functions  at the gaussian point.*/
-
-	switch(this->element_type){
-		case XTaylorHoodEnum:
-			this->element_type = P1DGEnum;
-			this->GetNodalFunctions(basis,gauss);
-			this->element_type = XTaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetSegmentNodalFunctions{{{*/
-void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2){
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
+	}
+}
+/*}}}*/
+void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2){/*{{{*/
 	/*This routine returns the values of the nodal functions  at the gaussian point.*/
 
@@ -351,6 +243,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){{{*/
-void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
+void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
 
 	GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss,this->element_type);
@@ -358,6 +249,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement){{{*/
-void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement){
+void TriaRef::GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement){/*{{{*/
 
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
@@ -389,73 +279,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivativesPressure{{{*/
-void TriaRef::GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = TaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivativesVelocity{{{*/
-void TriaRef::GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss){
-	switch(this->element_type){
-		case P1P1Enum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1Enum;
-			return;
-		case P1P1GLSEnum:
-			this->element_type = P1Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = P1P1GLSEnum;
-			return;
-		case MINIcondensedEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIcondensedEnum;
-			return;
-		case MINIEnum:
-			this->element_type = P1bubbleEnum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = MINIEnum;
-			return;
-		case TaylorHoodEnum:
-		case XTaylorHoodEnum:
-			this->element_type = P2Enum;
-			this->GetNodalFunctionsDerivatives(dbasis,xyz_list,gauss);
-			this->element_type = XTaylorHoodEnum;
-			return;
-		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss){{{*/
-void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss){
+void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -465,6 +287,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss,int finiteelement){{{*/
-void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in,int finiteelement){
+void TriaRef::GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss_in,int finiteelement){/*{{{*/
 	/*This routine returns the values of the nodal functions derivatives  (with respect to the 
 	 * natural coordinate system) at the gaussian point. */
@@ -528,11 +349,10 @@
 			return;
 		default:
-			_error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-}
-/*}}}*/
-/*FUNCTION TriaRef::GetInputDerivativeValue{{{*/
-void TriaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss){
+			_error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");
+	}
+
+}
+/*}}}*/
+void TriaRef::GetInputDerivativeValue(IssmDouble* p, IssmDouble* plist,IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
 
 	/*From node values of parameter p (plist[0],plist[1],plist[2]), return parameter derivative value at gaussian 
@@ -566,12 +386,10 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss){{{*/
-void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss){
+void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss){/*{{{*/
 
 	GetInputValue(p,plist,gauss,this->element_type);
 }
 /*}}}*/
-/*FUNCTION TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss,int finiteelement){{{*/
-void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss,int finiteelement){
+void TriaRef::GetInputValue(IssmDouble* p, IssmDouble* plist, Gauss* gauss,int finiteelement){/*{{{*/
 
 	/*Output*/
@@ -593,12 +411,10 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::NumberofNodes(){{{*/
-int TriaRef::NumberofNodes(void){
+int  TriaRef::NumberofNodes(void){/*{{{*/
 
 	return this->NumberofNodes(this->element_type);
 }
 /*}}}*/
-/*FUNCTION TriaRef::NumberofNodes(int finiteelement){{{*/
-int TriaRef::NumberofNodes(int finiteelement){
+int  TriaRef::NumberofNodes(int finiteelement){/*{{{*/
 
 	switch(finiteelement){
@@ -621,38 +437,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::NumberofNodesPressure{{{*/
-int TriaRef::NumberofNodesPressure(void){
-
-	switch(this->element_type){
-		case P1P1Enum:          return NUMNODESP1;
-		case P1P1GLSEnum:       return NUMNODESP1;
-		case MINIcondensedEnum: return NUMNODESP1;
-		case MINIEnum:          return NUMNODESP1;
-		case TaylorHoodEnum:    return NUMNODESP1;
-		case XTaylorHoodEnum:   return NUMNODESP1;
-		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-	return -1;
-}
-/*}}}*/
-/*FUNCTION TriaRef::NumberofNodesVelocity{{{*/
-int TriaRef::NumberofNodesVelocity(void){
-
-	switch(this->element_type){
-		case P1P1Enum:          return NUMNODESP1;
-		case P1P1GLSEnum:       return NUMNODESP1;
-		case MINIcondensedEnum: return NUMNODESP1b;
-		case MINIEnum:          return NUMNODESP1b;
-		case TaylorHoodEnum:    return NUMNODESP2;
-		case XTaylorHoodEnum:   return NUMNODESP2;
-		default:       _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
-	}
-
-	return -1;
-}
-/*}}}*/
-/*FUNCTION TriaRef::VelocityInterpolation{{{*/
-int TriaRef::VelocityInterpolation(void){
+int  TriaRef::VelocityInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -669,6 +452,5 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::PressureInterpolation{{{*/
-int TriaRef::PressureInterpolation(void){
+int  TriaRef::PressureInterpolation(void){/*{{{*/
 
 	switch(this->element_type){
@@ -685,6 +467,14 @@
 }
 /*}}}*/
-/*FUNCTION TriaRef::NodeOnEdgeIndices{{{*/
-void TriaRef::NodeOnEdgeIndices(int* pnumindices,int** pindices,int index,int finiteelement){
+int  TriaRef::TensorInterpolation(void){/*{{{*/
+	/*This routine returns the values of the nodal functions  at the gaussian point.*/
+
+	switch(this->element_type){
+		case XTaylorHoodEnum: return P1DGEnum;
+		default: _error_("Element type "<<EnumToStringx(this->element_type)<<" not supported yet");
+	}
+}
+/*}}}*/
+void TriaRef::NodeOnEdgeIndices(int* pnumindices,int** pindices,int index,int finiteelement){/*{{{*/
 
 	/*Output*/
Index: /issm/trunk/src/c/classes/Elements/TriaRef.h
===================================================================
--- /issm/trunk/src/c/classes/Elements/TriaRef.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Elements/TriaRef.h	(revision 17989)
@@ -29,7 +29,4 @@
 		void GetNodalFunctions(IssmDouble* basis,Gauss* gauss);
 		void GetNodalFunctions(IssmDouble* basis,Gauss* gauss,int finiteelement);
-		void GetNodalFunctionsVelocity(IssmDouble* basis, Gauss* gauss);
-		void GetNodalFunctionsPressure(IssmDouble* basis, Gauss* gauss);
-		void GetNodalFunctionsTensor(IssmDouble* basis, Gauss* gauss);
 		void GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss, int index1,int index2);
 		void GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2);
@@ -37,6 +34,4 @@
 		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss);
 		void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, Gauss* gauss,int finiteelement);
-		void GetNodalFunctionsDerivativesVelocity(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
-		void GetNodalFunctionsDerivativesPressure(IssmDouble* dbasis,IssmDouble* xyz_list,Gauss* gauss);
 		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss);
 		void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,Gauss* gauss,int finiteelement);
@@ -48,8 +43,7 @@
 		int  NumberofNodes(void);
 		int  NumberofNodes(int finiteelement);
-		int  NumberofNodesVelocity(void);
-		int  NumberofNodesPressure(void);
 		int  VelocityInterpolation(void);
 		int  PressureInterpolation(void);
+		int  TensorInterpolation(void);
 };
 #endif
Index: /issm/trunk/src/c/classes/FemModel.cpp
===================================================================
--- /issm/trunk/src/c/classes/FemModel.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/FemModel.cpp	(revision 17989)
@@ -1134,33 +1134,59 @@
 void FemModel::BalancethicknessMisfitx(IssmDouble* presponse){/*{{{*/
 
-	IssmDouble J = 0;
+	/*output: */
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
-	for(int i=0;i<this->elements->Size();i++){
-		Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
-		J+=element->BalancethicknessMisfit();
-	}
-	ISSM_MPI_Reduce (&J,&J_sum,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
-	ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
-	J=J_sum;
-
-	/*Assign output pointers: */
-	*presponse=J;
-
-}/*}}}*/
-void FemModel::ThicknessAbsGradientx( IssmDouble* pJ){/*{{{*/
-
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
-	/*output: */
-	IssmDouble J=0;
-	IssmDouble J_sum;
+	IssmDouble  weight,vx,vy,H,dvx[2],dvy[2],dH[2];
+	IssmDouble  temp,Jdet,dhdt,basal_melting,surface_mass_balance;
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  dp[3];
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->ThicknessAbsGradient();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+
+		/*If on water, return 0: */
+		if(!element->IsIceInElement()) continue;
+
+		/* Get node coordinates*/
+		element->GetVerticesCoordinates(&xyz_list);
+		Input* weights_input              = element->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
+		Input* thickness_input            = element->GetInput(ThicknessEnum); _assert_(thickness_input);
+		Input* vx_input                   = element->GetInput(VxEnum);                                 _assert_(vx_input);
+		Input* vy_input                   = element->GetInput(VyEnum);                                 _assert_(vy_input);
+		Input* surface_mass_balance_input = element->GetInput(SurfaceforcingsMassBalanceEnum);         _assert_(surface_mass_balance_input);
+		Input* basal_melting_input        = element->GetInput(BasalforcingsMeltingRateEnum);           _assert_(basal_melting_input);
+		Input* dhdt_input                 = element->GetInput(BalancethicknessThickeningRateEnum);     _assert_(dhdt_input);
+
+		/* Start  looping on the number of gaussian points: */
+		Gauss* gauss=element->NewGauss(2);
+		for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+			gauss->GaussPoint(ig);
+
+			/* Get Jacobian determinant: */
+			element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+			/*Get all parameters at gaussian point*/
+			weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum);
+			thickness_input->GetInputValue(&H, gauss);
+			thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss);
+			surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss);
+			basal_melting_input->GetInputValue(&basal_melting,gauss);
+			dhdt_input->GetInputValue(&dhdt,gauss);
+			vx_input->GetInputValue(&vx,gauss);
+			vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
+			vy_input->GetInputValue(&vy,gauss);
+			vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
+
+			/*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/
+			temp  = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-basal_melting-dhdt);
+			J    +=weight*1/2*temp*temp*Jdet*gauss->weight;
+		}
+
+		/*clean up and Return: */
+		xDelete<IssmDouble>(xyz_list);
+		delete gauss;
 	}
 
@@ -1171,8 +1197,64 @@
 
 	/*Assign output pointers: */
+	*presponse=J;
+
+}/*}}}*/
+void FemModel::ThicknessAbsGradientx( IssmDouble* pJ){/*{{{*/
+
+	/*output: */
+	IssmDouble J=0.;
+	IssmDouble J_sum;
+
+	IssmDouble  thickness,thicknessobs,weight;
+	IssmDouble  Jdet;
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  dp[3];
+
+	/*Compute Misfit: */
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+
+		/*If on water, return 0: */
+		if(!element->IsIceInElement()) continue;
+
+		/* Get node coordinates*/
+		element->GetVerticesCoordinates(&xyz_list);
+
+		/*Retrieve all inputs we will be needing: */
+		Input* weights_input   =element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+		Input* thickness_input =element->GetInput(ThicknessEnum);                          _assert_(thickness_input);
+
+		/* Start  looping on the number of gaussian points: */
+		Gauss* gauss=element->NewGauss(2);
+		for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+			gauss->GaussPoint(ig);
+
+			/* Get Jacobian determinant: */
+			element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+			/*Get all parameters at gaussian point*/
+			weights_input->GetInputValue(&weight,gauss,ThicknessAcrossGradientEnum);
+			thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
+
+			/*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
+			J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
+		}
+
+		/*clean up and Return: */
+		xDelete<IssmDouble>(xyz_list);
+		delete gauss;
+	}
+
+	/*Sum all J from all cpus of the cluster:*/
+	ISSM_MPI_Reduce (&J,&J_sum,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
+	ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
+	J=J_sum;
+
+	/*Assign output pointers: */
 	*pJ=J;
 }
 /*}}}*/
-void FemModel::CostFunctionx(IssmDouble* pJ){/*{{{*/
+void FemModel::CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn){/*{{{*/
 
 	/*Intermediary*/
@@ -1188,13 +1270,12 @@
 	this->RequestedOutputsx(&cost_functions,responses,num_responses);
 
-	/*Add all contributions one by one*/
-	IssmDouble J=0;
-	//_printf0_("list of misfits: ");
+	/*Get and add all contributions one by one*/
+	IssmDouble  J=0;
+	IssmDouble* Jlist = xNew<IssmDouble>(num_responses);
 	for(int i=0;i<num_responses;i++){
 		ExternalResult* result=(ExternalResult*)cost_functions->GetObjectByOffset(i);
-		J += reCast<IssmDouble>(result->GetValue());
-		//_printf0_(J<<" ");
-	}
-	//_printf0_(" \n");
+		Jlist[i] = reCast<IssmDouble>(result->GetValue());
+		J       += Jlist[i];
+	}
 	_assert_(cost_functions->Size()==num_responses);
 
@@ -1202,5 +1283,8 @@
 	delete cost_functions;
 	xDelete<int>(responses);
-	*pJ=J;
+	if(pJ)     *pJ     = J;
+	if(pJlist) *pJlist = Jlist;
+	else        xDelete<IssmDouble>(Jlist);
+	if(pn)     *pn     = num_responses;
 }
 /*}}}*/
Index: /issm/trunk/src/c/classes/FemModel.h
===================================================================
--- /issm/trunk/src/c/classes/FemModel.h	(revision 17988)
+++ /issm/trunk/src/c/classes/FemModel.h	(revision 17989)
@@ -86,5 +86,5 @@
 		void Responsex(IssmDouble* presponse,const char* response_descriptor);
 		void OutputControlsx(Results **presults);
-		void CostFunctionx( IssmDouble* pJ);
+		void CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn);
 		void ThicknessAbsGradientx( IssmDouble* pJ);
 		#ifdef _HAVE_GIA_
Index: /issm/trunk/src/c/classes/IoModel.cpp
===================================================================
--- /issm/trunk/src/c/classes/IoModel.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/IoModel.cpp	(revision 17989)
@@ -37,4 +37,5 @@
 	this->numberoffaces=-1;
 	this->numberofedges=-1;
+	this->facescols=-1;
 	this->elements=NULL;
 	this->faces=NULL;
@@ -83,4 +84,5 @@
 	FetchData(&this->numberofelements,MeshNumberofelementsEnum);
 	FetchData(&this->elements,NULL,NULL,MeshElementsEnum);
+	this->facescols                       = -1;
 	this->faces                           = NULL;
 	this->edges                           = NULL;
@@ -284,5 +286,4 @@
 void IoModel::StartTrace(void){
 
-	int  i;
 	bool autodiff = false;
 	bool keep=false;
Index: /issm/trunk/src/c/classes/IoModel.h
===================================================================
--- /issm/trunk/src/c/classes/IoModel.h	(revision 17988)
+++ /issm/trunk/src/c/classes/IoModel.h	(revision 17989)
@@ -38,4 +38,5 @@
 		int  numberoffaces;
 		int  numberofedges;
+		int  facescols;
 		int *elements;
 		int *faces;
Index: /issm/trunk/src/c/classes/Loads/Friction.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Friction.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Loads/Friction.cpp	(revision 17989)
@@ -20,4 +20,6 @@
 	this->element=NULL;
 	this->dim=0;
+	this->law=0;
+
 }
 /*}}}*/
@@ -27,4 +29,5 @@
 	this->element=element_in;
 	this->dim=dim_in;
+	element_in->FindParam(&this->law,FrictionLawEnum);
 }
 /*}}}*/
@@ -42,8 +45,23 @@
 /*}}}*/
 /*FUNCTION Friction::GetAlpha2{{{*/
-void Friction::GetAlpha2(IssmDouble* palpha2, Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){
+void Friction::GetAlpha2(IssmDouble* palpha2, Gauss* gauss){
+
+	switch(this->law){
+		case 1:
+			GetAlpha2Viscous(palpha2,gauss);
+			break;
+		case 2:
+			GetAlpha2Weertman(palpha2,gauss);
+			break;
+		default:
+			_error_("not supported");
+	}
+
+}/*}}}*/
+/*FUNCTION Friction::GetAlpha2{{{*/
+void Friction::GetAlpha2Viscous(IssmDouble* palpha2, Gauss* gauss){
 
 	/*This routine calculates the basal friction coefficient 
-	  alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p**/
+	  alpha2= drag^2 * Neff ^r * | vel | ^(s-1), with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p**/
 
 	/*diverse: */
@@ -62,5 +80,5 @@
 	element->GetInputValue(&bed, gauss,BaseEnum);
 	element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
-	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
@@ -76,16 +94,16 @@
 	switch(dim){
 		case 1:
-			vx_input->GetInputValue(&vx,gauss);
+			element->GetInputValue(&vx,gauss,VxEnum);
 			vmag=sqrt(vx*vx);
 			break;
 		case 2:
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
+			element->GetInputValue(&vx,gauss,VxEnum);
+			element->GetInputValue(&vy,gauss,VyEnum);
 			vmag=sqrt(vx*vx+vy*vy);
 			break;
 		case 3:
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
-			vz_input->GetInputValue(&vz,gauss);
+			element->GetInputValue(&vx,gauss,VxEnum);
+			element->GetInputValue(&vy,gauss,VyEnum);
+			element->GetInputValue(&vz,gauss,VzEnum);
 			vmag=sqrt(vx*vx+vy*vy+vz*vz);
 			break;
@@ -94,20 +112,62 @@
 	}
 
-	/*Checks that s-1>0 if v=0*/
-	if(vmag==0. && (s-1.)<0.) _error_("velocity is 0 and (s-1)=" << (s-1.) << "<0, alpha2 is Inf");
-
-	alpha2=drag_coefficient*drag_coefficient*pow(Neff,r)*pow(vmag,(s-1.));
+	/*Check to prevent dividing by zero if vmag==0*/
+	if(vmag==0. && (s-1.)<0.) alpha2=0.;
+	else alpha2=drag_coefficient*drag_coefficient*pow(Neff,r)*pow(vmag,(s-1.));
 	_assert_(!xIsNan<IssmDouble>(alpha2));
 
 	/*Assign output pointers:*/
 	*palpha2=alpha2;
-}
-/*}}}*/
+}/*}}}*/
+/*FUNCTION Friction::GetAlpha2Weertman{{{*/
+void Friction::GetAlpha2Weertman(IssmDouble* palpha2, Gauss* gauss){
+
+	/*This routine calculates the basal friction coefficient alpha2= C^-1/m |v|^(1/m-1) */
+
+	/*diverse: */
+	IssmDouble  C,m;
+	IssmDouble  vx,vy,vz,vmag;
+	IssmDouble  alpha2;
+
+	/*Recover parameters: */
+	element->GetInputValue(&C,gauss,FrictionCEnum);
+	element->GetInputValue(&m,FrictionMEnum);
+
+	switch(dim){
+		case 1:
+			element->GetInputValue(&vx,gauss,VxEnum);
+			vmag=sqrt(vx*vx);
+			break;
+		case 2:
+			element->GetInputValue(&vx,gauss,VxEnum);
+			element->GetInputValue(&vy,gauss,VyEnum);
+			vmag=sqrt(vx*vx+vy*vy);
+			break;
+		case 3:
+			element->GetInputValue(&vx,gauss,VxEnum);
+			element->GetInputValue(&vy,gauss,VyEnum);
+			element->GetInputValue(&vz,gauss,VzEnum);
+			vmag=sqrt(vx*vx+vy*vy+vz*vz);
+			break;
+		default:
+			_error_("not supported");
+	}
+
+	/*Check to prevent dividing by zero if vmag==0*/
+	if(vmag==0. && (1./m-1.)<0.) alpha2=0.;
+	else alpha2=pow(C,-1./m)*pow(vmag,(1./m-1.));
+	_assert_(!xIsNan<IssmDouble>(alpha2));
+
+	/*Assign output pointers:*/
+	*palpha2=alpha2;
+}/*}}}*/
 /*FUNCTION Friction::GetAlphaComplement(IssmDouble* palpha_complement, Gauss* gauss,int vxenum,int vyenum,int vzenum) {{{*/
-void Friction::GetAlphaComplement(IssmDouble* palpha_complement, Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){
+void Friction::GetAlphaComplement(IssmDouble* palpha_complement, Gauss* gauss){
 
 	/* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p. 
 	 * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 
 	 * alpha_complement= Neff ^r * vel ^s*/
+
+	if(this->law!=1)_error_("not supported");
 
 	/*diverse: */
@@ -126,5 +186,5 @@
 	element->GetInputValue(&bed, gauss,BaseEnum);
 	element->GetInputValue(&drag_coefficient, gauss,FrictionCoefficientEnum);
-	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoWaterEnum);
+	IssmDouble rho_water   = element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
 	IssmDouble rho_ice     = element->GetMaterialParameter(MaterialsRhoIceEnum);
 	IssmDouble gravity     = element->GetMaterialParameter(ConstantsGEnum);
@@ -141,16 +201,16 @@
 	switch(dim){
 		case 1:
-			vx_input->GetInputValue(&vx,gauss);
+			element->GetInputValue(&vx,gauss,VxEnum);
 			vmag=sqrt(vx*vx);
 			break;
 		case 2:
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
+			element->GetInputValue(&vx,gauss,VxEnum);
+			element->GetInputValue(&vy,gauss,VyEnum);
 			vmag=sqrt(vx*vx+vy*vy);
 			break;
 		case 3:
-			vx_input->GetInputValue(&vx,gauss);
-			vy_input->GetInputValue(&vy,gauss);
-			vz_input->GetInputValue(&vz,gauss);
+			element->GetInputValue(&vx,gauss,VxEnum);
+			element->GetInputValue(&vy,gauss,VyEnum);
+			element->GetInputValue(&vz,gauss,VzEnum);
 			vmag=sqrt(vx*vx+vy*vy+vz*vz);
 			break;
@@ -159,8 +219,7 @@
 	}
 
-	/*Checks that s-1>0 if v=0*/
-	if(vmag==0. && (s-1.)<0.) _error_("velocity is 0 and (s-1)=" << (s-1.) << "<0, alpha2 is Inf");
-
-	alpha_complement=pow(Neff,r)*pow(vmag,(s-1));_assert_(!xIsNan<IssmDouble>(alpha_complement));
+	/*Check to prevent dividing by zero if vmag==0*/
+	if(vmag==0. && (s-1.)<0.) alpha_complement=0.;
+	else alpha_complement=pow(Neff,r)*pow(vmag,(s-1));_assert_(!xIsNan<IssmDouble>(alpha_complement));
 
 	/*Assign output pointers:*/
Index: /issm/trunk/src/c/classes/Loads/Friction.h
===================================================================
--- /issm/trunk/src/c/classes/Loads/Friction.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Loads/Friction.h	(revision 17989)
@@ -21,4 +21,5 @@
 		Element* element;
 		int      dim;
+		int      law;
 
 		/*methods: */
@@ -28,6 +29,8 @@
 
 		void  Echo(void);
-		void  GetAlpha2(IssmDouble* palpha2, Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
-		void  GetAlphaComplement(IssmDouble* alpha_complement,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input);
+		void  GetAlpha2(IssmDouble* palpha2,Gauss* gauss);
+		void  GetAlpha2Viscous(IssmDouble* palpha2,Gauss* gauss);
+		void  GetAlpha2Weertman(IssmDouble* palpha2,Gauss* gauss);
+		void  GetAlphaComplement(IssmDouble* alpha_complement,Gauss* gauss);
 };
 
Index: /issm/trunk/src/c/classes/Loads/Pengrid.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Pengrid.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Loads/Pengrid.cpp	(revision 17989)
@@ -646,5 +646,5 @@
 		if(zigzag_counter>penalty_lock){
 			unstable=0;
-			active=0;
+			active=1;
 		}
 	}
Index: /issm/trunk/src/c/classes/Loads/Riftfront.cpp
===================================================================
--- /issm/trunk/src/c/classes/Loads/Riftfront.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Loads/Riftfront.cpp	(revision 17989)
@@ -39,9 +39,6 @@
 	int    riftfront_elem_ids[2];
 	int    riftfront_matpar_id;
-	int    riftfront_type;
-	int    riftfront_fill;
 	IssmDouble riftfront_friction;
 	IssmDouble riftfront_fractionincrement;
-	bool   riftfront_shelf;
 	int    penalty_lock;
 
Index: /issm/trunk/src/c/classes/Massfluxatgate.h
===================================================================
--- /issm/trunk/src/c/classes/Massfluxatgate.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Massfluxatgate.h	(revision 17989)
@@ -31,7 +31,7 @@
 		/*FUNCTION Massfluxatgate() {{{*/
 		Massfluxatgate(){
-			this->name     = 0;
-			this->numsegments     = 0;
-			this->segments   = 0;
+			this->name        = 0;
+			this->numsegments = 0;
+			this->segments    = 0;
 		}
 		/*}}}*/
Index: /issm/trunk/src/c/classes/Materials/Material.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Material.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Materials/Material.h	(revision 17989)
@@ -30,5 +30,4 @@
 		virtual void       GetViscosityDComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon)=0;
 		virtual void       GetViscosityDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon)=0;
-		virtual void       GetViscosityDerivativeEpsSquareFS(IssmDouble* pmu_prime, IssmDouble* pepsilon)=0;
 		virtual void       GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon)=0;
 		virtual IssmDouble GetA()=0;
Index: /issm/trunk/src/c/classes/Materials/Matice.cpp
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matice.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Materials/Matice.cpp	(revision 17989)
@@ -31,5 +31,4 @@
 	this->helement=NULL;
 	this->element=NULL;
-	this->isdamaged=NULL;
 	return;
 }
@@ -109,4 +108,5 @@
 	matice->helement=(Hook*)this->helement->copy();
 	matice->element =(Element*)this->helement->delivers();
+	matice->isdamaged = this->isdamaged;
 
 	return matice;
@@ -126,4 +126,5 @@
 	matice->helement=(Hook*)this->helement->copy();
 	matice->element =element_in;
+	matice->isdamaged = this->isdamaged;
 
 	return matice;
@@ -484,37 +485,4 @@
 }
 /*}}}*/
-/*FUNCTION Matice::GetViscosityDerivativeEpsSquareFS{{{*/
-void  Matice::GetViscosityDerivativeEpsSquareFS(IssmDouble* pmu_prime, IssmDouble* epsilon){
-
-	/*output: */
-	IssmDouble mu_prime;
-	IssmDouble mu,n,eff2;
-
-	/*input strain rate: */
-	IssmDouble exx,eyy,exy,exz,eyz,ezz;
-
-	if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 
-				(epsilon[3]==0) && (epsilon[4]==0) && (epsilon[5]==0)){
-		mu_prime=0.5*pow(10.,14);
-	}
-	else{
-		/*Retrive strain rate components: */
-		exx=epsilon[0];
-		eyy=epsilon[1];
-		ezz=epsilon[2];
-		exy=epsilon[3];
-		exz=epsilon[4];
-		eyz=epsilon[5];
-		eff2 = exx*exx + eyy*eyy + exx*eyy + exy*exy + exz*exz + eyz*eyz;
-
-		GetViscosity(&mu,sqrt(eff2));
-		n=GetN();
-		mu_prime=(1-n)/(2*n) * mu/eff2;
-	}
-
-	/*Assign output pointers:*/
-	*pmu_prime=mu_prime;
-}
-/*}}}*/
 /*FUNCTION Matice::GetViscosity2dDerivativeEpsSquare{{{*/
 void  Matice::GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* epsilon){
Index: /issm/trunk/src/c/classes/Materials/Matice.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matice.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Materials/Matice.h	(revision 17989)
@@ -59,5 +59,4 @@
 		void       GetViscosityDComplement(IssmDouble*, IssmDouble*);
 		void       GetViscosityDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon);
-		void       GetViscosityDerivativeEpsSquareFS(IssmDouble* pmu_prime, IssmDouble* pepsilon);
 		void       GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon);
 		IssmDouble GetA();
Index: /issm/trunk/src/c/classes/Materials/Matpar.cpp
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matpar.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/Materials/Matpar.cpp	(revision 17989)
@@ -21,5 +21,4 @@
 Matpar::Matpar(int matpar_mid, IoModel* iomodel){
 
-	bool ispdd;
 	bool isefficientlayer;
 	int  hydrology_model,smb_model;
@@ -29,5 +28,5 @@
 	this->mid = matpar_mid;
 	iomodel->Constant(&this->rho_ice,MaterialsRhoIceEnum);
-	iomodel->Constant(&this->rho_water,MaterialsRhoWaterEnum);
+	iomodel->Constant(&this->rho_water,MaterialsRhoSeawaterEnum);
 	iomodel->Constant(&this->rho_freshwater,MaterialsRhoFreshwaterEnum);
 	iomodel->Constant(&this->mu_water,MaterialsMuWaterEnum);
@@ -60,13 +59,5 @@
 			_error_("Surface mass balance model "<<EnumToStringx(smb_model)<<" not supported yet");
 	}
-
-	if(hydrology_model==HydrologyshreveEnum){
-		iomodel->Constant(&this->hydro_CR,HydrologyshreveCREnum);
-		iomodel->Constant(&this->hydro_kn,HydrologyshreveKnEnum);
-		iomodel->Constant(&this->hydro_n,HydrologyshreveNEnum);
-		iomodel->Constant(&this->hydro_p,HydrologyshrevePEnum);
-		iomodel->Constant(&this->hydro_q,HydrologyshreveQEnum);
-	}
-	else if(hydrology_model==HydrologydcEnum){
+	if(hydrology_model==HydrologydcEnum){
 		iomodel->Constant(&this->sediment_compressibility,HydrologydcSedimentCompressibilityEnum);
 		iomodel->Constant(&this->sediment_porosity,HydrologydcSedimentPorosityEnum);
@@ -82,4 +73,7 @@
 				iomodel->Constant(&this->epl_conductivity,HydrologydcEplConductivityEnum);
 		}
+	}
+	else if(hydrology_model==HydrologyshreveEnum){
+		/*Nothing to add*/
 	}
 	else{
@@ -170,5 +164,5 @@
 			this->rho_ice=constant;
 			break;
-		case MaterialsRhoWaterEnum:
+		case MaterialsRhoSeawaterEnum:
 			this->rho_water=constant;
 			break;
@@ -245,5 +239,5 @@
 	switch(enum_in){
 		case MaterialsRhoIceEnum:                    return this->rho_ice;
-		case MaterialsRhoWaterEnum:                  return this->rho_water;
+		case MaterialsRhoSeawaterEnum:                  return this->rho_water;
 		case MaterialsRhoFreshwaterEnum:             return this->rho_freshwater;
 		case MaterialsMuWaterEnum:                   return this->mu_water;
@@ -266,9 +260,4 @@
 		case HydrologydcEplMaxThicknessEnum:         return this->epl_max_thickness;
 		case HydrologydcWaterCompressibilityEnum:    return this->water_compressibility;
-		case HydrologyshreveCREnum:                  return this->hydro_CR;
-		case HydrologyshreveKnEnum:                  return this->hydro_kn;
-		case HydrologyshreveNEnum:                   return this->hydro_n;
-		case HydrologyshrevePEnum:                   return this->hydro_p;
-		case HydrologyshreveQEnum:                   return this->hydro_q;
 		case ConstantsGEnum:                         return this->g;
 		default: _error_("Enum "<<EnumToStringx(enum_in)<<" not supported yet");
@@ -287,14 +276,4 @@
 }
 /*}}}*/
-/*FUNCTION Matpar::GetHeatCapacity {{{*/
-IssmDouble Matpar::GetHeatCapacity(){
-	return heatcapacity;
-}
-/*}}}*/
-/*FUNCTION Matpar::GetLatentHeat {{{*/
-IssmDouble Matpar::GetLatentHeat(){
-	return latentheat;
-}
-/*}}}*/
 /*FUNCTION Matpar::GetMeltingPoint {{{*/
 IssmDouble Matpar::GetMeltingPoint(){
@@ -302,14 +281,4 @@
 }
 /*}}}*/
-/*FUNCTION Matpar::GetReferenceTemperature {{{*/
-IssmDouble Matpar::GetReferenceTemperature(){
-	return referencetemperature;
-}
-/*}}}*/
-/*FUNCTION Matpar::GetMixedLayerCapacity {{{*/
-IssmDouble Matpar::GetMixedLayerCapacity(){
-	return mixed_layer_capacity;
-}
-/*}}}*/
 /*FUNCTION Matpar::GetRhoIce {{{*/
 IssmDouble Matpar::GetRhoIce(){
@@ -328,9 +297,4 @@
 }
 /*}}}*/
-/*FUNCTION Matpar::GetMuWater {{{*/
-IssmDouble Matpar::GetMuWater(){
-	return mu_water;
-}
-/*}}}*/
 /*FUNCTION Matpar::GetDesFac {{{*/
 IssmDouble Matpar::GetDesFac(){
@@ -343,76 +307,4 @@
 }
 /*}}}*/
-/*FUNCTION Matpar::GetThermalConductivity {{{*/
-IssmDouble Matpar::GetThermalConductivity(){
-	return thermalconductivity;
-}
-/*}}}*/
-/*FUNCTION Matpar::GetTemperateIceConductivity {{{*/
-IssmDouble Matpar::GetTemperateIceConductivity(){
-	return temperateiceconductivity;
-}
-/*}}}*/
-/*FUNCTION Matpar::GetThermalExchangeVelocity {{{*/
-IssmDouble Matpar::GetThermalExchangeVelocity(){
-	return thermal_exchange_velocity;
-}
-/*}}}*/
-/*FUNCTION Matpar::GetHydrologyKn {{{*/
-IssmDouble Matpar::GetHydrologyKn(){
-	return hydro_kn;		 
-}		 
-/*}}}*/			 
-/*FUNCTION Matpar::GetHydrologyP {{{*/			 
-IssmDouble Matpar::GetHydrologyP(){		 
-	return hydro_p;			 
-}		 
-/*}}}*/			 
-/*FUNCTION Matqar::GetHydrologyQ {{{*/			 
-IssmDouble Matpar::GetHydrologyQ(){		 
-	return hydro_q;			 
-}		 
-/*}}}*/			 
-/*FUNCTION Matpar::GetHydrologyCR {{{*/		 
-IssmDouble Matpar::GetHydrologyCR(){		 
-	return hydro_CR;		 
-}		 
-/*}}}*/			 
-/*FUNCTION Matpar::GetHydrologyN {{{*/			 
-IssmDouble Matpar::GetHydrologyN(){		 
-	return hydro_n;			 
-}		 
-/*}}}*/ 
-/*FUNCTION Matpar::GetSedimentStoring {{{*/
-IssmDouble Matpar::GetSedimentStoring(){
-	return this->rho_freshwater * this->g * this->sediment_porosity * this->sediment_thickness *
-    (this->water_compressibility + (this->sediment_compressibility / this->sediment_porosity));		 
-}		 
-/*}}}*/ 
-/*FUNCTION Matpar::GetEplSpecificStoring {{{*/
-IssmDouble Matpar::GetEplSpecificStoring(){
-	return this->rho_freshwater * this->g * this->epl_porosity * 
-    (this->water_compressibility + (this->epl_compressibility / this->epl_porosity));		 
-}		 	 
-/*}}}*/ 
-/*FUNCTION Matpar::GetSedimentThickness {{{*/
-IssmDouble Matpar::GetSedimentThickness(){
-	return sediment_thickness;		 
-}		 
-/*}}}*/	
-/*FUNCTION Matpar::GetEplInitialThickness {{{*/
-IssmDouble Matpar::GetEplInitialThickness(){
-	return epl_init_thickness;		 
-}		 
-/*}}}*/	
-/*FUNCTION Matpar::GetEplMaxThickness {{{*/
-IssmDouble Matpar::GetEplMaxThickness(){
-	return epl_max_thickness;		 
-}		 
-/*}}}*/	
-/*FUNCTION Matpar::GetEplConductivity {{{*/
-IssmDouble Matpar::GetEplConductivity(){
-	return epl_conductivity;		 
-}		 
-/*}}}*/			 
 /*FUNCTION Matpar::TMeltingPoint {{{*/
 IssmDouble Matpar::TMeltingPoint(IssmDouble pressure){
Index: /issm/trunk/src/c/classes/Materials/Matpar.h
===================================================================
--- /issm/trunk/src/c/classes/Materials/Matpar.h	(revision 17988)
+++ /issm/trunk/src/c/classes/Materials/Matpar.h	(revision 17989)
@@ -32,11 +32,4 @@
 		IssmDouble  desfac;
 		IssmDouble  s0p;
-
-		/*hydrology Shreve: */	 
-		IssmDouble  hydro_kn;			 
-		IssmDouble  hydro_p;		 
-		IssmDouble  hydro_q;		 
-		IssmDouble  hydro_CR;			 
-		IssmDouble  hydro_n; 
 
 		/*hydrology Dual Porous Continuum: */	 
@@ -87,5 +80,4 @@
 		void       GetViscosityDComplement(IssmDouble* pviscosity_complement, IssmDouble* pepsilon){_error_("not supported");};
 		void       GetViscosityDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon){_error_("not supported");};
-		void       GetViscosityDerivativeEpsSquareFS(IssmDouble* pmu_prime, IssmDouble* pepsilon){_error_("not supported");};
 		void       GetViscosity2dDerivativeEpsSquare(IssmDouble* pmu_prime, IssmDouble* pepsilon){_error_("not supported");};
 		IssmDouble GetA(){_error_("not supported");};
@@ -103,25 +95,6 @@
 		IssmDouble GetRhoWater();
 		IssmDouble GetRhoFreshwater();
-		IssmDouble GetMuWater();
-		IssmDouble GetMixedLayerCapacity();
-		IssmDouble GetThermalExchangeVelocity();
-		IssmDouble GetHeatCapacity();
-		IssmDouble GetThermalConductivity();
-		IssmDouble GetTemperateIceConductivity();
-		IssmDouble GetLatentHeat();
 		IssmDouble GetBeta();
 		IssmDouble GetMeltingPoint();
-		IssmDouble GetReferenceTemperature();
-		IssmDouble GetHydrologyKn();
-		IssmDouble GetHydrologyP();
-		IssmDouble GetHydrologyQ();
-		IssmDouble GetHydrologyCR();
-		IssmDouble GetHydrologyN();
-		IssmDouble GetSedimentStoring();
-		IssmDouble GetEplSpecificStoring();
-		IssmDouble GetSedimentThickness();
-		IssmDouble GetEplConductivity();
-		IssmDouble GetEplInitialThickness();
-		IssmDouble GetEplMaxThickness();
 		IssmDouble TMeltingPoint(IssmDouble pressure);
 		IssmDouble PureIceEnthalpy(IssmDouble pressure);
Index: /issm/trunk/src/c/classes/gauss/GaussTetra.cpp
===================================================================
--- /issm/trunk/src/c/classes/gauss/GaussTetra.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/gauss/GaussTetra.cpp	(revision 17989)
@@ -33,7 +33,21 @@
 /*FUNCTION GaussTetra::GaussTetra(int order) {{{*/
 GaussTetra::GaussTetra(int order){
+
 	/*Get gauss points*/
 	GaussLegendreTetra(&numgauss,&coords1,&coords2,&coords3,&coords4,&weights,order);
-	for(int i=0;i<numgauss;i++) this->weights[i]=this->weights[i]/6.; //FIXME: double check that
+
+	/*Rescale weights if necessary*/
+	IssmDouble sumweights = 0.;
+	for(int i=0;i<numgauss;i++) sumweights += this->weights[i];
+	if(sumweights==1.){
+		for(int i=0;i<numgauss;i++) this->weights[i] = this->weights[i]/6.; /*rescale volume to 1/6*/
+	}
+
+	/*Check final weights in debugging mode*/
+	#ifdef _ISSM_DEBUG_
+	sumweights = 0.; for(int i=0;i<numgauss;i++) sumweights += this->weights[i];
+	_assert_(sumweights>1./6.-1e-10);
+	_assert_(sumweights<1./6.+1e-10);
+	#endif
 
 	/*Initialize static fields as undefinite*/
Index: /issm/trunk/src/c/classes/kriging/Observations.cpp
===================================================================
--- /issm/trunk/src/c/classes/kriging/Observations.cpp	(revision 17988)
+++ /issm/trunk/src/c/classes/kriging/Observations.cpp	(revision 17989)
@@ -353,5 +353,4 @@
 	int           i,j,n_obs;
 	IssmPDouble   prediction,error;
-	IssmPDouble   numerator,denominator,ratio;
 	IssmPDouble  *x      = NULL;
 	IssmPDouble  *y      = NULL;
Index: /issm/trunk/src/c/cores/AdjointCorePointerFromSolutionEnum.cpp
===================================================================
--- /issm/trunk/src/c/cores/AdjointCorePointerFromSolutionEnum.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/AdjointCorePointerFromSolutionEnum.cpp	(revision 17989)
@@ -32,4 +32,7 @@
 			adjointcore=&adjointbalancethickness_core;
 			break;
+		case Balancethickness2SolutionEnum:
+			adjointcore=&adjointbalancethickness2_core;
+			break;
 		case BalancethicknessSoftSolutionEnum:
 			adjointcore=&dummy_core;
Index: /issm/trunk/src/c/cores/AnalysisConfiguration.cpp
===================================================================
--- /issm/trunk/src/c/cores/AnalysisConfiguration.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/AnalysisConfiguration.cpp	(revision 17989)
@@ -78,4 +78,10 @@
 			break;
 
+		case Balancethickness2SolutionEnum:
+			numanalyses=1;
+			analyses=xNew<int>(numanalyses);
+			analyses[0]=Balancethickness2AnalysisEnum;
+			break;
+
 		case BalancethicknessSoftSolutionEnum:
 			numanalyses=1;
Index: /issm/trunk/src/c/cores/CorePointerFromSolutionEnum.cpp
===================================================================
--- /issm/trunk/src/c/cores/CorePointerFromSolutionEnum.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/CorePointerFromSolutionEnum.cpp	(revision 17989)
@@ -34,4 +34,7 @@
 		case BalancethicknessSolutionEnum:
 			solutioncore=&balancethickness_core;
+			break;
+		case Balancethickness2SolutionEnum:
+			solutioncore=&balancethickness2_core;
 			break;
 		case BalancethicknessSoftSolutionEnum:
Index: /issm/trunk/src/c/cores/WrapperCorePointerFromSolutionEnum.cpp
===================================================================
--- /issm/trunk/src/c/cores/WrapperCorePointerFromSolutionEnum.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/WrapperCorePointerFromSolutionEnum.cpp	(revision 17989)
@@ -21,7 +21,7 @@
 
 	/*parameters: */
-	bool control_analysis=false;
-	bool tao_analysis=false;
-	bool dakota_analysis=false;
+	bool control_analysis;
+	bool dakota_analysis;
+	int  inversiontype;
 
 	/* retrieve some parameters that tell us whether wrappers are allowed, or whether we return 
@@ -30,5 +30,5 @@
 	parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
 	parameters->FindParam(&control_analysis,InversionIscontrolEnum);
-	parameters->FindParam(&tao_analysis,InversionTaoEnum);
+	parameters->FindParam(&inversiontype,InversionTypeEnum);
 
 	if(nodakotacore)dakota_analysis=false;
@@ -42,6 +42,10 @@
 	}
 	else if(control_analysis){
-		if(tao_analysis) solutioncore=controltao_core;
-		else solutioncore=control_core;
+		switch(inversiontype){
+			case 0: solutioncore=control_core; break;
+			case 1: solutioncore=controltao_core; break;
+			case 2: solutioncore=controlm1qn3_core; break;
+			default: _error_("control type not supported");
+		}
 	}
 	else CorePointerFromSolutionEnum(&solutioncore,parameters,solutiontype);  /*This means we retrieve a core solution that is not a wrapper*/
Index: /issm/trunk/src/c/cores/adjointbalancethickness2_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/adjointbalancethickness2_core.cpp	(revision 17989)
+++ /issm/trunk/src/c/cores/adjointbalancethickness2_core.cpp	(revision 17989)
@@ -0,0 +1,39 @@
+/*!\file:  adjointbalancethickness2_core.cpp
+ * \brief compute inverse method adjoint state
+ */ 
+
+#include "./cores.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+
+void adjointbalancethickness2_core(FemModel* femmodel){
+
+	/*parameters: */
+	bool save_results;
+
+	/*retrieve parameters:*/
+	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
+
+	/*compute thickness2 */
+	if(VerboseSolution()) _printf0_("   computing thickness2\n");
+	femmodel->SetCurrentConfiguration(Balancethickness2AnalysisEnum);
+	solutionsequence_linear(femmodel);
+
+	/*Call SurfaceAreax, because some it might be needed by PVector*/
+	SurfaceAreax(NULL,femmodel);
+
+	/*compute adjoint*/
+	if(VerboseSolution()) _printf0_("   computing adjoint\n");
+	femmodel->SetCurrentConfiguration(Balancethickness2AnalysisEnum,AdjointBalancethickness2AnalysisEnum);
+	solutionsequence_adjoint_linear(femmodel);
+
+	/*Save results*/
+	if(save_results){
+		if(VerboseSolution()) _printf0_("   saving results\n");
+		int outputs[1] = {AdjointEnum};
+		femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],1);
+	}
+}
Index: /issm/trunk/src/c/cores/adjointstressbalance_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/adjointstressbalance_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/adjointstressbalance_core.cpp	(revision 17989)
@@ -38,6 +38,8 @@
 		if(VerboseSolution()) _printf0_("   saving results\n");
 		if (isFS){
-			int outputs[4] = {AdjointxEnum,AdjointyEnum,AdjointzEnum,AdjointpEnum};
-			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],4);
+			//int outputs[4] = {AdjointxEnum,AdjointyEnum,AdjointzEnum,AdjointpEnum};
+			//femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],4);
+			int outputs[3] = {AdjointxEnum,AdjointyEnum,AdjointpEnum};
+			femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],3);
 		}
 		else{
Index: /issm/trunk/src/c/cores/balancethickness2_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/balancethickness2_core.cpp	(revision 17989)
+++ /issm/trunk/src/c/cores/balancethickness2_core.cpp	(revision 17989)
@@ -0,0 +1,32 @@
+/*!\file: balancethickness_core.cpp
+ * \brief: core of the balancethickness solution 
+ */ 
+
+#include "./cores.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+
+void balancethickness2_core(FemModel* femmodel){
+
+	/*parameters: */
+	bool save_results;
+
+	/*activate formulation: */
+	femmodel->SetCurrentConfiguration(Balancethickness2AnalysisEnum);
+
+	/*recover parameters: */
+	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
+
+	if(VerboseSolution()) _printf0_("call computational core:\n");
+	solutionsequence_linear(femmodel);
+
+	if(save_results){
+		if(VerboseSolution()) _printf0_("   saving results\n");
+		int outputs[4] = {ThicknessEnum,PotentialEnum,VxEnum,VyEnum};
+		femmodel->RequestedOutputsx(&femmodel->results,&outputs[0],4);
+	}
+
+}
Index: /issm/trunk/src/c/cores/control_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/control_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/control_core.cpp	(revision 17989)
@@ -12,4 +12,5 @@
 /*Local prototypes*/
 bool controlconvergence(IssmDouble J, IssmDouble tol_cm);
+IssmDouble objectivefunction(IssmDouble search_scalar,void* optargs);
 
 void control_core(FemModel* femmodel){
@@ -31,5 +32,4 @@
 	/*intermediary: */
 	IssmDouble search_scalar = 1.;
-	OptArgs    optargs;
 	OptPars    optpars;
 
@@ -65,5 +65,4 @@
 
 	/*Initialize some of the BrentSearch arguments: */
-	optargs.femmodel=femmodel;
 	optpars.xmin=0; optpars.xmax=1;
 
@@ -84,5 +83,5 @@
 		if(VerboseControl()) _printf0_("   optimizing along gradient direction\n");
 		optpars.maxiter=reCast<int,IssmDouble>(maxiter[n]); optpars.cm_jump=cm_jump[n];
-		BrentSearch(&search_scalar,J+n,&optpars,&objectivefunction,&optargs);
+		BrentSearch(&search_scalar,J+n,&optpars,&objectivefunction,(void*)femmodel);
 
 		if(VerboseControl()) _printf0_("   updating parameter using optimized search scalar\n"); //true means update save controls
@@ -128,2 +127,59 @@
 	return converged;
 }
+
+IssmDouble objectivefunction(IssmDouble search_scalar,void* optargs){
+
+	/*output: */
+	IssmDouble J;
+
+	/*parameters: */
+	int        solution_type,analysis_type;
+	bool       isFS       = false;
+	bool       conserve_loads = true;
+	FemModel  *femmodel       = (FemModel*)optargs;
+
+	/*Recover parameters: */
+	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
+	femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
+	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
+
+	/*set analysis type to compute velocity: */
+	if (solution_type==SteadystateSolutionEnum || solution_type==StressbalanceSolutionEnum){
+		femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
+	}
+	else if (solution_type==BalancethicknessSolutionEnum){
+		femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum);
+	}
+	else if (solution_type==BalancethicknessSoftSolutionEnum){
+		femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum);
+	}
+	else{
+		_error_("Solution " << EnumToStringx(solution_type) << " not implemented yet");
+	}
+
+	/*update parameter according to scalar: */ //false means: do not save control
+	InputControlUpdatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,search_scalar,false);
+
+	/*Run stressbalance with updated inputs: */
+	if (solution_type==SteadystateSolutionEnum){
+		stressbalance_core(femmodel);	//We need a 3D velocity!! (vz is required for the next thermal run)
+	}
+	else if (solution_type==StressbalanceSolutionEnum){
+		solutionsequence_nonlinear(femmodel,conserve_loads); 
+	}
+	else if (solution_type==BalancethicknessSolutionEnum){
+		solutionsequence_linear(femmodel); 
+	}
+	else if (solution_type==BalancethicknessSoftSolutionEnum){
+		/*Don't do anything*/
+	}
+	else{
+		_error_("Solution " << EnumToStringx(solution_type) << " not implemented yet");
+	}
+
+	/*Compute misfit for this velocity field.*/
+	femmodel->CostFunctionx(&J,NULL,NULL);
+
+	/*Free ressources:*/
+	return J;
+}
Index: /issm/trunk/src/c/cores/controlm1qn3_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/controlm1qn3_core.cpp	(revision 17989)
+++ /issm/trunk/src/c/cores/controlm1qn3_core.cpp	(revision 17989)
@@ -0,0 +1,204 @@
+/*!\file: controlm1qn3_core.cpp
+ * \brief: core of the control solution 
+ */ 
+
+#include <config.h>
+#include "./cores.h"
+#include "../toolkits/toolkits.h"
+#include "../classes/classes.h"
+#include "../shared/shared.h"
+#include "../modules/modules.h"
+#include "../solutionsequences/solutionsequences.h"
+
+#if defined (_HAVE_M1QN3_)
+/*m1qn3 prototypes*/
+extern "C" void *ctonbe_; // DIS mode : Conversion
+extern "C" void *ctcabe_; // DIS mode : Conversion
+extern "C" void *euclid_; // Scalar product
+typedef void (*SimulFunc) (long* indic,long* n, double* x, double* pf,double* g,long [],float [],void* dzs);
+extern "C" void m1qn3_ (void f(long* indic,long* n, double* x, double* pf,double* g,long [],float [],void* dzs),
+			void **, void **, void **,
+			long *, double [], double *, double [], double*, double *,
+			double *, char [], long *, long *, long *, long *, long *, long *, long [], double [], long *,
+			long *, long *, long [], float [],void* );
+
+/*Cost function prototype*/
+void simul(long* indic,long* n,double* X,double* pf,double* G,long izs[1],float rzs[1],void* dzs);
+
+void controlm1qn3_core(FemModel* femmodel){
+
+	/*Intermediaries*/
+	long         omode;
+	double       f,dxmin,gttol; 
+	int          maxsteps,maxiter;
+	int          intn,num_controls,solution_type;
+	IssmDouble  *X  = NULL;
+	IssmDouble  *G  = NULL;
+
+	/*Recover some parameters*/
+	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
+	femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
+	femmodel->parameters->FindParam(&maxsteps,InversionMaxstepsEnum);
+	femmodel->parameters->FindParam(&maxiter,InversionMaxiterEnum);
+	femmodel->parameters->FindParam(&dxmin,InversionDxminEnum);
+	femmodel->parameters->FindParam(&gttol,InversionGttolEnum);
+	femmodel->parameters->SetParam(false,SaveResultsEnum);
+
+	/*Initialize M1QN3 parameters*/
+	if(VerboseControl())_printf0_("   Initialize M1QN3 parameters\n");
+	SimulFunc costfuncion  = &simul;    /*Cost function address*/
+	void**    prosca       = &euclid_;  /*Dot product function (euclid is the default)*/
+	char      normtype[]   = "dfn";     /*Norm type: dfn = scalar product defined by prosca*/
+	long      izs[5];                   /*Arrays used by m1qn3 subroutines*/
+	long      iz[5];                    /*Integer m1qn3 working array of size 5*/
+	float     rzs[1];                   /*Arrays used by m1qn3 subroutines*/
+	long      impres       = 0;         /*verbosity level*/
+	long      imode[3]     = {0};       /*scaling and starting mode, 0 by default*/
+	long      indic        = 4;         /*compute f and g*/
+	long      reverse      = 0;         /*reverse or direct mode*/
+	long      io           = 6;         /*Channel number for the output*/
+
+	/*Optimization criterions*/
+	long      niter        = long(maxsteps); /*Maximum number of iterations*/
+	long      nsim         = long(maxiter);/*Maximum number of function calls*/
+
+	/*Get initial guess*/
+	Vector<IssmDouble> *Xpetsc = NULL;
+	GetVectorFromControlInputsx(&Xpetsc,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
+	X = Xpetsc->ToMPISerial();
+	Xpetsc->GetSize(&intn);
+	delete Xpetsc;
+
+	/*Get problem dimension and initialize gradient and initial guess*/
+	long n = long(intn);
+	G = xNew<double>(n);
+
+	/*Allocate m1qn3 working arrays (see doc)*/
+	long      m   = 100;
+	long      ndz = 4*n+m*(2*n+1);
+	double*   dz  = xNew<double>(ndz);
+
+	if(VerboseControl())_printf0_("   Computing initial solution\n");
+	_printf0_("\n");
+	_printf0_("Cost function f(x)   |  List of contributions\n");
+	_printf0_("_____________________________________________\n");
+	indic = 0; //no adjoint required
+	simul(&indic,&n,X,&f,G,izs,rzs,(void*)femmodel);
+	double f1=f;
+
+	indic = 4; //adjoint and gradient required
+	m1qn3_(costfuncion,prosca,&ctonbe_,&ctcabe_,
+				&n,X,&f,G,&dxmin,&f1,
+				&gttol,normtype,&impres,&io,imode,&omode,&niter,&nsim,iz,dz,&ndz,
+				&reverse,&indic,izs,rzs,(void*)femmodel);
+
+	switch(int(omode)){
+		case 0:  _printf0_("   Stop requested (indic = 0)\n"); break;
+		case 1:  _printf0_("   Convergence reached (gradient satisfies stopping criterion)\n"); break;
+		case 2:  _printf0_("   Bad initialization\n"); break;
+		case 3:  _printf0_("   Line search failure\n"); break;
+		case 4:  _printf0_("   Maximum number of iterations exceeded\n");break;
+		case 5:  _printf0_("   Maximum number of function calls exceeded\n"); break;
+		case 6:  _printf0_("   stopped on dxmin during line search\n"); break;
+		case 7:  _printf0_("   <g,d> > 0  or  <y,s> <0\n"); break;
+		default: _printf0_("   Unknown end condition\n");
+	}
+
+	/*Get solution*/
+	SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X);
+	ControlInputSetGradientx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,G);
+	femmodel->OutputControlsx(&femmodel->results);
+	femmodel->results->AddObject(new GenericExternalResult<double>(JEnum,f,1,0));
+
+	/*Finalize*/
+	if(VerboseControl()) _printf0_("   preparing final solution\n");
+	femmodel->parameters->SetParam(true,SaveResultsEnum);
+	void (*solutioncore)(FemModel*)=NULL;
+	CorePointerFromSolutionEnum(&solutioncore,femmodel->parameters,solution_type);
+	solutioncore(femmodel);
+
+	/*Clean-up and return*/
+	xDelete<double>(G);
+	xDelete<double>(X);
+	xDelete<double>(dz);
+}
+
+/*Cost function definition*/
+void simul(long* indic,long* n,double* X,double* pf,double* G,long izs[1],float rzs[1],void* dzs){
+
+	/*Recover Femmodel*/
+	int         solution_type;
+	FemModel   *femmodel  = (FemModel*)dzs;
+
+	/*Recover responses*/
+	int         num_responses;
+	int        *responses = NULL;
+	femmodel->parameters->FindParam(&responses,&num_responses,InversionCostFunctionsEnum);
+
+	/*Constrain input vector*/
+	IssmDouble  *XL = NULL;
+	IssmDouble  *XU = NULL;
+	GetVectorFromControlInputsx(&XL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"lowerbound");
+	GetVectorFromControlInputsx(&XU,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"upperbound");
+	for(long i=0;i<*n;i++){
+		if(X[i]>XU[i]) X[i]=XU[i];
+		if(X[i]<XL[i]) X[i]=XL[i];
+	}
+
+	/*Update control input*/
+	SetControlInputsFromVectorx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,X);
+
+	/*Recover some parameters*/
+	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
+
+	/*Compute solution and adjoint*/
+	void (*solutioncore)(FemModel*)=NULL;
+	void (*adjointcore)(FemModel*)=NULL;
+	CorePointerFromSolutionEnum(&solutioncore,femmodel->parameters,solution_type);
+	solutioncore(femmodel);
+
+	/*Compute objective function*/
+	IssmDouble* Jlist = NULL;
+	femmodel->CostFunctionx(pf,&Jlist,NULL);
+	_printf0_("f(x) = "<<setw(12)<<setprecision(7)<<*pf<<"  |  ");
+
+	/*Retrieve objective functions independently*/
+	for(int i=0;i<num_responses;i++) _printf0_(" "<<setw(12)<<setprecision(7)<<Jlist[i]);
+	_printf0_("\n");
+	xDelete<IssmDouble>(Jlist);
+
+	if(indic==0){
+		/*dry run, no gradient required*/
+		xDelete<int>(responses);
+		xDelete<IssmDouble>(XU);
+		xDelete<IssmDouble>(XL);
+		return;
+	}
+
+	/*Compute Adjoint*/
+	AdjointCorePointerFromSolutionEnum(&adjointcore,solution_type);
+	adjointcore(femmodel);
+
+	/*Compute gradient*/
+	IssmDouble* G2 = NULL;
+	Gradjx(&G2,NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
+	for(long i=0;i<*n;i++) G[i] = -G2[i];
+	xDelete<IssmDouble>(G2);
+
+	/*Constrain Gradient*/
+	for(long i=0;i<*n;i++){
+		if(X[i]>=XU[i]) G[i]=0.;
+		if(X[i]<=XL[i]) G[i]=0.;
+	}
+
+	/*Clean-up and return*/
+	xDelete<int>(responses);
+	xDelete<IssmDouble>(XU);
+	xDelete<IssmDouble>(XL);
+}
+
+#else
+void controlm1qn3_core(FemModel* femmodel){
+	_error_("M1QN3 not installed");
+}
+#endif //_HAVE_M1QN3_
Index: /issm/trunk/src/c/cores/controltao_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/controltao_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/controltao_core.cpp	(revision 17989)
@@ -26,8 +26,10 @@
 	int                 ierr;
 	int                 num_controls,solution_type;
-	int                 nsteps,maxiter;
+	int                 maxsteps,maxiter;
+	IssmDouble          fatol,frtol,gatol,grtol,gttol;
 	AppCtx              user;
 	TaoSolver           tao = 0;
 	int                *control_list = NULL;
+	char               *algorithm    = NULL;
 	Vector<IssmDouble> *X            = NULL;
 	Vector<IssmDouble> *G            = NULL;
@@ -45,7 +47,13 @@
 	femmodel->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
 	femmodel->parameters->FindParam(&control_list,NULL,InversionControlParametersEnum);
-	femmodel->parameters->FindParam(&nsteps,InversionNstepsEnum);
+	femmodel->parameters->FindParam(&maxsteps,InversionMaxstepsEnum);
+	femmodel->parameters->FindParam(&maxiter,InversionMaxiterEnum);
+	femmodel->parameters->FindParam(&fatol,InversionFatolEnum);
+	femmodel->parameters->FindParam(&frtol,InversionFrtolEnum);
+	femmodel->parameters->FindParam(&gatol,InversionGatolEnum);
+	femmodel->parameters->FindParam(&grtol,InversionGrtolEnum);
+	femmodel->parameters->FindParam(&gttol,InversionGttolEnum);
+	femmodel->parameters->FindParam(&algorithm,InversionAlgorithmEnum);
 	femmodel->parameters->SetParam(false,SaveResultsEnum);
-	maxiter=nsteps*10;
 
 	/*Prepare Toolkit*/
@@ -56,13 +64,11 @@
 	if(VerboseControl()) _printf0_("   Initializing the Toolkit for Advanced Optimization (TAO)\n");
 	TaoSetFromOptions(tao);
-	TaoSetType(tao,"tao_blmvm");
-	//TaoSetType(tao,"tao_cg");
-	//TaoSetType(tao,"tao_lmvm");
+	TaoSetType(tao,algorithm);
 
 	/*Prepare all TAO parameters*/
 	TaoSetMonitor(tao,IssmMonitor,&user,NULL);
 	TaoSetMaximumFunctionEvaluations(tao,maxiter);
-	TaoSetMaximumIterations(tao,nsteps);
-	TaoSetTolerances(tao,0.,0.,0.,0.,0.);
+	TaoSetMaximumIterations(tao,maxsteps);
+	TaoSetTolerances(tao,fatol,frtol,gatol,grtol,gttol);
 
 	GetVectorFromControlInputsx(&X, femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,"value");
@@ -101,4 +107,5 @@
 	/*Clean up and return*/
 	xDelete<int>(control_list);
+	xDelete<char>(algorithm);
 	xDelete<double>(user.J);
 	delete X;
@@ -135,5 +142,5 @@
 
 	/*Compute objective function*/
-	femmodel->CostFunctionx(fcn);
+	femmodel->CostFunctionx(fcn,NULL,NULL);
 
 	/*Compute gradient*/
Index: /issm/trunk/src/c/cores/cores.h
===================================================================
--- /issm/trunk/src/c/cores/cores.h	(revision 17988)
+++ /issm/trunk/src/c/cores/cores.h	(revision 17989)
@@ -7,5 +7,4 @@
 
 /*forward declarations: */
-struct OptArgs;
 class FemModel;
 class Parameters;
@@ -19,4 +18,5 @@
 void adjointstressbalance_core(FemModel* femmodel);
 void adjointbalancethickness_core(FemModel* femmodel);
+void adjointbalancethickness2_core(FemModel* femmodel);
 void gradient_core(FemModel* femmodel,int n=0,bool orthogonalize=false);
 void stressbalance_core(FemModel* femmodel);
@@ -29,4 +29,5 @@
 void control_core(FemModel* femmodel);
 void controltao_core(FemModel* femmodel);
+void controlm1qn3_core(FemModel* femmodel);
 void masstransport_core(FemModel* femmodel);
 void depthaverage_core(FemModel* femmodel);
@@ -34,4 +35,5 @@
 void extrudefromtop_core(FemModel* femmodel);
 void balancethickness_core(FemModel* femmodel);
+void balancethickness2_core(FemModel* femmodel);
 void balancevelocity_core(FemModel* femmodel);
 void slopecompute_core(FemModel* femmodel);
@@ -43,5 +45,5 @@
 void gia_core(FemModel* femmodel);
 void damage_core(FemModel* femmodel);
-IssmDouble objectivefunction(IssmDouble search_scalar,OptArgs* optargs);
+IssmDouble objectivefunction(IssmDouble search_scalar,FemModel* femmodel);
 
 //optimization
Index: /issm/trunk/src/c/cores/extrudefrombase_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/extrudefrombase_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/extrudefrombase_core.cpp	(revision 17989)
@@ -12,10 +12,26 @@
 void extrudefrombase_core(FemModel* femmodel){
 
+	/*Intermediaries*/
+	int elementtype,domaintype;
+
 	if(VerboseSolution()) _printf0_("extruding solution from base...\n");
 
-	/*Call on core computations: */
-	femmodel->SetCurrentConfiguration(ExtrudeFromBaseAnalysisEnum);
-	femmodel->UpdateConstraintsExtrudeFromBasex();
-	solutionsequence_linear(femmodel);
+	/*Get parameters*/
+	femmodel->parameters->FindParam(&domaintype,DomainTypeEnum);
+	femmodel->parameters->FindParam(&elementtype,MeshElementtypeEnum);
 
+	/*If this is a 2D horizontal domain, return (no need to extrude)*/
+	if(domaintype==Domain2DhorizontalEnum) return;
+
+	/*Special method for Penta, otherwise call solution sequence*/
+	if(elementtype==PentaEnum){
+		int inputenum; femmodel->parameters->FindParam(&inputenum,InputToExtrudeEnum);
+		InputExtrudex(femmodel,inputenum);
+	}
+	else{
+		/*Call on core computations: */
+		femmodel->SetCurrentConfiguration(ExtrudeFromBaseAnalysisEnum);
+		femmodel->UpdateConstraintsExtrudeFromBasex();
+		solutionsequence_linear(femmodel);
+	}
 }
Index: /issm/trunk/src/c/cores/hydrology_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/hydrology_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/hydrology_core.cpp	(revision 17989)
@@ -35,5 +35,4 @@
 		
 		/*transfer water column thickness to old water column thickness: */
-		
 		InputDuplicatex(femmodel,WatercolumnEnum,WaterColumnOldEnum);
 		
@@ -61,4 +60,5 @@
 		if(VerboseSolution()) _printf0_("   computing water head\n");
 		solutionsequence_hydro_nonlinear(femmodel);
+
 		if(save_results){
 			if(VerboseSolution()) _printf0_("   saving results \n");
Index: /issm/trunk/src/c/cores/masstransport_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/masstransport_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/masstransport_core.cpp	(revision 17989)
@@ -13,8 +13,7 @@
 
 	/*parameters: */
-	int    i;
 	int    numoutputs,domaintype;
 	bool   save_results;
-	bool   issmbgradients,ispdd,isdelta18o,isFS,isfreesurface,dakota_analysis;
+	bool   isFS,isfreesurface,dakota_analysis;
 	int    solution_type;
 	char** requested_outputs = NULL;
@@ -48,26 +47,21 @@
 		femmodel->SetCurrentConfiguration(FreeSurfaceBaseAnalysisEnum);
 		solutionsequence_linear(femmodel);
-		if(domaintype!=Domain2DhorizontalEnum){
-			femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
-			extrudefrombase_core(femmodel);
-		}
+		femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
+		extrudefrombase_core(femmodel);
+
 		femmodel->SetCurrentConfiguration(FreeSurfaceTopAnalysisEnum);
 		solutionsequence_linear(femmodel);
-		if(domaintype!=Domain2DhorizontalEnum){
-			femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
-			extrudefromtop_core(femmodel);
-		}
+		femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
+		extrudefromtop_core(femmodel);
 	}
 	else{
 		if(VerboseSolution()) _printf0_("   call computational core\n");
 		solutionsequence_linear(femmodel);
-		if(domaintype==Domain2DverticalEnum){
-			femmodel->parameters->SetParam(ThicknessEnum,InputToExtrudeEnum);
-			extrudefrombase_core(femmodel);
-			femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
-			extrudefrombase_core(femmodel);
-			femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
-			extrudefrombase_core(femmodel);
-		}
+		femmodel->parameters->SetParam(ThicknessEnum,InputToExtrudeEnum);
+		extrudefrombase_core(femmodel);
+		femmodel->parameters->SetParam(BaseEnum,InputToExtrudeEnum);
+		extrudefrombase_core(femmodel);
+		femmodel->parameters->SetParam(SurfaceEnum,InputToExtrudeEnum);
+		extrudefrombase_core(femmodel);
 	}
 
Index: sm/trunk/src/c/cores/objectivefunction.cpp
===================================================================
--- /issm/trunk/src/c/cores/objectivefunction.cpp	(revision 17988)
+++ 	(revision )
@@ -1,77 +1,0 @@
-/*!\file:  objectivefunction
- * \brief  objective function that returns a misfit, for a certain parameter.
- */ 
-
-/*include files: {{{*/
-#ifdef HAVE_CONFIG_H
-	#include <config.h>
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-#include "./cores.h"
-#include "../toolkits/toolkits.h"
-#include "../classes/classes.h"
-#include "../shared/shared.h"
-#include "../solutionsequences/solutionsequences.h"
-#include "../modules/modules.h"
-/*}}}*/
-
-IssmDouble objectivefunction(IssmDouble search_scalar,OptArgs* optargs){
-
-	/*output: */
-	IssmDouble J;
-
-	/*parameters: */
-	int        solution_type,analysis_type;
-	bool       isFS       = false;
-	bool       conserve_loads = true;
-	FemModel  *femmodel       = NULL;
-
-	/*Recover finite element model: */
-	femmodel=optargs->femmodel;
-
-	/*Recover parameters: */
-	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
-	femmodel->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
-	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
-
-	/*set analysis type to compute velocity: */
-	if (solution_type==SteadystateSolutionEnum || solution_type==StressbalanceSolutionEnum){
-		femmodel->SetCurrentConfiguration(StressbalanceAnalysisEnum);
-	}
-	else if (solution_type==BalancethicknessSolutionEnum){
-		femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum);
-	}
-	else if (solution_type==BalancethicknessSoftSolutionEnum){
-		femmodel->SetCurrentConfiguration(BalancethicknessAnalysisEnum);
-	}
-	else{
-		_error_("Solution " << EnumToStringx(solution_type) << " not implemented yet");
-	}
-
-	/*update parameter according to scalar: */ //false means: do not save control
-	InputControlUpdatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,search_scalar,false);
-
-	/*Run stressbalance with updated inputs: */
-	if (solution_type==SteadystateSolutionEnum){
-		stressbalance_core(femmodel);	//We need a 3D velocity!! (vz is required for the next thermal run)
-	}
-	else if (solution_type==StressbalanceSolutionEnum){
-		solutionsequence_nonlinear(femmodel,conserve_loads); 
-	}
-	else if (solution_type==BalancethicknessSolutionEnum){
-		solutionsequence_linear(femmodel); 
-	}
-	else if (solution_type==BalancethicknessSoftSolutionEnum){
-		/*Don't do anything*/
-	}
-	else{
-		_error_("Solution " << EnumToStringx(solution_type) << " not implemented yet");
-	}
-
-	/*Compute misfit for this velocity field.*/
-	femmodel->CostFunctionx(&J);
-
-	/*Free ressources:*/
-	return J;
-}
Index: /issm/trunk/src/c/cores/steadystate_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/steadystate_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/steadystate_core.cpp	(revision 17989)
@@ -21,5 +21,4 @@
 
 	/*intermediary: */
-	int i;
 	int step; 
 	Vector<IssmDouble>* ug     = NULL;
Index: /issm/trunk/src/c/cores/transient_core.cpp
===================================================================
--- /issm/trunk/src/c/cores/transient_core.cpp	(revision 17988)
+++ /issm/trunk/src/c/cores/transient_core.cpp	(revision 17989)
@@ -20,14 +20,13 @@
 
 	/*parameters: */
-	int    i;
 	IssmDouble starttime,finaltime,dt,yts;
-	bool   isstressbalance,ismasstransport,isFS,isthermal,isgroundingline,isgia,islevelset,isdamageevolution,ishydrology;
-	bool   save_results,dakota_analysis;
-	bool   time_adapt=false;
-	int    output_frequency;
-	int    domaintype,groundingline_migration,smb_model;
-	int    numoutputs         = 0;
-  Analysis *analysis = NULL;
-	char** requested_outputs = NULL;
+	bool       isstressbalance,ismasstransport,isFS,isthermal,isgroundingline,isgia,islevelset,isdamageevolution,ishydrology;
+	bool       save_results,dakota_analysis;
+	bool       time_adapt=false;
+	int        output_frequency;
+	int        domaintype,groundingline_migration;
+	int        numoutputs         = 0;
+	Analysis  *analysis = NULL;
+	char**     requested_outputs = NULL;
 
 
Index: /issm/trunk/src/c/modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp
===================================================================
--- /issm/trunk/src/c/modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void DragCoefficientAbsGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->DragCoefficientAbsGradient();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=DragCoefficientAbsGradient(element);
 	}
 
@@ -32,2 +28,61 @@
 	*pJ=J;
 }
+
+IssmDouble DragCoefficientAbsGradient(Element* element){
+
+	int         domaintype,numcomponents;
+	IssmDouble  Jelem=0.;
+	IssmDouble  misfit,Jdet;
+	IssmDouble  dp[2],weight;
+	IssmDouble* xyz_list      = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnBase()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   numcomponents   = 1; break;
+		case Domain3DEnum:           numcomponents   = 2; break;
+		case Domain2DhorizontalEnum: numcomponents   = 2; break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn basal element*/
+	Element* basalelement = element->SpawnBasalElement();
+
+	/* Get node coordinates*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input=basalelement->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
+	Input* drag_input   =basalelement->GetInput(FrictionCoefficientEnum); _assert_(drag_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,DragCoefficientAbsGradientEnum);
+		drag_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
+
+		/*Compute Tikhonov regularization J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
+		Jelem+=weight*.5*dp[0]*dp[0]*Jdet*gauss->weight;
+		if(numcomponents==2) Jelem+=weight*.5*dp[1]*dp[1]*Jdet*gauss->weight;
+
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h
===================================================================
--- /issm/trunk/src/c/modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void DragCoefficientAbsGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble DragCoefficientAbsGradient(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/Gradjx/Gradjx.cpp
===================================================================
--- /issm/trunk/src/c/modules/Gradjx/Gradjx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/Gradjx/Gradjx.cpp	(revision 17989)
@@ -66,2 +66,19 @@
 	xDelete<int>(control_type);
 }
+void Gradjx(IssmDouble** pgradient,IssmDouble** pnorm_list, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters){
+
+	/*output: */
+	IssmDouble* gradient=NULL;
+
+	/*intermediary: */
+	Vector<IssmDouble>* vec_gradient=NULL;
+
+	Gradjx(&vec_gradient,pnorm_list,elements,nodes, vertices,loads,materials,parameters);
+	gradient=vec_gradient->ToMPISerial();
+
+	/*Free ressources:*/
+	delete vec_gradient;
+
+	/*Assign output pointers:*/
+	*pgradient=gradient;
+}
Index: /issm/trunk/src/c/modules/Gradjx/Gradjx.h
===================================================================
--- /issm/trunk/src/c/modules/Gradjx/Gradjx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/Gradjx/Gradjx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void Gradjx(Vector<IssmDouble>** pgrad_g,IssmDouble** pgrad_norm,Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters);
+void Gradjx(IssmDouble** pgrad_g,IssmDouble** pgrad_norm,Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters);
 
 #endif  /* _GRADJX_H */
Index: /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp
===================================================================
--- /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/GroundinglineMigrationx/GroundinglineMigrationx.cpp	(revision 17989)
@@ -36,5 +36,5 @@
 			phi_ungrounding=ContactFSLevelset(elements,vertices);
 			break;
-		case AgressiveMigrationEnum:
+		case AggressiveMigrationEnum:
 		case SubelementMigrationEnum:
 		case SubelementMigration2Enum:
Index: /issm/trunk/src/c/modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.cpp
===================================================================
--- /issm/trunk/src/c/modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.cpp	(revision 17989)
+++ /issm/trunk/src/c/modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.cpp	(revision 17989)
@@ -0,0 +1,15 @@
+/*!\file InputDepthAverageAtBasex
+ * \brief: extrude input
+ */
+
+#include "./InputDepthAverageAtBasex.h"
+#include "../../shared/shared.h"
+#include "../../classes/classes.h"
+#include "../../toolkits/toolkits.h"
+
+void InputDepthAverageAtBasex(FemModel* femmodel,int original_enum, int new_enum){
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->InputDepthAverageAtBase(original_enum,new_enum);
+	}
+}
Index: /issm/trunk/src/c/modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.h
===================================================================
--- /issm/trunk/src/c/modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.h	(revision 17989)
+++ /issm/trunk/src/c/modules/InputDepthAverageAtBasex/InputDepthAverageAtBasex.h	(revision 17989)
@@ -0,0 +1,13 @@
+/*!\file:  InputDepthAverageAtBasex.h
+ * \brief header file for field extrusion
+ */ 
+
+#ifndef _INPUTDEPTHAVERAGEATBASEX_H
+#define _INPUTDEPTHAVERAGEATBASEX_H
+
+#include "../../classes/classes.h"
+
+/* local prototypes: */
+void InputDepthAverageAtBasex(FemModel* femmodel,int reinitialized_enum, int original_enum);
+
+#endif  /* _INPUTDUPLICATEX_H */
Index: /issm/trunk/src/c/modules/InputExtrudex/InputExtrudex.cpp
===================================================================
--- /issm/trunk/src/c/modules/InputExtrudex/InputExtrudex.cpp	(revision 17989)
+++ /issm/trunk/src/c/modules/InputExtrudex/InputExtrudex.cpp	(revision 17989)
@@ -0,0 +1,15 @@
+/*!\file InputExtrudex
+ * \brief: extrude input
+ */
+
+#include "./InputExtrudex.h"
+#include "../../shared/shared.h"
+#include "../../classes/classes.h"
+#include "../../toolkits/toolkits.h"
+
+void InputExtrudex(FemModel* femmodel,int input_enum){
+	for(int i=0;i<femmodel->elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		element->InputExtrude(input_enum);
+	}
+}
Index: /issm/trunk/src/c/modules/InputExtrudex/InputExtrudex.h
===================================================================
--- /issm/trunk/src/c/modules/InputExtrudex/InputExtrudex.h	(revision 17989)
+++ /issm/trunk/src/c/modules/InputExtrudex/InputExtrudex.h	(revision 17989)
@@ -0,0 +1,13 @@
+/*!\file:  InputExtrudex.h
+ * \brief header file for field extrusion
+ */ 
+
+#ifndef _INPUTEXTRUDEX_H
+#define _INPUTEXTRUDEX_H
+
+#include "../../classes/classes.h"
+
+/* local prototypes: */
+void InputExtrudex(FemModel* femmodel,int input_enum);
+
+#endif  /* _INPUTDUPLICATEX_H */
Index: /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp
===================================================================
--- /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp	(revision 17989)
@@ -33,7 +33,5 @@
 
 	/*intermediary: */
-	bool        isnan;
 	int         i,j,count,elementnbv,numfacevertices;
-	int*        faceverticesid   = NULL;
 	IssmDouble  value;
 	IssmDouble *times            = NULL;
@@ -42,7 +40,8 @@
 
 	/*Higher-order finite elements*/
-	int   v1,v2,v3,v4;
+	int   v1,v2;
 	bool *my_edges = NULL;
 	bool *my_faces = NULL;
+	bool *boundaryedge = NULL;
 
 	switch(finite_element){
@@ -75,4 +74,5 @@
 				FacesPartitioning(&my_faces,iomodel);
 			}
+			EdgeOnBoundaryFlags(&boundaryedge,iomodel);
 			break;
 		case P2xP4Enum:
@@ -107,5 +107,5 @@
 				}
 				for(i=0;i<iomodel->numberofedges;i++){
-					if(my_edges[i]){
+					if(my_edges[i] && boundaryedge[i]){
 						v1 = iomodel->edges[3*i+0]-1;
 						v2 = iomodel->edges[3*i+1]-1;
@@ -119,21 +119,18 @@
 				if(iomodel->meshelementtype==PentaEnum){
 					for(i=0;i<iomodel->numberoffaces;i++){
-						if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+						if(iomodel->faces[i*iomodel->facescols+2]==2){/*Vertical quads*/
 							if(my_faces[i]){
-								FaceGetVertexIndices(iomodel,&numfacevertices,&faceverticesid,i);
-								isnan=0;
+								numfacevertices = iomodel->faces[i*iomodel->facescols+3];
+								value=0.;
 								for(j=0;j<numfacevertices;j++){
-									if(xIsNan<IssmDouble>(spcdata[faceverticesid[j]-1])) isnan=1;
+									value += spcdata[iomodel->faces[i*iomodel->facescols+4+j] -1];
 								}
-								if(isnan==0){
-									value=0;
-									for(j=0;j<numfacevertices;j++){
-										value=value+spcdata[faceverticesid[j]-1]/numfacevertices;
-									}
-									constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+i+1,
+								value = value/reCast<IssmDouble>(numfacevertices);
+								if(!xIsNan<IssmDouble>(value)){
+									constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,
+													iomodel->nodecounter+iomodel->numberofvertices+iomodel->numberofedges+i+1,
 													dof,value,analysis_type));
 									count++;
 								}
-								xDelete<int>(faceverticesid);
 							}
 						}
@@ -179,25 +176,24 @@
 				}
 				for(i=0;i<iomodel->numberoffaces;i++){
-					if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+					if(iomodel->faces[i*iomodel->facescols+2]==2){/*Vertical quads*/
 						if(my_faces[i]){
-							FaceGetVertexIndices(iomodel,&numfacevertices,&faceverticesid,i);
-							isnan=0;
+							numfacevertices = iomodel->faces[i*iomodel->facescols+3];
+							value=0.;
 							for(j=0;j<numfacevertices;j++){
-								if(xIsNan<IssmDouble>(spcdata[faceverticesid[j]-1])) isnan=1;
-							}
-							if(isnan==0){
-								value=0;
-								for(j=0;j<numfacevertices;j++){
-									value=value+spcdata[faceverticesid[j]-1]/numfacevertices;
-								}
-								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+1,
+								value += spcdata[iomodel->faces[i*iomodel->facescols+4+j] -1];
+							}
+							value = value/reCast<IssmDouble>(numfacevertices);
+							if(!xIsNan<IssmDouble>(value)){
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+1,
+												iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+1,
 												dof,value,analysis_type));
-								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+2,iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+2,
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+2,
+												iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+2,
 												dof,value,analysis_type));
-								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+3,iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+3,
+								constraints->AddObject(new SpcStatic(iomodel->constraintcounter+count+3,
+												iomodel->nodecounter+iomodel->numberofvertices+3*iomodel->numberofedges+3*i+3,
 												dof,value,analysis_type));
 								count=count+3;
 							}
-							xDelete<int>(faceverticesid);
 						}
 					}
@@ -471,3 +467,4 @@
 	xDelete<bool>(my_edges);
 	xDelete<bool>(my_faces);
+	xDelete<bool>(boundaryedge);
 }
Index: /issm/trunk/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/Control/CreateParametersControl.cpp	(revision 17989)
@@ -10,5 +10,6 @@
 void CreateParametersControl(Parameters* parameters,IoModel* iomodel,int solution_type){
 
-	bool        control_analysis,tao_analysis;
+	bool        control_analysis;
+	int         inversiontype;
 	int         nsteps;
 	int         num_control_type;
@@ -22,5 +23,5 @@
 	/*retrieve some parameters: */
 	iomodel->Constant(&control_analysis,InversionIscontrolEnum);
-	iomodel->Constant(&tao_analysis,InversionTaoEnum);
+	iomodel->Constant(&inversiontype,InversionTypeEnum);
 
 	if(control_analysis){
@@ -29,9 +30,5 @@
 		parameters->AddObject(iomodel->CopyConstantObject(InversionNumControlParametersEnum));
 		parameters->AddObject(iomodel->CopyConstantObject(InversionNumCostFunctionsEnum));
-		parameters->AddObject(iomodel->CopyConstantObject(InversionNstepsEnum));
 		parameters->AddObject(iomodel->CopyConstantObject(InversionIncompleteAdjointEnum));
-		if(!tao_analysis){
-			parameters->AddObject(iomodel->CopyConstantObject(InversionCostFunctionThresholdEnum));
-		}
 
 		/*What solution type?*/
@@ -46,20 +43,38 @@
 		iomodel->FetchData(&control_type,NULL,&num_control_type,InversionControlParametersEnum);
 		iomodel->FetchData(&cm_responses,NULL,&num_cm_responses,InversionCostFunctionsEnum);
-		if(!tao_analysis){
-			iomodel->FetchData(&cm_jump,&nsteps,NULL,InversionStepThresholdEnum);
-			iomodel->FetchData(&optscal,NULL,NULL,InversionGradientScalingEnum);
-			iomodel->FetchData(&maxiter,NULL,NULL,InversionMaxiterPerStepEnum);
-		}
+		parameters->AddObject(new IntVecParam(InversionControlParametersEnum,control_type,num_control_type));
+		parameters->AddObject(new IntVecParam(InversionCostFunctionsEnum,cm_responses,num_cm_responses));
 
-		if(tao_analysis){
-			parameters->AddObject(new IntVecParam(InversionControlParametersEnum,control_type,num_control_type));
-			parameters->AddObject(new IntVecParam(InversionCostFunctionsEnum,cm_responses,num_cm_responses));
-		}
-		else{
-			parameters->AddObject(new IntVecParam(InversionControlParametersEnum,control_type,num_control_type));
-			parameters->AddObject(new IntVecParam(InversionCostFunctionsEnum,cm_responses,num_cm_responses));
-			parameters->AddObject(new DoubleMatParam(InversionGradientScalingEnum,optscal,nsteps,num_control_type));
-			parameters->AddObject(new DoubleVecParam(InversionStepThresholdEnum,cm_jump,nsteps));
-			parameters->AddObject(new DoubleVecParam(InversionMaxiterPerStepEnum,maxiter,nsteps));
+		/*Inversion type specifics*/
+		switch(inversiontype){
+			case 0:/*Brent Search*/
+				parameters->AddObject(iomodel->CopyConstantObject(InversionNstepsEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionCostFunctionThresholdEnum));
+				iomodel->FetchData(&cm_jump,&nsteps,NULL,InversionStepThresholdEnum);
+				iomodel->FetchData(&optscal,NULL,NULL,InversionGradientScalingEnum);
+				iomodel->FetchData(&maxiter,NULL,NULL,InversionMaxiterPerStepEnum);
+				parameters->AddObject(new DoubleMatParam(InversionGradientScalingEnum,optscal,nsteps,num_control_type));
+				parameters->AddObject(new DoubleVecParam(InversionStepThresholdEnum,cm_jump,nsteps));
+				parameters->AddObject(new DoubleVecParam(InversionMaxiterPerStepEnum,maxiter,nsteps));
+				break;
+			case 1:/*TAO*/
+				parameters->AddObject(iomodel->CopyConstantObject(InversionFatolEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionFrtolEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionGatolEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionGrtolEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionGttolEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionMaxstepsEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionMaxiterEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionAlgorithmEnum));
+				break;
+			case 2:/*M1QN3*/
+				parameters->AddObject(iomodel->CopyConstantObject(InversionDxminEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionGttolEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionMaxstepsEnum));
+				parameters->AddObject(iomodel->CopyConstantObject(InversionMaxiterEnum));
+				break;
+			default:
+				_error_("not supported");
+
 		}
 
Index: /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp	(revision 17989)
@@ -16,6 +16,6 @@
 	Element  *element = NULL;
 	Material *material = NULL;
-	int    num_control_type;
-	bool   control_analysis;
+	int       num_control_type;
+	bool      control_analysis;
 
 	/*Fetch parameters: */
@@ -32,14 +32,24 @@
 
 	iomodel->FetchData(5,InversionControlParametersEnum,InversionCostFunctionsEnum,InversionCostFunctionsCoefficientsEnum,InversionMinParametersEnum,InversionMaxParametersEnum);
+
 	for(i=0;i<num_control_type;i++){
-		switch(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])){
-			case BalancethicknessThickeningRateEnum: iomodel->FetchData(1,BalancethicknessThickeningRateEnum); break;
-			case VxEnum:   iomodel->FetchData(1,VxEnum); break;
-			case VyEnum:   iomodel->FetchData(1,VyEnum); break;
-			case ThicknessEnum:             iomodel->FetchData(1,ThicknessEnum); break;
-			case FrictionCoefficientEnum:   iomodel->FetchData(1,FrictionCoefficientEnum); break;
+		int control = reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i]);
+		switch(control){
+			/*List of supported controls*/
+			case BalancethicknessThickeningRateEnum: 
+			case VxEnum:
+			case VyEnum:
+			case ThicknessEnum:
+			case FrictionCoefficientEnum:
+			case BalancethicknessNuxEnum:
+			case BalancethicknessNuyEnum:
+				iomodel->FetchData(1,control); 
+				break;
+
+			/*Special cases*/
 			case MaterialsRheologyBbarEnum: iomodel->FetchData(1,MaterialsRheologyBEnum); break;
-			case DamageDbarEnum: iomodel->FetchData(1,DamageDEnum); break;
-			default: _error_("Control " << EnumToStringx(reCast<int,IssmDouble>(iomodel->Data(InversionControlParametersEnum)[i])) << " not implemented yet");
+			case DamageDbarEnum:            iomodel->FetchData(1,DamageDEnum);            break;
+			default:
+				_error_("Control " << EnumToStringx(control) << " not implemented yet");
 		}
 	}
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateEdges.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateEdges.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateEdges.cpp	(revision 17989)
@@ -5,6 +5,7 @@
 #include "../../classes/classes.h"
 #include "../../shared/shared.h"
-
-void CreateEdges(IoModel* iomodel){
+#include "./ModelProcessorx.h"
+
+void CreateEdges(IoModel* iomodel){/*{{{*/
 
 	/*If edges are already present, exit*/
@@ -39,9 +40,9 @@
 			elementedges_markers = xNew<int>(elementnbe);
 			elementedges[2*0+0] = 1; elementedges[2*0+1] = 2; elementedges_markers[0] = 1;
-			elementedges[2*1+0] = 2; elementedges[2*1+1] = 0; elementedges_markers[1] = 1;
+			elementedges[2*1+0] = 0; elementedges[2*1+1] = 2; elementedges_markers[1] = 1;
 			elementedges[2*2+0] = 0; elementedges[2*2+1] = 1; elementedges_markers[2] = 1;
-			elementedges[2*3+0] = 0; elementedges[2*3+1] = 3; elementedges_markers[3] = 1;
-			elementedges[2*4+0] = 1; elementedges[2*4+1] = 3; elementedges_markers[4] = 1;
-			elementedges[2*5+0] = 2; elementedges[2*5+1] = 3; elementedges_markers[5] = 1;
+			elementedges[2*3+0] = 1; elementedges[2*3+1] = 3; elementedges_markers[3] = 1;
+			elementedges[2*4+0] = 2; elementedges[2*4+1] = 3; elementedges_markers[4] = 1;
+			elementedges[2*5+0] = 0; elementedges[2*5+1] = 3; elementedges_markers[5] = 1;
 			break;
 		case PentaEnum:
@@ -142,3 +143,92 @@
 	iomodel->elementtoedgeconnectivity = element_edge_connectivity;
 	iomodel->numberofedges             = nbe;
-}
+}/*}}}*/
+void EdgeOnBoundaryFlags(bool** pflags,IoModel* iomodel){/*{{{*/
+
+	/*Intermediaries*/
+	bool isv1,isv2;
+	int  facenbv,v1,v2;
+	int  id_edge,id_element;
+	int  elementnbe;
+
+	/*Mesh dependent variables*/
+	switch(iomodel->meshelementtype){
+		case TriaEnum:  elementnbe = 3; break;
+		case TetraEnum: elementnbe = 6; break;
+		case PentaEnum: elementnbe = 9; break;
+		default:        _error_("mesh dimension not supported yet");
+	}
+
+	/*Get edges and allocate output*/
+	if(!iomodel->edges) CreateEdges(iomodel);
+	bool* flags = xNewZeroInit<bool>(iomodel->numberofedges);
+
+	if(iomodel->domaindim==2){
+
+		/*Count how many times an edge is found in elementtoedgeconnectivity*/
+		int* counter = xNewZeroInit<int>(iomodel->numberofedges);
+		for(int i=0;i<iomodel->numberofelements;i++){
+			for(int j=0;j<elementnbe;j++){
+				counter[iomodel->elementtoedgeconnectivity[elementnbe*i+j]] += 1;
+			}
+		}
+
+		/*Now, loop over the egdes, whenever it is not connected to a second element, the edge is on boundary*/
+		for(int i=0;i<iomodel->numberofedges;i++){
+			if(counter[i]==1) flags[i]=true;
+		}
+
+		/*Clean up*/
+		xDelete<int>(counter);
+	}
+	else if(iomodel->domaindim==3){
+
+		/*Get faces*/
+		if(!iomodel->faces) CreateFaces(iomodel);
+
+		/*Now, loop over the faces, whenever it is not connected to a second element, all edges are on boundary*/
+		for(int id_face=0;id_face<iomodel->numberoffaces;id_face++){
+
+			if(iomodel->faces[id_face*iomodel->facescols+1]==-1){
+
+				/*The face is connected to the element e only*/
+				id_element = iomodel->faces[id_face*iomodel->facescols+0]-1;
+				facenbv    = iomodel->faces[id_face*iomodel->facescols+3];
+
+				/*Get all edges for this element*/
+				for(int edge = 0; edge<elementnbe; edge++){
+
+					id_edge     = iomodel->elementtoedgeconnectivity[elementnbe*id_element+edge];
+					v1          = iomodel->edges[id_edge*3+0];
+					v2          = iomodel->edges[id_edge*3+1];
+
+					/*Test if v1 is in the face*/
+					isv1=false;
+					for(int i=0;i<facenbv;i++){
+						if(iomodel->faces[id_face*iomodel->facescols+4+i] == v1){
+							isv1 = true; break;
+						}
+					}
+					if(!isv1) continue;
+
+					/*test if v2 is in the face*/
+					isv2=false;
+					for(int i=0;i<facenbv;i++){
+						if(iomodel->faces[id_face*iomodel->facescols+4+i] == v2){
+							isv2 = true; break;
+						}
+					}
+
+					/*If v1 and v2 are found, this edge is on boundary*/
+					if(isv2) flags[id_edge] = true;
+				}
+			}
+		}
+	}
+	else{
+		_error_("dimension not supported");
+	}
+
+	/*Clean up and return*/
+	*pflags = flags;
+}/*}}}*/
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateFaces.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateFaces.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateFaces.cpp	(revision 17989)
@@ -126,15 +126,61 @@
 	/*Intermediaries*/
 	bool exist;
-	int  i,j,k,v0,cols;
-	int  maxnbf,nbf,elementnbf,elementnbv,facemaxnbv;
+	int  i,j,k,v0,cols,facescols;
+	int  maxnbf,nbf,elementnbf,elementnbv,facenbv,facemaxnbv;
 	int *elementfaces         = NULL;
 	int *elementfaces_markers = NULL;
 
-	/*Maximum number of faces*/
-	maxnbf = 5*iomodel->numberofelements;
+	/*Mesh specific face indexing per element*/
+	switch(iomodel->meshelementtype){
+		case PentaEnum:
+			elementnbv = 6; /*Number of vertices per element*/
+			elementnbf = 5; /*Number of faces per element*/
+			facemaxnbv = 4; /*Maximum number of vertices per face*/
+			cols       = facemaxnbv + 1;
+			elementfaces         = xNew<int>(elementnbf*cols);
+			elementfaces_markers = xNew<int>(elementnbf);
+			/*2 triangles*/
+			elementfaces_markers[0] = 1;
+			elementfaces_markers[1] = 1;
+			elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0;  elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
+			elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 3;  elementfaces[cols*1+2] = 4; elementfaces[cols*1+3] = 5;
+			/*3 quads*/
+			elementfaces_markers[2] = 2;
+			elementfaces_markers[3] = 2;
+			elementfaces_markers[4] = 2;
+			elementfaces[cols*2+0] = 4; elementfaces[cols*2+1] = 1;  elementfaces[cols*2+2] = 2; elementfaces[cols*2+3] = 5;  elementfaces[cols*2+4] = 4;
+			elementfaces[cols*3+0] = 4; elementfaces[cols*3+1] = 2;  elementfaces[cols*3+2] = 0; elementfaces[cols*3+3] = 3;  elementfaces[cols*3+4] = 5;
+			elementfaces[cols*4+0] = 4; elementfaces[cols*4+1] = 0;  elementfaces[cols*4+2] = 1; elementfaces[cols*4+3] = 4;  elementfaces[cols*4+4] = 3;
+			break;
+		case TetraEnum:
+			elementnbv = 4; /*Number of vertices per element*/
+			elementnbf = 4; /*Number of faces per element*/
+			facemaxnbv = 3; /*Maximum number of vertices per face*/
+			cols       = facemaxnbv + 1;
+			elementfaces         = xNew<int>(elementnbf*cols);
+			elementfaces_markers = xNew<int>(elementnbf);
+			/*4 triangles*/
+			elementfaces_markers[0] = 1;
+			elementfaces_markers[1] = 1;
+			elementfaces_markers[2] = 1;
+			elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0;  elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
+			elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 0;  elementfaces[cols*1+2] = 3; elementfaces[cols*1+3] = 1;
+			elementfaces[cols*2+0] = 3; elementfaces[cols*2+1] = 1;  elementfaces[cols*2+2] = 3; elementfaces[cols*2+3] = 2;
+			elementfaces[cols*3+0] = 3; elementfaces[cols*3+1] = 0;  elementfaces[cols*3+2] = 2; elementfaces[cols*3+3] = 3;
+			break;
+		default:
+		_error_("mesh "<< EnumToStringx(iomodel->meshelementtype) <<" not supported");
+	}
+
+	/*Allocate connectivity*/
+	int *element_face_connectivity = xNew<int>(iomodel->numberofelements*elementnbf); /*format: [face1 face2 ...] */
+
+	/*Maximum number of faces for initial allocation*/
+	maxnbf     = elementnbf*iomodel->numberofelements;
+	facescols  = 4+facemaxnbv; _assert_(facescols>6);
 
 	/*Initialize intermediaries*/
-	int*  facestemp = xNew<int>(maxnbf*6);         /*format: [vertex1 vertex2 vertex3 element1 element2 marker]    */
-	for(i=0;i<maxnbf;i++) facestemp[i*6+4]=-1;     /*Initialize last column of faces as -1 (boundary face)         */
+	int* facestemp = xNew<int>(maxnbf*facescols);        /*format: [element1 element2 marker nbv vertex1 vertex2 vertex3 ...]    */
+	for(i=0;i<maxnbf;i++) facestemp[i*facescols+1]=-1;   /*Initialize second column of faces as -1 (boundary face)               */
 
 	/*Initialize chain*/
@@ -143,30 +189,4 @@
 	for(i=0;i<iomodel->numberofvertices;i++) head_minv[i]=-1;
 
-	/*Mesh specific face indexing per element*/
-	if(iomodel->meshelementtype==PentaEnum){
-		elementnbv = 6; /*Number of vertices per element*/
-		elementnbf = 5; /*Number of faces per element*/
-		facemaxnbv = 4; /*Maximum number of vertices per face*/
-		cols       = facemaxnbv + 1;
-		elementfaces         = xNew<int>(elementnbf*cols);
-		elementfaces_markers = xNew<int>(elementnbf);
-		/*2 triangles*/
-		elementfaces_markers[0] = 1;
-		elementfaces_markers[1] = 1;
-		elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0;  elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
-		elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 3;  elementfaces[cols*1+2] = 4; elementfaces[cols*1+3] = 5;
-		/*3 quads*/
-		elementfaces_markers[2] = 2;
-		elementfaces_markers[3] = 2;
-		elementfaces_markers[4] = 2;
-		elementfaces[cols*2+0] = 4; elementfaces[cols*2+1] = 1;  elementfaces[cols*2+2] = 2; elementfaces[cols*2+3] = 5;  elementfaces[cols*2+4] = 4;
-		elementfaces[cols*3+0] = 4; elementfaces[cols*3+1] = 2;  elementfaces[cols*3+2] = 0; elementfaces[cols*3+3] = 3;  elementfaces[cols*3+4] = 5;
-		elementfaces[cols*4+0] = 4; elementfaces[cols*4+1] = 0;  elementfaces[cols*4+2] = 1; elementfaces[cols*4+3] = 4;  elementfaces[cols*4+4] = 3;
-	}
-	else{
-		_error_("mesh dimension not supported yet");
-	}
-	int *element_face_connectivity = xNew<int>(iomodel->numberofelements*elementnbf); /*format: [face1 face2 ...] */
-
 	/*Initialize number of faces and list of vertex indices*/
 	nbf = 0;
@@ -177,5 +197,6 @@
 
 			/*Get indices of current face*/
-			for(k=0;k<elementfaces[cols*j+0];k++){
+			facenbv = elementfaces[cols*j+0];
+			for(k=0;k<facenbv;k++){
 				v[k] = iomodel->elements[i*elementnbv + elementfaces[cols*j+k+1]] - 1;
 			}
@@ -183,16 +204,15 @@
 			/*Sort list of vertices*/
 			HeapSort(v,elementfaces[cols*j+0]);
-			v0 = v[0];
+			v0 = v[0]; _assert_(v0>=0 && v0<iomodel->numberofvertices);
 
 			/*This face a priori has not been processed yet*/
 			exist = false;
 
-			/*Go through all processed faces connected to v1 and check whether we have seen this edge yet*/
-			_assert_(v0>=0 && v0<iomodel->numberofvertices);
-			for(int e=head_minv[v0]; e!=-1; e=next_face[e]){
-				if(facestemp[e*6+1]==v[1]+1 && facestemp[e*6+2]==v[2]+1){
+			/*Go through all processed faces connected to v0 and check whether we have seen this face yet*/
+			for(int f=head_minv[v0]; f!=-1; f=next_face[f]){
+				if(facestemp[f*facescols+5]==v[1]+1 && facestemp[f*facescols+6]==v[2]+1){
 					exist = true;
-					facestemp[e*6+4]=i+1;
-					element_face_connectivity[i*elementnbf+j]=e;
+					facestemp[f*facescols+1]=i+1;
+					element_face_connectivity[i*elementnbf+j]=f;
 					break;
 				}
@@ -204,9 +224,8 @@
 
 				/*Update faces*/
-				facestemp[nbf*6+0] = v[0]+1;
-				facestemp[nbf*6+1] = v[1]+1;
-				facestemp[nbf*6+2] = v[2]+1;
-				facestemp[nbf*6+3] = i+1;
-				facestemp[nbf*6+5] = elementfaces_markers[j];
+				facestemp[nbf*facescols+0] = i+1;
+				facestemp[nbf*facescols+2] = elementfaces_markers[j];
+				facestemp[nbf*facescols+3] = facenbv;
+				for(k=0;k<facenbv;k++) facestemp[nbf*facescols+4+k] = v[k]+1;
 
 				/*Update Connectivity*/
@@ -231,6 +250,6 @@
 
 	/*Create final faces (now that we have the correct size)*/
-	int* faces = xNew<int>(nbf*6); /*vertex1 vertex2 vertex3 element1 element2 marker*/
-	xMemCpy<int>(faces,facestemp,nbf*6);
+	int* faces = xNew<int>(nbf*facescols);
+	xMemCpy<int>(faces,facestemp,nbf*facescols);
 	xDelete<int>(facestemp);
 
@@ -238,74 +257,5 @@
 	iomodel->faces                     = faces;
 	iomodel->numberoffaces             = nbf;
+	iomodel->facescols                 = facescols;
 	iomodel->elementtofaceconnectivity = element_face_connectivity;
 }/*}}}*/
-void FaceGetVertexIndices(IoModel* iomodel,int* pnumvertices,int** pverticesid,int facenumber){/*{{{*/
-
-	int numbervertices;
-	if(iomodel->domaintype==Domain3DEnum){
-		if((iomodel->faces[6*facenumber+5])==1){
-			numbervertices=3;
-		}
-		else if((iomodel->faces[6*facenumber+5])==2){
-			numbervertices=4;
-		}
-		else _error_("face marker not supported yet ");
-	}
-	else _error_("mesh type not supported yet");
-
-	int* facevertices = xNew<int>(numbervertices);
-	if(numbervertices==3){
-		for(int i=0;i<3;i++) facevertices[i]=iomodel->faces[6*facenumber+i]-1;
-	}
-	else if(numbervertices==4){
-		int  i,j,k,cols,faceid;
-		int  maxnbf,nbf,elementnbf,elementnbv,facemaxnbv;
-		int *elementfaces         = NULL;
-		int *elementfaces_markers = NULL;
-		int elementid=iomodel->faces[6*facenumber+3];
-		int counter=0;
-
-		/*Recreate element properties*/
-		elementnbv = 6; /*Number of vertices per element*/
-		elementnbf = 5; /*Number of faces per element*/
-		facemaxnbv = 4; /*Maximum number of vertices per face*/
-		cols       = facemaxnbv + 1;
-		elementfaces         = xNew<int>(elementnbf*cols);
-		elementfaces_markers = xNew<int>(elementnbf);
-		/*2 triangles*/
-		elementfaces_markers[0] = 1;
-		elementfaces_markers[1] = 1;
-		elementfaces[cols*0+0] = 3; elementfaces[cols*0+1] = 0;  elementfaces[cols*0+2] = 1; elementfaces[cols*0+3] = 2;
-		elementfaces[cols*1+0] = 3; elementfaces[cols*1+1] = 3;  elementfaces[cols*1+2] = 4; elementfaces[cols*1+3] = 5;
-		/*3 quads*/
-		elementfaces_markers[2] = 2;
-		elementfaces_markers[3] = 2;
-		elementfaces_markers[4] = 2;
-		elementfaces[cols*2+0] = 4; elementfaces[cols*2+1] = 1;  elementfaces[cols*2+2] = 2; elementfaces[cols*2+3] = 5;  elementfaces[cols*2+4] = 4;
-		elementfaces[cols*3+0] = 4; elementfaces[cols*3+1] = 2;  elementfaces[cols*3+2] = 0; elementfaces[cols*3+3] = 3;  elementfaces[cols*3+4] = 5;
-		elementfaces[cols*4+0] = 4; elementfaces[cols*4+1] = 0;  elementfaces[cols*4+2] = 1; elementfaces[cols*4+3] = 4;  elementfaces[cols*4+4] = 3;
-
-		for(faceid=2;faceid<5;faceid++){
-			counter=0;
-			for(j=0;j<3;j++){
-				for(k=1;k<5;k++){
-					if(iomodel->elements[(elementid-1)*6+elementfaces[cols*faceid+k]] == iomodel->faces[6*facenumber+j]) counter++;
-				}
-			}
-			if(counter==3) break;
-		}
-		if(counter!=3) _error_("face not found in element");
-
-		for(j=0;j<4;j++){
-			facevertices[j]=iomodel->elements[(elementid-1)*6+elementfaces[cols*faceid+j+1]];
-		}
-
-		/*Delete*/
-		xDelete<int>(elementfaces);
-		xDelete<int>(elementfaces_markers);
-	}
-
-	/*Output results*/
-	*pverticesid=facevertices;
-	*pnumvertices=numbervertices;
-}/*}}}*/
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateNodes.cpp	(revision 17989)
@@ -147,5 +147,5 @@
 				FacesPartitioning(&my_faces,iomodel);
 				for(i=0;i<iomodel->numberoffaces;i++){
-					if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+					if(iomodel->faces[i*iomodel->facescols+2]==2){/*Vertical quads*/
 						if(my_faces[i]){
 							node = new Node(id0+i+1,iomodel->numberofvertices+iomodel->numberofedges+i,lid++,0,iomodel,analysis,approximation);
@@ -153,5 +153,5 @@
 						}
 					}
-					else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+					else if(iomodel->faces[i*iomodel->facescols+2]==1){/*Triangular base/top*/
 						/*Nothing*/
 					}
@@ -196,5 +196,5 @@
 			id0 = id0+iomodel->numberofvertices+3*iomodel->numberofedges;
 			for(i=0;i<iomodel->numberoffaces;i++){
-				if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+				if(iomodel->faces[i*iomodel->facescols+2]==2){/*Vertical quads*/
 					if(my_faces[i]){
 						node = new Node(id0+3*i+1,counter+1,lid++,0,iomodel,analysis,approximation);
@@ -207,5 +207,5 @@
 					counter=counter+3;
 				}
-				else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+				else if(iomodel->faces[i*iomodel->facescols+2]==1){/*Triangular base/top*/
 					/*Nothing*/
 				}
@@ -312,5 +312,5 @@
 				FacesPartitioning(&my_faces,iomodel);
 				for(i=0;i<iomodel->numberoffaces;i++){
-					if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+					if(iomodel->faces[i*iomodel->facescols+2]==2){/*Vertical quads*/
 						if(my_faces[i]){
 							node = new Node(id0+i+1,iomodel->numberofvertices+iomodel->numberofedges+i,lid++,0,iomodel,analysis,FSvelocityEnum);
@@ -318,5 +318,5 @@
 						}
 					}
-					else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+					else if(iomodel->faces[i*iomodel->facescols+2]==1){/*Triangular base/top*/
 						/*Nothing*/
 					}
@@ -377,5 +377,5 @@
 			id0 = id0+iomodel->numberofvertices+3*iomodel->numberofedges;
 			for(i=0;i<iomodel->numberoffaces;i++){
-				if(iomodel->faces[i*6+5]==2){/*Vertical quads*/
+				if(iomodel->faces[i*iomodel->facescols+2]==2){/*Vertical quads*/
 					if(my_faces[i]){
 						node = new Node(id0+3*i+1,counter+1,lid++,0,iomodel,analysis,FSvelocityEnum);
@@ -388,5 +388,5 @@
 					counter=counter+3;
 				}
-				else if(iomodel->faces[i*6+5]==1){/*Triangular base/top*/
+				else if(iomodel->faces[i*iomodel->facescols+2]==1){/*Triangular base/top*/
 					/*Nothing*/
 				}
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp	(revision 17989)
@@ -19,8 +19,8 @@
 
 	int         i,j,m,k;
-	int         numoutputs,domaintype,materialtype,smb_model;
+	int         numoutputs,materialtype,smb_model;
 	char**      requestedoutputs = NULL;
 	IssmDouble  time;
-	bool        ispdd,isdelta18o;
+	bool        isdelta18o;
 
 	/*parameters for mass flux:*/
@@ -57,5 +57,4 @@
 	parameters->AddObject(iomodel->CopyConstantObject(MeshAverageVertexConnectivityEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(ConstantsReferencetemperatureEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(BalancethicknessStabilizationEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(GroundinglineMeltingRateEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(SettingsWaitonlockEnum));
@@ -77,5 +76,5 @@
 	parameters->AddObject(iomodel->CopyConstantObject(QmuIsdakotaEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(InversionIscontrolEnum));
-	parameters->AddObject(iomodel->CopyConstantObject(InversionTaoEnum));
+	parameters->AddObject(iomodel->CopyConstantObject(InversionTypeEnum));
 	parameters->AddObject(iomodel->CopyConstantObject(GiaCrossSectionShapeEnum));
 
@@ -219,5 +218,4 @@
 	/*}}}*/
 
-	
 	/*Before returning, create parameters in case we are running Qmu or control types runs: */
 	CreateParametersControl(parameters,iomodel,solution_type);
Index: /issm/trunk/src/c/modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/CreateSingleNodeToElementConnectivity.cpp	(revision 17989)
@@ -29,9 +29,9 @@
 	connectivity=xNewZeroInit<int>(iomodel->numberofvertices);
 
-	/*Get element width (3 or 6)*/
-	switch(iomodel->domaintype){
-		case Domain2DhorizontalEnum: elementswidth=3; break;
-		case Domain2DverticalEnum  : elementswidth=3; break;
-		case Domain3DEnum          : elementswidth=6; break;
+	/*Get element width*/
+	switch(iomodel->meshelementtype){
+		case TriaEnum:  elementswidth=3; break;
+		case PentaEnum: elementswidth=6; break;
+		case TetraEnum: elementswidth=4; break;
 		default:  _error_("mesh type "<<EnumToStringx(iomodel->domaintype)<<" not supported yet");
 	}
Index: /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h
===================================================================
--- /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.h	(revision 17989)
@@ -33,5 +33,5 @@
 void CreateFaces(IoModel* iomodel);
 void CreateFaces3d(IoModel* iomodel);
-void FaceGetVertexIndices(IoModel* iomodel,int* pnumvertices,int** pverticesid,int facenumber);
+void EdgeOnBoundaryFlags(bool** pflags,IoModel* iomodel);
 
 /*Connectivity*/
Index: /issm/trunk/src/c/modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp
===================================================================
--- /issm/trunk/src/c/modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void RheologyBbarAbsGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->RheologyBbarAbsGradient();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=RheologyBbarAbsGradient(element);
 	}
 
@@ -32,2 +28,59 @@
 	*pJ=J;
 }
+
+IssmDouble RheologyBbarAbsGradient(Element* element){
+
+	int         domaintype,numcomponents;
+	IssmDouble  Jelem=0.;
+	IssmDouble  misfit,Jdet;
+	IssmDouble  dp[2],weight;
+	IssmDouble* xyz_list      = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnBase()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   numcomponents   = 1; break;
+		case Domain3DEnum:           numcomponents   = 2; break;
+		case Domain2DhorizontalEnum: numcomponents   = 2; break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn basal element*/
+	Element* basalelement = element->SpawnBasalElement();
+
+	/* Get node coordinates*/
+	basalelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input=basalelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* rheologyb_input=basalelement->GetInput(MaterialsRheologyBbarEnum);                  _assert_(rheologyb_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=basalelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,RheologyBbarAbsGradientEnum);
+		rheologyb_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
+
+		/*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */ 
+		Jelem+=weight*1/2*(dp[0]*dp[0] + dp[1]*dp[1])*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h
===================================================================
--- /issm/trunk/src/c/modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void RheologyBbarAbsGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble RheologyBbarAbsGradient(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void SurfaceAbsVelMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->SurfaceAbsVelMisfit();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=SurfaceAbsVelMisfit(element);
 	}
 
@@ -32,2 +28,81 @@
 	*pJ=J;
 }
+
+IssmDouble SurfaceAbsVelMisfit(Element* element){
+
+	int        domaintype,numcomponents;
+	IssmDouble Jelem=0.;
+	IssmDouble misfit,Jdet;
+	IssmDouble vx,vy,vxobs,vyobs,weight;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnSurface()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   numcomponents   = 1; break;
+		case Domain3DEnum:           numcomponents   = 2; break;
+		case Domain2DhorizontalEnum: numcomponents   = 2; break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn surface element*/
+	Element* topelement = element->SpawnTopElement();
+
+	/* Get node coordinates*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input=topelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input     =topelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vxobs_input  =topelement->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vy_input     = NULL;
+	Input* vyobs_input  = NULL;
+	if(numcomponents==2){
+		vy_input    =topelement->GetInput(VyEnum);              _assert_(vy_input);
+		vyobs_input =topelement->GetInput(InversionVyObsEnum);  _assert_(vyobs_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,SurfaceAbsVelMisfitEnum);
+		vx_input->GetInputValue(&vx,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		if(numcomponents==2){
+			vy_input->GetInputValue(&vy,gauss);
+			vyobs_input->GetInputValue(&vyobs,gauss);
+		}
+
+		/*Compute SurfaceAbsVelMisfitEnum:
+		 *
+		 *      1  [           2              2 ]
+		 * J = --- | (u - u   )  +  (v - v   )  |
+		 *      2  [       obs            obs   ]
+		 *
+		 */
+		misfit=0.5*(vx-vxobs)*(vx-vxobs);
+		if(numcomponents==2) misfit+=0.5*(vy-vyobs)*(vy-vyobs);
+
+		/*Add to cost function*/
+		Jelem+=misfit*weight*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void SurfaceAbsVelMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble SurfaceAbsVelMisfit(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp	(revision 17989)
@@ -11,18 +11,12 @@
 void SurfaceAverageVelMisfitx(IssmDouble* pJ,FemModel* femmodel){
 
-	/*Intermediary*/
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J = 0.;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
-
-	/*Compute surface area and add to elements inputs */
-	SurfaceAreax(NULL,femmodel);
 
 	/*Compute Misfit: */
 	for(int i=0;i<femmodel->elements->Size();i++){
-		element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		J+=element->SurfaceAverageVelMisfit();
+		Element* element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		J+=SurfaceAverageVelMisfit(element);
 	}
 
@@ -35,2 +29,91 @@
 	*pJ=J;
 }
+
+IssmDouble SurfaceAverageVelMisfit(Element* element){
+
+	int        domaintype,numcomponents;
+	IssmDouble Jelem=0.;
+	IssmDouble misfit,S,Jdet;
+	IssmDouble vx,vy,vxobs,vyobs,weight;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnSurface()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:
+			numcomponents   = 1;
+			break;
+		case Domain3DEnum:
+			numcomponents   = 2;
+			break;
+		case Domain2DhorizontalEnum:
+			numcomponents   = 2;
+			break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn surface element*/
+	Element* topelement = element->SpawnTopElement();
+
+	/* Get node coordinates*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	topelement->GetInputValue(&S,SurfaceAreaEnum);
+	Input* weights_input=topelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input     =topelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vxobs_input  =topelement->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vy_input     = NULL;
+	Input* vyobs_input  = NULL;
+	if(numcomponents==2){
+		vy_input    =topelement->GetInput(VyEnum);              _assert_(vy_input);
+		vyobs_input =topelement->GetInput(InversionVyObsEnum);  _assert_(vyobs_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(3);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,SurfaceAverageVelMisfitEnum);
+		vx_input->GetInputValue(&vx,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		if(numcomponents==2){
+			vy_input->GetInputValue(&vy,gauss);
+			vyobs_input->GetInputValue(&vyobs,gauss);
+		}
+
+		/*Compute SurfaceAverageVelMisfitEnum:
+		 *
+		 *      1                    2              2
+		 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
+		 *      S                obs            obs
+		 */
+		if(numcomponents==1){
+			misfit=1/S*(vx-vxobs)*(vx-vxobs);
+		}
+		else{
+			misfit=1/S*sqrt( pow(vx-vxobs,2) + pow(vy-vyobs,2));
+		}
+
+		/*Add to cost function*/
+		Jelem+=misfit*weight*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void SurfaceAverageVelMisfitx(IssmDouble* pJ,FemModel* femmodel);
+IssmDouble SurfaceAverageVelMisfit(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void SurfaceLogVelMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->SurfaceLogVelMisfit();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=SurfaceLogVelMisfit(element);
 	}
 
@@ -32,2 +28,91 @@
 	*pJ=J;
 }
+
+IssmDouble SurfaceLogVelMisfit(Element* element){
+
+	int        domaintype,numcomponents;
+	IssmDouble Jelem=0.;
+	IssmDouble epsvel=2.220446049250313e-16;
+	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
+	IssmDouble velocity_mag,obs_velocity_mag;
+	IssmDouble misfit,Jdet;
+	IssmDouble vx,vy,vxobs,vyobs,weight;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnSurface()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   numcomponents   = 1; break;
+		case Domain3DEnum:           numcomponents   = 2; break;
+		case Domain2DhorizontalEnum: numcomponents   = 2; break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn surface element*/
+	Element* topelement = element->SpawnTopElement();
+
+	/* Get node coordinates*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input=topelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input     =topelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vxobs_input  =topelement->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vy_input     = NULL;
+	Input* vyobs_input  = NULL;
+	if(numcomponents==2){
+		vy_input    =topelement->GetInput(VyEnum);              _assert_(vy_input);
+		vyobs_input =topelement->GetInput(InversionVyObsEnum);  _assert_(vyobs_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,SurfaceLogVelMisfitEnum);
+		vx_input->GetInputValue(&vx,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		if(numcomponents==2){
+			vy_input->GetInputValue(&vy,gauss);
+			vyobs_input->GetInputValue(&vyobs,gauss);
+		}
+
+		/*Compute SurfaceLogVelMisfit:
+		 *                 [        vel + eps     ] 2
+		 * J = 4 \bar{v}^2 | log ( -----------  ) |  
+		 *                 [       vel   + eps    ]
+		 *                            obs
+		 */
+		if(numcomponents==1){
+			velocity_mag    =fabs(vx)+epsvel;
+			obs_velocity_mag=fabs(vxobs)+epsvel;
+		}
+		else{
+			velocity_mag    =sqrt(vx*vx+vy*vy)+epsvel;
+			obs_velocity_mag=sqrt(vxobs*vxobs+vyobs*vyobs)+epsvel;
+		}
+
+		misfit=4*pow(meanvel,2)*pow(log(velocity_mag/obs_velocity_mag),2);
+
+		/*Add to cost function*/
+		Jelem+=misfit*weight*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void SurfaceLogVelMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble SurfaceLogVelMisfit(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void SurfaceLogVxVyMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->SurfaceLogVxVyMisfit();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=SurfaceLogVxVyMisfit(element);
 	}
 
@@ -32,2 +28,90 @@
 	*pJ=J;
 }
+
+IssmDouble SurfaceLogVxVyMisfit(Element* element){
+
+	int        domaintype,numcomponents;
+	IssmDouble Jelem=0.;
+	IssmDouble epsvel=2.220446049250313e-16;
+	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
+	IssmDouble misfit,Jdet;
+	IssmDouble vx,vy,vxobs,vyobs,weight;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnSurface()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   numcomponents   = 1; break;
+		case Domain3DEnum:           numcomponents   = 2; break;
+		case Domain2DhorizontalEnum: numcomponents   = 2; break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn surface element*/
+	Element* topelement = element->SpawnTopElement();
+
+	/* Get node coordinates*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input=topelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input     =topelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vxobs_input  =topelement->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vy_input     = NULL;
+	Input* vyobs_input  = NULL;
+	if(numcomponents==2){
+		vy_input    =topelement->GetInput(VyEnum);              _assert_(vy_input);
+		vyobs_input =topelement->GetInput(InversionVyObsEnum);  _assert_(vyobs_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,SurfaceLogVxVyMisfitEnum);
+		vx_input->GetInputValue(&vx,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		if(numcomponents==2){
+			vy_input->GetInputValue(&vy,gauss);
+			vyobs_input->GetInputValue(&vyobs,gauss);
+		}
+
+		/*Compute SurfaceRelVelMisfit:
+		 *
+		 *      1            [        |u| + eps     2          |v| + eps     2  ]
+		 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   |  
+		 *      2            [       |u    |+ eps              |v    |+ eps     ]
+		 *                              obs                       obs
+		 */
+
+		if(numcomponents==1){
+			misfit=0.5*meanvel*meanvel*pow(log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)),2);
+		}
+		else{
+			misfit=0.5*meanvel*meanvel*(
+						pow(log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)),2) +
+						pow(log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)),2) );
+		}
+
+		/*Add to cost function*/
+		Jelem+=misfit*weight*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void SurfaceLogVxVyMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble SurfaceLogVxVyMisfit(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp
===================================================================
--- /issm/trunk/src/c/modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void SurfaceRelVelMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->SurfaceRelVelMisfit();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=SurfaceRelVelMisfit(element);
 	}
 
@@ -32,2 +28,91 @@
 	*pJ=J;
 }
+
+IssmDouble SurfaceRelVelMisfit(Element* element){
+
+	int        domaintype,numcomponents;
+	IssmDouble Jelem=0.;
+	IssmDouble misfit,Jdet,scalex,scaley;
+	IssmDouble epsvel=2.220446049250313e-16;
+	IssmDouble meanvel=3.170979198376458e-05; /*1000 m/yr*/
+	IssmDouble vx,vy,vxobs,vyobs,weight;
+	IssmDouble* xyz_list = NULL;
+
+	/*Get basal element*/
+	if(!element->IsOnSurface()) return 0.;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/*Get problem dimension*/
+	element->FindParam(&domaintype,DomainTypeEnum);
+	switch(domaintype){
+		case Domain2DverticalEnum:   numcomponents   = 1; break;
+		case Domain3DEnum:           numcomponents   = 2; break;
+		case Domain2DhorizontalEnum: numcomponents   = 2; break;
+		default: _error_("not supported yet");
+	}
+
+	/*Spawn surface element*/
+	Element* topelement = element->SpawnTopElement();
+
+	/* Get node coordinates*/
+	topelement->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input=topelement->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* vx_input     =topelement->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vxobs_input  =topelement->GetInput(InversionVxObsEnum);                     _assert_(vxobs_input);
+	Input* vy_input     = NULL;
+	Input* vyobs_input  = NULL;
+	if(numcomponents==2){
+		vy_input    =topelement->GetInput(VyEnum);              _assert_(vy_input);
+		vyobs_input =topelement->GetInput(InversionVyObsEnum);  _assert_(vyobs_input);
+	}
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=topelement->NewGauss(4);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		topelement->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,SurfaceRelVelMisfitEnum);
+		vx_input->GetInputValue(&vx,gauss);
+		vxobs_input->GetInputValue(&vxobs,gauss);
+		if(numcomponents==2){
+			vy_input->GetInputValue(&vy,gauss);
+			vyobs_input->GetInputValue(&vyobs,gauss);
+		}
+
+		/*Compute SurfaceRelVelMisfit:
+		 *                        
+		 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
+		 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
+		 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
+		 *              obs                        obs                      
+		 */
+
+		if(numcomponents==2){
+			scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
+			scaley=pow(meanvel/(vyobs+epsvel),2); if(vyobs==0)scaley=0;
+			misfit=0.5*(scalex*pow((vx-vxobs),2)+scaley*pow((vy-vyobs),2));
+		}
+		else{
+			scalex=pow(meanvel/(vxobs+epsvel),2); if(vxobs==0)scalex=0;
+			misfit=0.5*(scalex*pow((vx-vxobs),2));
+		}
+
+		/*Add to cost function*/
+		Jelem+=misfit*weight*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	if(domaintype!=Domain2DhorizontalEnum){topelement->DeleteMaterials(); delete topelement;};
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h
===================================================================
--- /issm/trunk/src/c/modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void SurfaceRelVelMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble SurfaceRelVelMisfit(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp
===================================================================
--- /issm/trunk/src/c/modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void ThicknessAbsMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->ThicknessAbsMisfit();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=ThicknessAbsMisfit(element);
 	}
 
@@ -32,2 +28,44 @@
 	*pJ=J;
 }
+
+IssmDouble ThicknessAbsMisfit(Element* element){
+
+	IssmDouble  thickness,thicknessobs,weight;
+	IssmDouble  Jelem=0.;
+	IssmDouble  misfit,Jdet;
+	IssmDouble* xyz_list = NULL;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/* Get node coordinates*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input     =element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* thickness_input   =element->GetInput(ThicknessEnum);                          _assert_(thickness_input);
+	Input* thicknessobs_input=element->GetInput(InversionThicknessObsEnum);              _assert_(thicknessobs_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,ThicknessAbsMisfitEnum);
+		thickness_input->GetInputValue(&thickness,gauss);
+		thicknessobs_input->GetInputValue(&thicknessobs,gauss);
+
+		/*Compute ThicknessAbsMisfitEnum*/
+		Jelem+=0.5*(thickness-thicknessobs)*(thickness-thicknessobs)*weight*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h
===================================================================
--- /issm/trunk/src/c/modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void ThicknessAbsMisfitx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble ThicknessAbsMisfit(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp
===================================================================
--- /issm/trunk/src/c/modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void ThicknessAcrossGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->ThicknessAcrossGradient();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=ThicknessAcrossGradient(element);
 	}
 
@@ -32,2 +28,52 @@
 	*pJ=J;
 }
+
+IssmDouble ThicknessAcrossGradient(Element* element){
+
+	IssmDouble  thickness,thicknessobs,weight;
+	IssmDouble  Jelem=0.;
+	IssmDouble  misfit,Jdet;
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  dp[3];
+	IssmDouble  vx,vy,vel;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/* Get node coordinates*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input   =element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* thickness_input =element->GetInput(ThicknessEnum);                          _assert_(thickness_input);
+	Input* vx_input        =element->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input        =element->GetInput(VyEnum);                                 _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,ThicknessAcrossGradientEnum);
+		thickness_input->GetInputValue(&thickness,gauss);
+		thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vel = sqrt(vx*vx+vy*vy);
+		vx  = vx/(vel+1.e-9);
+		vy  = vy/(vel+1.e-9);
+
+		/*J = 1/2 ( -vy*dH/dx + vx*dH/dy )^2 */
+		Jelem+=weight*1/2*(-vy*dp[0] + vx*dp[1])*(-vy*dp[0] + vx*dp[1])*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.h
===================================================================
--- /issm/trunk/src/c/modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void ThicknessAcrossGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble ThicknessAcrossGradient(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp
===================================================================
--- /issm/trunk/src/c/modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp	(revision 17988)
+++ /issm/trunk/src/c/modules/ThicknessAlongGradientx/ThicknessAlongGradientx.cpp	(revision 17989)
@@ -10,16 +10,12 @@
 void ThicknessAlongGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials,Parameters* parameters){
 
-	/*Intermediary*/
-	int i;
-	Element* element=NULL;
-
 	/*output: */
-	IssmDouble J=0;
+	IssmDouble J=0.;
 	IssmDouble J_sum;
 
 	/*Compute Misfit: */
-	for (i=0;i<elements->Size();i++){
-		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
-		J+=element->ThicknessAlongGradient();
+	for(int i=0;i<elements->Size();i++){
+		Element* element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
+		J+=ThicknessAlongGradient(element);
 	}
 
@@ -32,2 +28,52 @@
 	*pJ=J;
 }
+
+IssmDouble ThicknessAlongGradient(Element* element){
+
+	IssmDouble  thickness,thicknessobs,weight;
+	IssmDouble  Jelem=0.;
+	IssmDouble  misfit,Jdet;
+	IssmDouble* xyz_list = NULL;
+	IssmDouble  dp[3];
+	IssmDouble  vx,vy,vel;
+
+	/*If on water, return 0: */
+	if(!element->IsIceInElement()) return 0.;
+
+	/* Get node coordinates*/
+	element->GetVerticesCoordinates(&xyz_list);
+
+	/*Retrieve all inputs we will be needing: */
+	Input* weights_input   =element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
+	Input* thickness_input =element->GetInput(ThicknessEnum);                          _assert_(thickness_input);
+	Input* vx_input        =element->GetInput(VxEnum);                                 _assert_(vx_input);
+	Input* vy_input        =element->GetInput(VyEnum);                                 _assert_(vy_input);
+
+	/* Start  looping on the number of gaussian points: */
+	Gauss* gauss=element->NewGauss(2);
+	for(int ig=gauss->begin();ig<gauss->end();ig++){
+
+		gauss->GaussPoint(ig);
+
+		/* Get Jacobian determinant: */
+		element->JacobianDeterminant(&Jdet,xyz_list,gauss);
+
+		/*Get all parameters at gaussian point*/
+		weights_input->GetInputValue(&weight,gauss,ThicknessAlongGradientEnum);
+		thickness_input->GetInputValue(&thickness,gauss);
+		thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
+		vx_input->GetInputValue(&vx,gauss);
+		vy_input->GetInputValue(&vy,gauss);
+		vel = sqrt(vx*vx+vy*vy);
+		vx  = vx/(vel+1.e-9);
+		vy  = vy/(vel+1.e-9);
+
+		/*J = 1/2 ( vx*dH/dx + vy*dH/dy )^2 */
+		Jelem+=weight*1/2*(vx*dp[0] + vy*dp[1])*(vx*dp[0] + vy*dp[1])*Jdet*gauss->weight;
+	}
+
+	/*clean up and Return: */
+	xDelete<IssmDouble>(xyz_list);
+	delete gauss;
+	return Jelem;
+}
Index: /issm/trunk/src/c/modules/ThicknessAlongGradientx/ThicknessAlongGradientx.h
===================================================================
--- /issm/trunk/src/c/modules/ThicknessAlongGradientx/ThicknessAlongGradientx.h	(revision 17988)
+++ /issm/trunk/src/c/modules/ThicknessAlongGradientx/ThicknessAlongGradientx.h	(revision 17989)
@@ -10,4 +10,5 @@
 /* local prototypes: */
 void ThicknessAlongGradientx( IssmDouble* pJ, Elements* elements,Nodes* nodes, Vertices* vertices, Loads* loads, Materials* materials, Parameters* parameters);
+IssmDouble ThicknessAlongGradient(Element* element);
 
 #endif
Index: /issm/trunk/src/c/modules/modules.h
===================================================================
--- /issm/trunk/src/c/modules/modules.h	(revision 17988)
+++ /issm/trunk/src/c/modules/modules.h	(revision 17989)
@@ -14,6 +14,4 @@
 #include "./BamgTriangulatex/BamgTriangulatex.h"
 #include "./Chacox/Chacox.h"
-#include "./ComputeBasalStressx/ComputeBasalStressx.h"
-#include "./ComputeStrainRatex/ComputeStrainRatex.h"
 #include "./ConfigureObjectsx/ConfigureObjectsx.h"
 #include "./ContourToMeshx/ContourToMeshx.h"
@@ -37,5 +35,7 @@
 #include "./HoleFillerx/HoleFillerx.h"
 #include "./InputControlUpdatex/InputControlUpdatex.h"
+#include "./InputDepthAverageAtBasex/InputDepthAverageAtBasex.h"
 #include "./InputDuplicatex/InputDuplicatex.h"
+#include "./InputExtrudex/InputExtrudex.h"
 #include "./InputScalex/InputScalex.h"
 #include "./InterpFromMesh2dx/InterpFromMesh2dx.h"
@@ -77,5 +77,4 @@
 #include "./PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.h"
 #include "./Reduceloadx/Reduceloadx.h"
-#include "./Reducevectorgtosx/Reducevectorgtosx.h"
 #include "./Reducevectorgtofx/Reducevectorgtofx.h"
 #include "./ResetConstraintsx/ResetConstraintsx.h"
Index: /issm/trunk/src/c/shared/Enum/EnumDefinitions.h
===================================================================
--- /issm/trunk/src/c/shared/Enum/EnumDefinitions.h	(revision 17988)
+++ /issm/trunk/src/c/shared/Enum/EnumDefinitions.h	(revision 17989)
@@ -84,12 +84,10 @@
 	FrictionPEnum,
 	FrictionQEnum,
+	FrictionMEnum,
+	FrictionCEnum,
+	FrictionLawEnum,
 	GeometryHydrostaticRatioEnum,
 	HydrologyModelEnum,
 	HydrologyshreveEnum,
-	HydrologyshreveCREnum,
-	HydrologyshreveKnEnum,
-	HydrologyshreveNEnum,
-	HydrologyshrevePEnum,
-	HydrologyshreveQEnum,
 	HydrologyshreveSpcwatercolumnEnum,
 	HydrologyshreveStabilizationEnum,
@@ -101,5 +99,5 @@
 	EplHeadEnum,
 	EplHeadOldEnum,
-  EplHeadSlopeXEnum,
+	EplHeadSlopeXEnum,
 	EplHeadSlopeYEnum,
 	HydrologydcMaxIterEnum,
@@ -140,10 +138,19 @@
 	InversionGradientScalingEnum,
 	InversionIscontrolEnum,
-	InversionTaoEnum,
+	InversionTypeEnum,
 	InversionIncompleteAdjointEnum,
 	InversionMaxParametersEnum,
 	InversionMaxiterPerStepEnum,
+	InversionMaxiterEnum,
+	InversionMaxstepsEnum,
+	InversionFatolEnum,
+	InversionFrtolEnum,
+	InversionGatolEnum,
+	InversionGrtolEnum,
+	InversionGttolEnum,
+	InversionAlgorithmEnum,
 	InversionMinParametersEnum,
 	InversionNstepsEnum,
+	InversionDxminEnum,
 	InversionNumControlParametersEnum,
 	InversionNumCostFunctionsEnum,
@@ -188,5 +195,5 @@
 	DamageEvolutionRequestedOutputsEnum,
 	MaterialsRhoIceEnum,
-	MaterialsRhoWaterEnum,
+	MaterialsRhoSeawaterEnum,
 	MaterialsRhoFreshwaterEnum,
 	MaterialsMuWaterEnum,
@@ -199,6 +206,4 @@
 	MaterialsMantleDensityEnum,
 	MeshAverageVertexConnectivityEnum,
-	MeshElementonbaseEnum,
-	MeshElementonsurfaceEnum,
 	MeshElements2dEnum,
 	MeshElementsEnum,
@@ -212,4 +217,5 @@
 	MeshVertexonbaseEnum,
 	MeshVertexonsurfaceEnum,
+	MeshVertexonboundaryEnum,
 	MeshXEnum,
 	MeshYEnum,
@@ -249,5 +255,4 @@
 	SettingsOutputFrequencyEnum,
 	SettingsWaitonlockEnum,
-
 	DebugProfilingEnum,
 	ProfilingCurrentMemEnum,
@@ -260,5 +265,4 @@
 	SteadystateRequestedOutputsEnum,
 	SurfaceEnum,
-
 	ThermalIsenthalpyEnum,
 	ThermalIsdynamicbasalspcEnum,
@@ -279,4 +283,5 @@
 	TimesteppingTimeAdaptEnum,
 	TimesteppingTimeStepEnum,
+	TimesteppingInterpForcingsEnum,
 	TransientIsstressbalanceEnum,
 	TransientIsgroundinglineEnum,
@@ -288,4 +293,13 @@
 	TransientNumRequestedOutputsEnum,
 	TransientRequestedOutputsEnum,
+	PotentialEnum,
+	BalancethicknessSpcpotentialEnum,
+	BalancethicknessApparentMassbalanceEnum,
+	Balancethickness2MisfitEnum,
+	BalancethicknessNuxEnum,
+	BalancethicknessNuyEnum,
+	BalancethicknessVxObsEnum,
+	BalancethicknessVyObsEnum,
+	BalancethicknessThicknessObsEnum,
 	/*}}}*/
 	/*Surfaceforcings{{{*/
@@ -319,4 +333,5 @@
 	ConfigurationTypeEnum,
 	AdjointBalancethicknessAnalysisEnum,
+	AdjointBalancethickness2AnalysisEnum,
 	AdjointHorizAnalysisEnum,
 	AnalysisCounterEnum,
@@ -324,4 +339,6 @@
 	BalancethicknessAnalysisEnum,
 	BalancethicknessSolutionEnum,
+	Balancethickness2AnalysisEnum,
+	Balancethickness2SolutionEnum,
 	BalancethicknessSoftAnalysisEnum,
 	BalancethicknessSoftSolutionEnum,
@@ -637,5 +654,5 @@
 	/*Grounding Line{{{*/
 	NoneEnum,
-	AgressiveMigrationEnum,
+	AggressiveMigrationEnum,
 	SoftMigrationEnum,
 	SubelementMigrationEnum,
Index: /issm/trunk/src/c/shared/Enum/EnumToStringx.cpp
===================================================================
--- /issm/trunk/src/c/shared/Enum/EnumToStringx.cpp	(revision 17988)
+++ /issm/trunk/src/c/shared/Enum/EnumToStringx.cpp	(revision 17989)
@@ -92,12 +92,10 @@
 		case FrictionPEnum : return "FrictionP";
 		case FrictionQEnum : return "FrictionQ";
+		case FrictionMEnum : return "FrictionM";
+		case FrictionCEnum : return "FrictionC";
+		case FrictionLawEnum : return "FrictionLaw";
 		case GeometryHydrostaticRatioEnum : return "GeometryHydrostaticRatio";
 		case HydrologyModelEnum : return "HydrologyModel";
 		case HydrologyshreveEnum : return "Hydrologyshreve";
-		case HydrologyshreveCREnum : return "HydrologyshreveCR";
-		case HydrologyshreveKnEnum : return "HydrologyshreveKn";
-		case HydrologyshreveNEnum : return "HydrologyshreveN";
-		case HydrologyshrevePEnum : return "HydrologyshreveP";
-		case HydrologyshreveQEnum : return "HydrologyshreveQ";
 		case HydrologyshreveSpcwatercolumnEnum : return "HydrologyshreveSpcwatercolumn";
 		case HydrologyshreveStabilizationEnum : return "HydrologyshreveStabilization";
@@ -148,10 +146,19 @@
 		case InversionGradientScalingEnum : return "InversionGradientScaling";
 		case InversionIscontrolEnum : return "InversionIscontrol";
-		case InversionTaoEnum : return "InversionTao";
+		case InversionTypeEnum : return "InversionType";
 		case InversionIncompleteAdjointEnum : return "InversionIncompleteAdjoint";
 		case InversionMaxParametersEnum : return "InversionMaxParameters";
 		case InversionMaxiterPerStepEnum : return "InversionMaxiterPerStep";
+		case InversionMaxiterEnum : return "InversionMaxiter";
+		case InversionMaxstepsEnum : return "InversionMaxsteps";
+		case InversionFatolEnum : return "InversionFatol";
+		case InversionFrtolEnum : return "InversionFrtol";
+		case InversionGatolEnum : return "InversionGatol";
+		case InversionGrtolEnum : return "InversionGrtol";
+		case InversionGttolEnum : return "InversionGttol";
+		case InversionAlgorithmEnum : return "InversionAlgorithm";
 		case InversionMinParametersEnum : return "InversionMinParameters";
 		case InversionNstepsEnum : return "InversionNsteps";
+		case InversionDxminEnum : return "InversionDxmin";
 		case InversionNumControlParametersEnum : return "InversionNumControlParameters";
 		case InversionNumCostFunctionsEnum : return "InversionNumCostFunctions";
@@ -196,5 +203,5 @@
 		case DamageEvolutionRequestedOutputsEnum : return "DamageEvolutionRequestedOutputs";
 		case MaterialsRhoIceEnum : return "MaterialsRhoIce";
-		case MaterialsRhoWaterEnum : return "MaterialsRhoWater";
+		case MaterialsRhoSeawaterEnum : return "MaterialsRhoSeawater";
 		case MaterialsRhoFreshwaterEnum : return "MaterialsRhoFreshwater";
 		case MaterialsMuWaterEnum : return "MaterialsMuWater";
@@ -207,6 +214,4 @@
 		case MaterialsMantleDensityEnum : return "MaterialsMantleDensity";
 		case MeshAverageVertexConnectivityEnum : return "MeshAverageVertexConnectivity";
-		case MeshElementonbaseEnum : return "MeshElementonbase";
-		case MeshElementonsurfaceEnum : return "MeshElementonsurface";
 		case MeshElements2dEnum : return "MeshElements2d";
 		case MeshElementsEnum : return "MeshElements";
@@ -220,4 +225,5 @@
 		case MeshVertexonbaseEnum : return "MeshVertexonbase";
 		case MeshVertexonsurfaceEnum : return "MeshVertexonsurface";
+		case MeshVertexonboundaryEnum : return "MeshVertexonboundary";
 		case MeshXEnum : return "MeshX";
 		case MeshYEnum : return "MeshY";
@@ -285,4 +291,5 @@
 		case TimesteppingTimeAdaptEnum : return "TimesteppingTimeAdapt";
 		case TimesteppingTimeStepEnum : return "TimesteppingTimeStep";
+		case TimesteppingInterpForcingsEnum : return "TimesteppingInterpForcings";
 		case TransientIsstressbalanceEnum : return "TransientIsstressbalance";
 		case TransientIsgroundinglineEnum : return "TransientIsgroundingline";
@@ -294,4 +301,13 @@
 		case TransientNumRequestedOutputsEnum : return "TransientNumRequestedOutputs";
 		case TransientRequestedOutputsEnum : return "TransientRequestedOutputs";
+		case PotentialEnum : return "Potential";
+		case BalancethicknessSpcpotentialEnum : return "BalancethicknessSpcpotential";
+		case BalancethicknessApparentMassbalanceEnum : return "BalancethicknessApparentMassbalance";
+		case Balancethickness2MisfitEnum : return "Balancethickness2Misfit";
+		case BalancethicknessNuxEnum : return "BalancethicknessNux";
+		case BalancethicknessNuyEnum : return "BalancethicknessNuy";
+		case BalancethicknessVxObsEnum : return "BalancethicknessVxObs";
+		case BalancethicknessVyObsEnum : return "BalancethicknessVyObs";
+		case BalancethicknessThicknessObsEnum : return "BalancethicknessThicknessObs";
 		case SurfaceforcingsEnum : return "Surfaceforcings";
 		case SMBEnum : return "SMB";
@@ -320,4 +336,5 @@
 		case ConfigurationTypeEnum : return "ConfigurationType";
 		case AdjointBalancethicknessAnalysisEnum : return "AdjointBalancethicknessAnalysis";
+		case AdjointBalancethickness2AnalysisEnum : return "AdjointBalancethickness2Analysis";
 		case AdjointHorizAnalysisEnum : return "AdjointHorizAnalysis";
 		case AnalysisCounterEnum : return "AnalysisCounter";
@@ -325,4 +342,6 @@
 		case BalancethicknessAnalysisEnum : return "BalancethicknessAnalysis";
 		case BalancethicknessSolutionEnum : return "BalancethicknessSolution";
+		case Balancethickness2AnalysisEnum : return "Balancethickness2Analysis";
+		case Balancethickness2SolutionEnum : return "Balancethickness2Solution";
 		case BalancethicknessSoftAnalysisEnum : return "BalancethicknessSoftAnalysis";
 		case BalancethicknessSoftSolutionEnum : return "BalancethicknessSoftSolution";
@@ -614,5 +633,5 @@
 		case AugmentedLagrangianThetaEnum : return "AugmentedLagrangianTheta";
 		case NoneEnum : return "None";
-		case AgressiveMigrationEnum : return "AgressiveMigration";
+		case AggressiveMigrationEnum : return "AggressiveMigration";
 		case SoftMigrationEnum : return "SoftMigration";
 		case SubelementMigrationEnum : return "SubelementMigration";
Index: /issm/trunk/src/c/shared/Enum/StringToEnumx.cpp
===================================================================
--- /issm/trunk/src/c/shared/Enum/StringToEnumx.cpp	(revision 17988)
+++ /issm/trunk/src/c/shared/Enum/StringToEnumx.cpp	(revision 17989)
@@ -92,12 +92,10 @@
 	      else if (strcmp(name,"FrictionP")==0) return FrictionPEnum;
 	      else if (strcmp(name,"FrictionQ")==0) return FrictionQEnum;
+	      else if (strcmp(name,"FrictionM")==0) return FrictionMEnum;
+	      else if (strcmp(name,"FrictionC")==0) return FrictionCEnum;
+	      else if (strcmp(name,"FrictionLaw")==0) return FrictionLawEnum;
 	      else if (strcmp(name,"GeometryHydrostaticRatio")==0) return GeometryHydrostaticRatioEnum;
 	      else if (strcmp(name,"HydrologyModel")==0) return HydrologyModelEnum;
 	      else if (strcmp(name,"Hydrologyshreve")==0) return HydrologyshreveEnum;
-	      else if (strcmp(name,"HydrologyshreveCR")==0) return HydrologyshreveCREnum;
-	      else if (strcmp(name,"HydrologyshreveKn")==0) return HydrologyshreveKnEnum;
-	      else if (strcmp(name,"HydrologyshreveN")==0) return HydrologyshreveNEnum;
-	      else if (strcmp(name,"HydrologyshreveP")==0) return HydrologyshrevePEnum;
-	      else if (strcmp(name,"HydrologyshreveQ")==0) return HydrologyshreveQEnum;
 	      else if (strcmp(name,"HydrologyshreveSpcwatercolumn")==0) return HydrologyshreveSpcwatercolumnEnum;
 	      else if (strcmp(name,"HydrologyshreveStabilization")==0) return HydrologyshreveStabilizationEnum;
@@ -137,10 +135,10 @@
 	      else if (strcmp(name,"HydrologydcPenaltyLock")==0) return HydrologydcPenaltyLockEnum;
 	      else if (strcmp(name,"HydrologydcBasalMoulinInput")==0) return HydrologydcBasalMoulinInputEnum;
+	      else if (strcmp(name,"HydrologyLayer")==0) return HydrologyLayerEnum;
+	      else if (strcmp(name,"HydrologySediment")==0) return HydrologySedimentEnum;
          else stage=2;
    }
    if(stage==2){
-	      if (strcmp(name,"HydrologyLayer")==0) return HydrologyLayerEnum;
-	      else if (strcmp(name,"HydrologySediment")==0) return HydrologySedimentEnum;
-	      else if (strcmp(name,"HydrologyEfficient")==0) return HydrologyEfficientEnum;
+	      if (strcmp(name,"HydrologyEfficient")==0) return HydrologyEfficientEnum;
 	      else if (strcmp(name,"HydrologySedimentKmax")==0) return HydrologySedimentKmaxEnum;
 	      else if (strcmp(name,"IndependentObject")==0) return IndependentObjectEnum;
@@ -151,10 +149,19 @@
 	      else if (strcmp(name,"InversionGradientScaling")==0) return InversionGradientScalingEnum;
 	      else if (strcmp(name,"InversionIscontrol")==0) return InversionIscontrolEnum;
-	      else if (strcmp(name,"InversionTao")==0) return InversionTaoEnum;
+	      else if (strcmp(name,"InversionType")==0) return InversionTypeEnum;
 	      else if (strcmp(name,"InversionIncompleteAdjoint")==0) return InversionIncompleteAdjointEnum;
 	      else if (strcmp(name,"InversionMaxParameters")==0) return InversionMaxParametersEnum;
 	      else if (strcmp(name,"InversionMaxiterPerStep")==0) return InversionMaxiterPerStepEnum;
+	      else if (strcmp(name,"InversionMaxiter")==0) return InversionMaxiterEnum;
+	      else if (strcmp(name,"InversionMaxsteps")==0) return InversionMaxstepsEnum;
+	      else if (strcmp(name,"InversionFatol")==0) return InversionFatolEnum;
+	      else if (strcmp(name,"InversionFrtol")==0) return InversionFrtolEnum;
+	      else if (strcmp(name,"InversionGatol")==0) return InversionGatolEnum;
+	      else if (strcmp(name,"InversionGrtol")==0) return InversionGrtolEnum;
+	      else if (strcmp(name,"InversionGttol")==0) return InversionGttolEnum;
+	      else if (strcmp(name,"InversionAlgorithm")==0) return InversionAlgorithmEnum;
 	      else if (strcmp(name,"InversionMinParameters")==0) return InversionMinParametersEnum;
 	      else if (strcmp(name,"InversionNsteps")==0) return InversionNstepsEnum;
+	      else if (strcmp(name,"InversionDxmin")==0) return InversionDxminEnum;
 	      else if (strcmp(name,"InversionNumControlParameters")==0) return InversionNumControlParametersEnum;
 	      else if (strcmp(name,"InversionNumCostFunctions")==0) return InversionNumCostFunctionsEnum;
@@ -199,5 +206,5 @@
 	      else if (strcmp(name,"DamageEvolutionRequestedOutputs")==0) return DamageEvolutionRequestedOutputsEnum;
 	      else if (strcmp(name,"MaterialsRhoIce")==0) return MaterialsRhoIceEnum;
-	      else if (strcmp(name,"MaterialsRhoWater")==0) return MaterialsRhoWaterEnum;
+	      else if (strcmp(name,"MaterialsRhoSeawater")==0) return MaterialsRhoSeawaterEnum;
 	      else if (strcmp(name,"MaterialsRhoFreshwater")==0) return MaterialsRhoFreshwaterEnum;
 	      else if (strcmp(name,"MaterialsMuWater")==0) return MaterialsMuWaterEnum;
@@ -210,6 +217,4 @@
 	      else if (strcmp(name,"MaterialsMantleDensity")==0) return MaterialsMantleDensityEnum;
 	      else if (strcmp(name,"MeshAverageVertexConnectivity")==0) return MeshAverageVertexConnectivityEnum;
-	      else if (strcmp(name,"MeshElementonbase")==0) return MeshElementonbaseEnum;
-	      else if (strcmp(name,"MeshElementonsurface")==0) return MeshElementonsurfaceEnum;
 	      else if (strcmp(name,"MeshElements2d")==0) return MeshElements2dEnum;
 	      else if (strcmp(name,"MeshElements")==0) return MeshElementsEnum;
@@ -223,4 +228,5 @@
 	      else if (strcmp(name,"MeshVertexonbase")==0) return MeshVertexonbaseEnum;
 	      else if (strcmp(name,"MeshVertexonsurface")==0) return MeshVertexonsurfaceEnum;
+	      else if (strcmp(name,"MeshVertexonboundary")==0) return MeshVertexonboundaryEnum;
 	      else if (strcmp(name,"MeshX")==0) return MeshXEnum;
 	      else if (strcmp(name,"MeshY")==0) return MeshYEnum;
@@ -254,5 +260,8 @@
 	      else if (strcmp(name,"QmuMaterialsRheologyB")==0) return QmuMaterialsRheologyBEnum;
 	      else if (strcmp(name,"RiftsNumrifts")==0) return RiftsNumriftsEnum;
-	      else if (strcmp(name,"RiftsRiftstruct")==0) return RiftsRiftstructEnum;
+         else stage=3;
+   }
+   if(stage==3){
+	      if (strcmp(name,"RiftsRiftstruct")==0) return RiftsRiftstructEnum;
 	      else if (strcmp(name,"SettingsResultsOnNodes")==0) return SettingsResultsOnNodesEnum;
 	      else if (strcmp(name,"SettingsIoGather")==0) return SettingsIoGatherEnum;
@@ -260,8 +269,5 @@
 	      else if (strcmp(name,"SettingsOutputFrequency")==0) return SettingsOutputFrequencyEnum;
 	      else if (strcmp(name,"SettingsWaitonlock")==0) return SettingsWaitonlockEnum;
-         else stage=3;
-   }
-   if(stage==3){
-	      if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
+	      else if (strcmp(name,"DebugProfiling")==0) return DebugProfilingEnum;
 	      else if (strcmp(name,"ProfilingCurrentMem")==0) return ProfilingCurrentMemEnum;
 	      else if (strcmp(name,"ProfilingCurrentFlops")==0) return ProfilingCurrentFlopsEnum;
@@ -291,4 +297,5 @@
 	      else if (strcmp(name,"TimesteppingTimeAdapt")==0) return TimesteppingTimeAdaptEnum;
 	      else if (strcmp(name,"TimesteppingTimeStep")==0) return TimesteppingTimeStepEnum;
+	      else if (strcmp(name,"TimesteppingInterpForcings")==0) return TimesteppingInterpForcingsEnum;
 	      else if (strcmp(name,"TransientIsstressbalance")==0) return TransientIsstressbalanceEnum;
 	      else if (strcmp(name,"TransientIsgroundingline")==0) return TransientIsgroundinglineEnum;
@@ -300,4 +307,13 @@
 	      else if (strcmp(name,"TransientNumRequestedOutputs")==0) return TransientNumRequestedOutputsEnum;
 	      else if (strcmp(name,"TransientRequestedOutputs")==0) return TransientRequestedOutputsEnum;
+	      else if (strcmp(name,"Potential")==0) return PotentialEnum;
+	      else if (strcmp(name,"BalancethicknessSpcpotential")==0) return BalancethicknessSpcpotentialEnum;
+	      else if (strcmp(name,"BalancethicknessApparentMassbalance")==0) return BalancethicknessApparentMassbalanceEnum;
+	      else if (strcmp(name,"Balancethickness2Misfit")==0) return Balancethickness2MisfitEnum;
+	      else if (strcmp(name,"BalancethicknessNux")==0) return BalancethicknessNuxEnum;
+	      else if (strcmp(name,"BalancethicknessNuy")==0) return BalancethicknessNuyEnum;
+	      else if (strcmp(name,"BalancethicknessVxObs")==0) return BalancethicknessVxObsEnum;
+	      else if (strcmp(name,"BalancethicknessVyObs")==0) return BalancethicknessVyObsEnum;
+	      else if (strcmp(name,"BalancethicknessThicknessObs")==0) return BalancethicknessThicknessObsEnum;
 	      else if (strcmp(name,"Surfaceforcings")==0) return SurfaceforcingsEnum;
 	      else if (strcmp(name,"SMB")==0) return SMBEnum;
@@ -326,4 +342,5 @@
 	      else if (strcmp(name,"ConfigurationType")==0) return ConfigurationTypeEnum;
 	      else if (strcmp(name,"AdjointBalancethicknessAnalysis")==0) return AdjointBalancethicknessAnalysisEnum;
+	      else if (strcmp(name,"AdjointBalancethickness2Analysis")==0) return AdjointBalancethickness2AnalysisEnum;
 	      else if (strcmp(name,"AdjointHorizAnalysis")==0) return AdjointHorizAnalysisEnum;
 	      else if (strcmp(name,"AnalysisCounter")==0) return AnalysisCounterEnum;
@@ -331,4 +348,6 @@
 	      else if (strcmp(name,"BalancethicknessAnalysis")==0) return BalancethicknessAnalysisEnum;
 	      else if (strcmp(name,"BalancethicknessSolution")==0) return BalancethicknessSolutionEnum;
+	      else if (strcmp(name,"Balancethickness2Analysis")==0) return Balancethickness2AnalysisEnum;
+	      else if (strcmp(name,"Balancethickness2Solution")==0) return Balancethickness2SolutionEnum;
 	      else if (strcmp(name,"BalancethicknessSoftAnalysis")==0) return BalancethicknessSoftAnalysisEnum;
 	      else if (strcmp(name,"BalancethicknessSoftSolution")==0) return BalancethicknessSoftSolutionEnum;
@@ -364,5 +383,8 @@
 	      else if (strcmp(name,"SmoothedSurfaceSlopeXAnalysis")==0) return SmoothedSurfaceSlopeXAnalysisEnum;
 	      else if (strcmp(name,"SmoothedSurfaceSlopeYAnalysis")==0) return SmoothedSurfaceSlopeYAnalysisEnum;
-	      else if (strcmp(name,"ThermalAnalysis")==0) return ThermalAnalysisEnum;
+         else stage=4;
+   }
+   if(stage==4){
+	      if (strcmp(name,"ThermalAnalysis")==0) return ThermalAnalysisEnum;
 	      else if (strcmp(name,"ThermalSolution")==0) return ThermalSolutionEnum;
 	      else if (strcmp(name,"TransientSolution")==0) return TransientSolutionEnum;
@@ -383,8 +405,5 @@
 	      else if (strcmp(name,"HOApproximation")==0) return HOApproximationEnum;
 	      else if (strcmp(name,"HOFSApproximation")==0) return HOFSApproximationEnum;
-         else stage=4;
-   }
-   if(stage==4){
-	      if (strcmp(name,"FSApproximation")==0) return FSApproximationEnum;
+	      else if (strcmp(name,"FSApproximation")==0) return FSApproximationEnum;
 	      else if (strcmp(name,"FSvelocity")==0) return FSvelocityEnum;
 	      else if (strcmp(name,"FSpressure")==0) return FSpressureEnum;
@@ -487,5 +506,8 @@
 	      else if (strcmp(name,"QmuBase")==0) return QmuBaseEnum;
 	      else if (strcmp(name,"QmuSurface")==0) return QmuSurfaceEnum;
-	      else if (strcmp(name,"QmuMelting")==0) return QmuMeltingEnum;
+         else stage=5;
+   }
+   if(stage==5){
+	      if (strcmp(name,"QmuMelting")==0) return QmuMeltingEnum;
 	      else if (strcmp(name,"QmuVxMesh")==0) return QmuVxMeshEnum;
 	      else if (strcmp(name,"QmuVyMesh")==0) return QmuVyMeshEnum;
@@ -506,8 +528,5 @@
 	      else if (strcmp(name,"ThicknessAbsMisfit")==0) return ThicknessAbsMisfitEnum;
 	      else if (strcmp(name,"Vel")==0) return VelEnum;
-         else stage=5;
-   }
-   if(stage==5){
-	      if (strcmp(name,"Velocity")==0) return VelocityEnum;
+	      else if (strcmp(name,"Velocity")==0) return VelocityEnum;
 	      else if (strcmp(name,"VxAverage")==0) return VxAverageEnum;
 	      else if (strcmp(name,"Vx")==0) return VxEnum;
@@ -610,5 +629,8 @@
 	      else if (strcmp(name,"MaxVel")==0) return MaxVelEnum;
 	      else if (strcmp(name,"MinVx")==0) return MinVxEnum;
-	      else if (strcmp(name,"MaxVx")==0) return MaxVxEnum;
+         else stage=6;
+   }
+   if(stage==6){
+	      if (strcmp(name,"MaxVx")==0) return MaxVxEnum;
 	      else if (strcmp(name,"MaxAbsVx")==0) return MaxAbsVxEnum;
 	      else if (strcmp(name,"MinVy")==0) return MinVyEnum;
@@ -626,11 +648,8 @@
 	      else if (strcmp(name,"AugmentedLagrangianTheta")==0) return AugmentedLagrangianThetaEnum;
 	      else if (strcmp(name,"None")==0) return NoneEnum;
-	      else if (strcmp(name,"AgressiveMigration")==0) return AgressiveMigrationEnum;
+	      else if (strcmp(name,"AggressiveMigration")==0) return AggressiveMigrationEnum;
 	      else if (strcmp(name,"SoftMigration")==0) return SoftMigrationEnum;
 	      else if (strcmp(name,"SubelementMigration")==0) return SubelementMigrationEnum;
-         else stage=6;
-   }
-   if(stage==6){
-	      if (strcmp(name,"SubelementMigration2")==0) return SubelementMigration2Enum;
+	      else if (strcmp(name,"SubelementMigration2")==0) return SubelementMigration2Enum;
 	      else if (strcmp(name,"Contact")==0) return ContactEnum;
 	      else if (strcmp(name,"MaskGroundediceLevelset")==0) return MaskGroundediceLevelsetEnum;
Index: /issm/trunk/src/c/shared/Enum/Synchronize.sh
===================================================================
--- /issm/trunk/src/c/shared/Enum/Synchronize.sh	(revision 17988)
+++ /issm/trunk/src/c/shared/Enum/Synchronize.sh	(revision 17989)
@@ -35,5 +35,5 @@
 END
 #core
-cat temp | grep [a-zA-Z]Analysis | \
+cat temp | grep [a-zA-Z0-9]Analysis | \
 	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
 	awk '{print "\t\t#ifdef _HAVE_"toupper(substr($1,1,length($1)-12))"_\n\t\t" "case " $1" : return new " substr($1,1,length($1)-4) "();\n\t\t#endif"}' \
@@ -63,5 +63,5 @@
 END
 #core
-cat temp | grep [a-zA-Z]Analysis | \
+cat temp | grep [a-zA-Z0-9]Analysis | \
 	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
 	sed -e "s/AnalysisEnum//g" | \
Index: /issm/trunk/src/c/shared/Numerics/BrentSearch.cpp
===================================================================
--- /issm/trunk/src/c/shared/Numerics/BrentSearch.cpp	(revision 17988)
+++ /issm/trunk/src/c/shared/Numerics/BrentSearch.cpp	(revision 17989)
@@ -17,9 +17,8 @@
 #include "./Verbosity.h"
 #include "./OptPars.h"
-#include "./OptArgs.h"
 #include "./types.h"
 #include "./isnan.h"
 
-void BrentSearch(IssmDouble* psearch_scalar,IssmDouble* pJ,OptPars* optpars,IssmDouble (*f)(IssmDouble,OptArgs*), OptArgs* optargs){
+void BrentSearch(IssmDouble* psearch_scalar,IssmDouble* pJ,OptPars* optpars,IssmDouble (*f)(IssmDouble,void*),void* optargs){
 
 	/* This routine is optimizing a given function using Brent's method
Index: /issm/trunk/src/c/shared/Numerics/GaussPoints.cpp
===================================================================
--- /issm/trunk/src/c/shared/Numerics/GaussPoints.cpp	(revision 17988)
+++ /issm/trunk/src/c/shared/Numerics/GaussPoints.cpp	(revision 17989)
@@ -1425,5 +1425,5 @@
 			(*pl3 )[i]=l3p [iord-1][i];
 			(*pl4 )[i]=l4p [iord-1][i];
-			(*pwgt)[i]=wgtp[iord-1][i]*2./3.*SQRT2;
+			(*pwgt)[i]=wgtp[iord-1][i];
 		}
 	}
Index: sm/trunk/src/c/shared/Numerics/OptArgs.h
===================================================================
--- /issm/trunk/src/c/shared/Numerics/OptArgs.h	(revision 17988)
+++ 	(revision )
@@ -1,14 +1,0 @@
-/*!\file:  OptArgs.h
- * \brief place holder for optimization function arguments
- */ 
-
-#ifndef _OPTARGS_H_
-#define _OPTARGS_H_
-
-class FemModel;
-
-struct OptArgs{
-	FemModel* femmodel;
-};
-
-#endif
Index: sm/trunk/src/c/shared/Numerics/OptimalSearch.cpp
===================================================================
--- /issm/trunk/src/c/shared/Numerics/OptimalSearch.cpp	(revision 17988)
+++ 	(revision )
@@ -1,97 +1,0 @@
-/*!\file:  OptimalSearch.cpp
- * \brief optimization algorithm
- */ 
-
-#ifdef HAVE_CONFIG_H
-	#include <config.h>
-#else
-#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
-#endif
-
-#include <float.h>
-
-#include "../Exceptions/exceptions.h"
-#include "../io/io.h"
-#include "../MemOps/MemOps.h"
-#include "./Verbosity.h"
-#include "./OptPars.h"
-#include "./OptArgs.h"
-#include "./types.h"
-#include "./isnan.h"
-
-void OptimalSearch(IssmDouble* psearch_scalar,IssmDouble* pJ,OptPars* optpars,IssmDouble (*f)(IssmDouble,OptArgs*), OptArgs* optargs){
-
-	/* This routine is optimizing a given function*/
-
-	/*function values: */
-	IssmDouble fx1,fx2,fxbest;
-	IssmDouble x1,x2,xmin,xbest;
-
-	/*tolerances: */
-	IssmDouble seps;
-	IssmDouble tolerance=1.e-4;
-	int    maxiter;
-
-	/*counters: */
-	int  iter=0;
-	bool loop;
-
-	/*Recover parameters:*/
-	xmin     =optpars->xmin;
-	x1       =optpars->xmin;
-	x2       =optpars->xmax;
-	maxiter  =optpars->maxiter;
-
-	//get the value of the function at the first boundary
-	fx1= (*f)(x1,optargs);
-	if (xIsNan<IssmDouble>(fx1)) _error_("Function evaluation returned NaN");
-	cout<<setprecision(5);
-	if(VerboseControl()) _printf0_("\n");
-	if(VerboseControl()) _printf0_("       Iteration         x           f(x)       Tolerance\n");
-	if(VerboseControl()) _printf0_("\n");
-	if(VerboseControl()) _printf0_("           N/A    "<<setw(12)<<x1<<"  "<<setw(12)<<fx1<<"           N/A\n");
-
-	//update tolerances
-	seps=sqrt(DBL_EPSILON);
-
-	loop=true;
-	while(loop){
-
-		/*get f(x2)*/
-		iter++;
-		fx2 = (*f)(x2,optargs);
-		if (xIsNan<IssmDouble>(fx2)) _error_("Function evaluation returned NaN");
-		if(VerboseControl())
-		 _printf0_("         "<<setw(5)<<iter<<"    "<<setw(12)<<x2<<"  "<<setw(12)<<fx2<<"  "<<(fabs(x2-x1)>fabs(fx2-fx1)?fabs(fx2-fx1):fabs(x2-x1)) << "\n");
-
-		//Stop the optimization?
-		if ((fabs(x2-x1)+seps)<tolerance || (fabs(fx2-fx1)+seps)<tolerance){
-			if(VerboseControl()) _printf0_("      " << "optimization terminated: the current x satisfies the termination criteria using 'tolx' of "  << tolerance << "\n");
-			loop=false;
-		}
-		else if (iter>=maxiter){
-			if(VerboseControl()) _printf0_("      " << "exiting: Maximum number of iterations has been exceeded  - increase 'maxiter'\n");
-			loop=false;
-		}
-		else{
-			//continue
-			loop=true;
-		}
-
-		/*Compute x2*/
-		if(fx2<fx1){
-			xbest=x2; fxbest=fx2;
-			x1=x2;
-			x2=xmin+1.1*(x2-xmin); 
-			fx1=fx2;
-		}
-		else{
-			xbest=x1; fxbest=fx1;
-			x2=xmin+0.5*(x2-xmin);
-		}
-	}//end while
-
-	/*Assign output pointers: */
-	*psearch_scalar=xbest;
-	*pJ=fxbest;
-}
Index: /issm/trunk/src/c/shared/Numerics/numerics.h
===================================================================
--- /issm/trunk/src/c/shared/Numerics/numerics.h	(revision 17988)
+++ /issm/trunk/src/c/shared/Numerics/numerics.h	(revision 17989)
@@ -18,5 +18,4 @@
 #include "./types.h"
 #include "./constants.h"
-#include "./OptArgs.h"
 #include "./OptPars.h"
 
@@ -31,7 +30,5 @@
 int         min(int a,int b);
 int         max(int a,int b);
-IssmDouble  OptFunc(IssmDouble scalar, OptArgs *optargs);
-void        BrentSearch(IssmDouble *psearch_scalar,IssmDouble*pJ,OptPars*optpars,IssmDouble (*f)(IssmDouble,OptArgs*), OptArgs*optargs);
-void        OptimalSearch(IssmDouble *psearch_scalar,IssmDouble*pJ,OptPars*optpars,IssmDouble (*f)(IssmDouble,OptArgs*), OptArgs*optargs);
+void        BrentSearch(IssmDouble *psearch_scalar,IssmDouble*pJ,OptPars*optpars,IssmDouble (*f)(IssmDouble,void*),void* optargs);
 void        cross(IssmDouble *result,IssmDouble*vector1,IssmDouble*vector2);
 void        XZvectorsToCoordinateSystem(IssmDouble *T,IssmDouble*xzvectors);
Index: /issm/trunk/src/c/solutionsequences/solutionsequence_newton.cpp
===================================================================
--- /issm/trunk/src/c/solutionsequences/solutionsequence_newton.cpp	(revision 17988)
+++ /issm/trunk/src/c/solutionsequences/solutionsequence_newton.cpp	(revision 17989)
@@ -68,5 +68,5 @@
 
 		/*Prepare next iteration using Newton's method*/
-		SystemMatricesx(&Kff,&Kfs,&pf,&df,NULL,femmodel);delete df;
+		SystemMatricesx(&Kff,&Kfs,&pf,&df,&kmax,femmodel);delete df;
 		CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type);
 		Reduceloadx(pf,Kfs,ys);delete Kfs;
Index: /issm/trunk/src/c/toolkits/issm/IssmMpiSparseMat.h
===================================================================
--- /issm/trunk/src/c/toolkits/issm/IssmMpiSparseMat.h	(revision 17988)
+++ /issm/trunk/src/c/toolkits/issm/IssmMpiSparseMat.h	(revision 17989)
@@ -141,13 +141,10 @@
 		void Echo(void){
 
-			int my_rank;
-			int i,j,k;
-
 			/*Do a synchronized dump across all the rows: */
-			my_rank=IssmComm::GetRank();
-			for(i=0;i<IssmComm::GetSize();i++){
-				if (my_rank==i){
+			int my_rank=IssmComm::GetRank();
+			for(int i=0;i<IssmComm::GetSize();i++){
+				if(my_rank==i){
 					_printf_("cpu " << i << " #rows: " << this->m << "\n");
-					for (j=0;j<this->m;j++){
+					for(int j=0;j<this->m;j++){
 						_printf_("row " << j << ":");
 						this->matrix[j]->Echo();
@@ -190,5 +187,4 @@
 			int*          this_row_cols       = NULL;
 			int*          this_row_mods       = NULL;
-			doubletype*   this_row_values     = NULL;
 			int*          numvalues_perrow    = NULL;
 			int           row;
@@ -378,5 +374,5 @@
 			doubletype norm,local_norm;
 			doubletype absolute;
-			int i,j;
+			int i;
 
 			switch(mode){
@@ -421,7 +417,4 @@
 		void MatMult(IssmAbsVec<doubletype>* Xin,IssmAbsVec<doubletype>* AXin){
 
-			int         i,j;
-			doubletype *X_serial  = NULL;
-
 			/*A check on the types: */
 			if(IssmVecTypeFromToolkitOptions()!=MpiEnum)_error_("MatMult operation only possible with 'mpi' vectors");
@@ -432,9 +425,9 @@
 
 			/*Serialize input Xin: */
-			X_serial=X->ToMPISerial();
+			doubletype* X_serial=X->ToMPISerial();
 
 			/*Every cpu has a serial version of the input vector. Use it to do the Matrix-Vector multiply 
 			 *locally and plug it into AXin: */
-			for(i=0;i<this->m;i++){
+			for(int i=0;i<this->m;i++){
 				AX->vector[i]=this->matrix[i]->Mult(X_serial);
 			}
Index: /issm/trunk/src/c/toolkits/mumps/MumpsSolve.cpp
===================================================================
--- /issm/trunk/src/c/toolkits/mumps/MumpsSolve.cpp	(revision 17988)
+++ /issm/trunk/src/c/toolkits/mumps/MumpsSolve.cpp	(revision 17989)
@@ -200,5 +200,5 @@
 	ISSM_MPI_Comm  comm;
 	int            num_procs;
-	int            i,j;
+	int            i;
 	int            nnz,local_nnz;
 	int           *irn_loc    = NULL;
@@ -217,7 +217,7 @@
 
 	/*First, some checks*/
-	if (Kff_M!=Kff_N)_error_("stiffness matrix Kff should be square");
-	if (uf_M!=Kff_M || uf_M!=pf_M)_error_("solution vector should be the same size as stiffness matrix Kff and load vector pf");
-	if (uf_m!=Kff_m || uf_m!=pf_m)_error_("solution vector should be locally the same size as stiffness matrix Kff and load vector pf");
+	if(Kff_M!=Kff_N)_error_("stiffness matrix Kff should be square");
+	if(uf_M!=Kff_M || uf_M!=pf_M)_error_("solution vector should be the same size as stiffness matrix Kff and load vector pf");
+	if(uf_m!=Kff_m || uf_m!=pf_m)_error_("solution vector should be locally the same size as stiffness matrix Kff and load vector pf");
 
 	/*Initialize matrix */
Index: /issm/trunk/src/dox/issm.dox
===================================================================
--- /issm/trunk/src/dox/issm.dox	(revision 17988)
+++ /issm/trunk/src/dox/issm.dox	(revision 17989)
@@ -47,35 +47,41 @@
 </th>
 <tr>
-<th  bgcolor=#FFFFFF style="text-align:left;"> C++ </th><td  bgcolor=#FFFFFF style="text-align:right;">492</td><td  bgcolor=#FFFFFF style="text-align:right;">15134</td><td  bgcolor=#FFFFFF style="text-align:right;">17851</td><td  bgcolor=#FFFFFF style="text-align:right;">63296</td><td  bgcolor=#FFFFFF style="text-align:right;">96281</td>
+<th  bgcolor=#FFFFFF style="text-align:left;"> C++ </th><td  bgcolor=#FFFFFF style="text-align:right;">453</td><td  bgcolor=#FFFFFF style="text-align:right;">15861</td><td  bgcolor=#FFFFFF style="text-align:right;">18188</td><td  bgcolor=#FFFFFF style="text-align:right;">68849</td><td  bgcolor=#FFFFFF style="text-align:right;">102898</td>
 </tr>
 <tr>
-<th  bgcolor=#C6E2FF style="text-align:left;"> MATLAB </th><td  bgcolor=#C6E2FF style="text-align:right;">1057</td><td  bgcolor=#C6E2FF style="text-align:right;">7147</td><td  bgcolor=#C6E2FF style="text-align:right;">14649</td><td  bgcolor=#C6E2FF style="text-align:right;">33842</td><td  bgcolor=#C6E2FF style="text-align:right;">55638</td>
+<th  bgcolor=#C6E2FF style="text-align:left;"> MATLAB </th><td  bgcolor=#C6E2FF style="text-align:right;">1378</td><td  bgcolor=#C6E2FF style="text-align:right;">8341</td><td  bgcolor=#C6E2FF style="text-align:right;">16259</td><td  bgcolor=#C6E2FF style="text-align:right;">38645</td><td  bgcolor=#C6E2FF style="text-align:right;">63245</td>
 </tr>
 <tr>
-<th  bgcolor=#FFFFFF style="text-align:left;"> C/C++  Header </th><td  bgcolor=#FFFFFF style="text-align:right;">383</td><td  bgcolor=#FFFFFF style="text-align:right;">3169</td><td  bgcolor=#FFFFFF style="text-align:right;">3340</td><td  bgcolor=#FFFFFF style="text-align:right;">13334</td><td  bgcolor=#FFFFFF style="text-align:right;">19843</td>
+<th  bgcolor=#FFFFFF style="text-align:left;"> C/C++  Header </th><td  bgcolor=#FFFFFF style="text-align:right;">421</td><td  bgcolor=#FFFFFF style="text-align:right;">3504</td><td  bgcolor=#FFFFFF style="text-align:right;">3753</td><td  bgcolor=#FFFFFF style="text-align:right;">15489</td><td  bgcolor=#FFFFFF style="text-align:right;">22746</td>
 </tr>
 <tr>
-<th  bgcolor=#C6E2FF style="text-align:left;"> Python </th><td  bgcolor=#C6E2FF style="text-align:right;">119</td><td  bgcolor=#C6E2FF style="text-align:right;">1911</td><td  bgcolor=#C6E2FF style="text-align:right;">2296</td><td  bgcolor=#C6E2FF style="text-align:right;">7443</td><td  bgcolor=#C6E2FF style="text-align:right;">11650</td>
+<th  bgcolor=#C6E2FF style="text-align:left;"> m4 </th><td  bgcolor=#C6E2FF style="text-align:right;">9</td><td  bgcolor=#C6E2FF style="text-align:right;">1588</td><td  bgcolor=#C6E2FF style="text-align:right;">151</td><td  bgcolor=#C6E2FF style="text-align:right;">11565</td><td  bgcolor=#C6E2FF style="text-align:right;">13304</td>
 </tr>
 <tr>
-<th  bgcolor=#FFFFFF style="text-align:left;"> m4 </th><td  bgcolor=#FFFFFF style="text-align:right;">2</td><td  bgcolor=#FFFFFF style="text-align:right;">184</td><td  bgcolor=#FFFFFF style="text-align:right;">6</td><td  bgcolor=#FFFFFF style="text-align:right;">1845</td><td  bgcolor=#FFFFFF style="text-align:right;">2035</td>
+<th  bgcolor=#FFFFFF style="text-align:left;"> Python </th><td  bgcolor=#FFFFFF style="text-align:right;">144</td><td  bgcolor=#FFFFFF style="text-align:right;">2330</td><td  bgcolor=#FFFFFF style="text-align:right;">2559</td><td  bgcolor=#FFFFFF style="text-align:right;">9348</td><td  bgcolor=#FFFFFF style="text-align:right;">14237</td>
 </tr>
 <tr>
-<th  bgcolor=#C6E2FF style="text-align:left;"> CMake </th><td  bgcolor=#C6E2FF style="text-align:right;">2</td><td  bgcolor=#C6E2FF style="text-align:right;">31</td><td  bgcolor=#C6E2FF style="text-align:right;">84</td><td  bgcolor=#C6E2FF style="text-align:right;">637</td><td  bgcolor=#C6E2FF style="text-align:right;">752</td>
+<th  bgcolor=#C6E2FF style="text-align:left;"> XML </th><td  bgcolor=#C6E2FF style="text-align:right;">4</td><td  bgcolor=#C6E2FF style="text-align:right;">160</td><td  bgcolor=#C6E2FF style="text-align:right;">92</td><td  bgcolor=#C6E2FF style="text-align:right;">3075</td><td  bgcolor=#C6E2FF style="text-align:right;">3327</td>
 </tr>
 <tr>
-<th  bgcolor=#FFFFFF style="text-align:left;"> Objective  C </th><td  bgcolor=#FFFFFF style="text-align:right;">9</td><td  bgcolor=#FFFFFF style="text-align:right;">96</td><td  bgcolor=#FFFFFF style="text-align:right;">0</td><td  bgcolor=#FFFFFF style="text-align:right;">370</td><td  bgcolor=#FFFFFF style="text-align:right;">466</td>
+<th  bgcolor=#FFFFFF style="text-align:left;"> Java </th><td  bgcolor=#FFFFFF style="text-align:right;">18</td><td  bgcolor=#FFFFFF style="text-align:right;">719</td><td  bgcolor=#FFFFFF style="text-align:right;">891</td><td  bgcolor=#FFFFFF style="text-align:right;">2321</td><td  bgcolor=#FFFFFF style="text-align:right;">3931</td>
 </tr>
 <tr>
-<th  bgcolor=#C6E2FF style="text-align:left;"> Fortran </th><td  bgcolor=#C6E2FF style="text-align:right;">77</td><td  bgcolor=#C6E2FF style="text-align:right;">7</td><td  bgcolor=#C6E2FF style="text-align:right;">4</td><td  bgcolor=#C6E2FF style="text-align:right;">302</td><td  bgcolor=#C6E2FF style="text-align:right;">365</td><td  bgcolor=#C6E2FF style="text-align:right;">678</td>
+<th  bgcolor=#C6E2FF style="text-align:left;"> Fortran  77 </th><td  bgcolor=#C6E2FF style="text-align:right;">7</td><td  bgcolor=#C6E2FF style="text-align:right;">4</td><td  bgcolor=#C6E2FF style="text-align:right;">302</td><td  bgcolor=#C6E2FF style="text-align:right;">365</td><td  bgcolor=#C6E2FF style="text-align:right;">671</td>
 </tr>
 <tr>
-<th  bgcolor=#FFFFFF style="text-align:left;"> Bourne  Shell </th><td  bgcolor=#FFFFFF style="text-align:right;">2</td><td  bgcolor=#FFFFFF style="text-align:right;">48</td><td  bgcolor=#FFFFFF style="text-align:right;">66</td><td  bgcolor=#FFFFFF style="text-align:right;">213</td><td  bgcolor=#FFFFFF style="text-align:right;">327</td>
+<th  bgcolor=#FFFFFF style="text-align:left;"> Bourne  Shell </th><td  bgcolor=#FFFFFF style="text-align:right;">3</td><td  bgcolor=#FFFFFF style="text-align:right;">61</td><td  bgcolor=#FFFFFF style="text-align:right;">88</td><td  bgcolor=#FFFFFF style="text-align:right;">266</td><td  bgcolor=#FFFFFF style="text-align:right;">415</td>
 </tr>
 <tr>
-<th  bgcolor=#C6E2FF style="text-align:left;"> Perl </th><td  bgcolor=#C6E2FF style="text-align:right;">1</td><td  bgcolor=#C6E2FF style="text-align:right;">6</td><td  bgcolor=#C6E2FF style="text-align:right;">9</td><td  bgcolor=#C6E2FF style="text-align:right;">196</td><td  bgcolor=#C6E2FF style="text-align:right;">211</td>
+<th  bgcolor=#C6E2FF style="text-align:left;"> XSD </th><td  bgcolor=#C6E2FF style="text-align:right;">2</td><td  bgcolor=#C6E2FF style="text-align:right;">30</td><td  bgcolor=#C6E2FF style="text-align:right;">36</td><td  bgcolor=#C6E2FF style="text-align:right;">229</td><td  bgcolor=#C6E2FF style="text-align:right;">295</td>
 </tr>
 <tr>
-<th  bgcolor=#FFFFFF style="text-align:left;"> SUM: </th><td  bgcolor=#FFFFFF style="text-align:right;">2074</td><td  bgcolor=#FFFFFF style="text-align:right;">27730</td><td  bgcolor=#FFFFFF style="text-align:right;">38603</td><td  bgcolor=#FFFFFF style="text-align:right;">121541</td><td  bgcolor=#FFFFFF style="text-align:right;">187874</td>
+<th  bgcolor=#FFFFFF style="text-align:left;"> Perl </th><td  bgcolor=#FFFFFF style="text-align:right;">1</td><td  bgcolor=#FFFFFF style="text-align:right;">6</td><td  bgcolor=#FFFFFF style="text-align:right;">9</td><td  bgcolor=#FFFFFF style="text-align:right;">196</td><td  bgcolor=#FFFFFF style="text-align:right;">211</td>
+</tr>
+<tr>
+<th  bgcolor=#C6E2FF style="text-align:left;"> Ant </th><td  bgcolor=#C6E2FF style="text-align:right;">1</td><td  bgcolor=#C6E2FF style="text-align:right;">16</td><td  bgcolor=#C6E2FF style="text-align:right;">7</td><td  bgcolor=#C6E2FF style="text-align:right;">103</td><td  bgcolor=#C6E2FF style="text-align:right;">126</td>
+</tr>
+<tr>
+<th  bgcolor=#FFFFFF style="text-align:left;"> SUM: </th><td  bgcolor=#FFFFFF style="text-align:right;">2441</td><td  bgcolor=#FFFFFF style="text-align:right;">32620</td><td  bgcolor=#FFFFFF style="text-align:right;">42335</td><td  bgcolor=#FFFFFF style="text-align:right;">150451</td><td  bgcolor=#FFFFFF style="text-align:right;">225406</td>
 </tr>
 </table>
Index: /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.py	(revision 17988)
+++ /issm/trunk/src/m/boundaryconditions/SetIceSheetBC.py	(revision 17989)
@@ -15,7 +15,7 @@
 	#node on Dirichlet
 	pos=numpy.nonzero(md.mesh.vertexonboundary)
-	md.stressbalance.spcvx=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-	md.stressbalance.spcvy=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-	md.stressbalance.spcvz=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
+	md.stressbalance.spcvx=float('nan')*numpy.ones(md.mesh.numberofvertices)
+	md.stressbalance.spcvy=float('nan')*numpy.ones(md.mesh.numberofvertices)
+	md.stressbalance.spcvz=float('nan')*numpy.ones(md.mesh.numberofvertices)
 	md.stressbalance.spcvx[pos]=0
 	md.stressbalance.spcvy[pos]=0
Index: /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.py	(revision 17988)
+++ /issm/trunk/src/m/boundaryconditions/SetIceShelfBC.py	(revision 17989)
@@ -33,7 +33,7 @@
 #	pos=find(md.mesh.vertexonboundary & ~nodeonicefront);
 	pos=numpy.nonzero(numpy.logical_and(md.mesh.vertexonboundary,numpy.logical_not(nodeonicefront)))[0]
-	md.stressbalance.spcvx=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-	md.stressbalance.spcvy=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-	md.stressbalance.spcvz=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
+	md.stressbalance.spcvx=float('nan')*numpy.ones(md.mesh.numberofvertices)
+	md.stressbalance.spcvy=float('nan')*numpy.ones(md.mesh.numberofvertices)
+	md.stressbalance.spcvz=float('nan')*numpy.ones(md.mesh.numberofvertices)
 	md.stressbalance.referential=float('nan')*numpy.ones((md.mesh.numberofvertices,6))
 	md.stressbalance.loadingforce=0*numpy.ones((md.mesh.numberofvertices,3))
@@ -59,7 +59,7 @@
 	else:
 		pos=numpy.nonzero(md.mesh.vertexonboundary)[0]
-	md.stressbalance.spcvx[pos[:]]=0
-	md.stressbalance.spcvy[pos[:]]=0
-	md.stressbalance.spcvz[pos[:]]=0
+	md.stressbalance.spcvx[pos]=0
+	md.stressbalance.spcvy[pos]=0
+	md.stressbalance.spcvz[pos]=0
 																													   
 	#Dirichlet Values
Index: /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.py
===================================================================
--- /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.py	(revision 17988)
+++ /issm/trunk/src/m/boundaryconditions/SetMarineIceSheetBC.py	(revision 17989)
@@ -42,7 +42,7 @@
 		print "SetMarineIceSheetBC warning: ice front all around the glacier, no dirichlet found. Dirichlet must be added manually."
 
-	md.stressbalance.spcvx=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-	md.stressbalance.spcvy=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
-	md.stressbalance.spcvz=float('nan')*numpy.ones((md.mesh.numberofvertices,1))
+	md.stressbalance.spcvx=float('nan')*numpy.ones(md.mesh.numberofvertices)
+	md.stressbalance.spcvy=float('nan')*numpy.ones(md.mesh.numberofvertices)
+	md.stressbalance.spcvz=float('nan')*numpy.ones(md.mesh.numberofvertices)
 	md.stressbalance.referential=float('nan')*numpy.ones((md.mesh.numberofvertices,6))
 	md.stressbalance.loadingforce=0*numpy.ones((md.mesh.numberofvertices,3))
@@ -68,7 +68,7 @@
 	else:
 		pos=numpy.nonzero(md.mesh.vertexonboundary)[0]
-	md.stressbalance.spcvx[pos[:]]=0
-	md.stressbalance.spcvy[pos[:]]=0
-	md.stressbalance.spcvz[pos[:]]=0
+	md.stressbalance.spcvx[pos]=0
+	md.stressbalance.spcvy[pos]=0
+	md.stressbalance.spcvz[pos]=0
 
 	#Dirichlet Values
Index: /issm/trunk/src/m/classes/balancethickness.m
===================================================================
--- /issm/trunk/src/m/classes/balancethickness.m	(revision 17988)
+++ /issm/trunk/src/m/classes/balancethickness.m	(revision 17989)
@@ -17,5 +17,10 @@
 			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcthickness" type="',   	class(obj.spcthickness),'" default="',        convert2str(obj.spcthickness),'">',	'     <section name="balancethickness" />','     <help> thickness constraints (NaN means no constraint) [m] </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="thickening_rate" type="', 	class(obj.thickening_rate),'" default="',            convert2str(obj.thickening_rate),'">',     '     <section name="balancethickness" />','     <help> ice thickening rate used in the mass conservation (dh/dt) [m/yr] </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',        '<parameter key ="stabilization" type="',      class(obj.stabilization),'" default="',          convert2str(obj.stabilization),'">',	'     <section name="balancethickness" />','     <help> 0: None, 1: SU, 2: SSAs artificial diffusivity, 3:DG </help>','</parameter>');
+            
+            % balancethickness drop-down (1,2, or 3)
+            fprintf(fid,'%s\n%s\n%s\n',        '<parameter key ="stabilization" type="alternative" optional="false">','     <section name="balancethickness" />','     <help> 0: None, 1: SU, 2: SSAs artificial diffusivity, 3:DG </help>');
+            fprintf(fid,'%s\n','       <option value="1" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="2" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="3" type="string" default="false"> </option>','</parameter>');
 
         end % }}}
Index: /issm/trunk/src/m/classes/balancethickness2.m
===================================================================
--- /issm/trunk/src/m/classes/balancethickness2.m	(revision 17989)
+++ /issm/trunk/src/m/classes/balancethickness2.m	(revision 17989)
@@ -0,0 +1,57 @@
+%BALANCETHICKNESS2 class definition
+%
+%   Usage:
+%      balancethickness2=balancethickness2();
+
+classdef balancethickness2
+	properties (SetAccess=public) 
+		spcpotential         = NaN;
+		apparent_massbalance = NaN;
+		nux                  = NaN;
+		nuy                  = NaN;
+		vx_obs               = NaN;
+		vy_obs               = NaN;
+		thickness_obs        = NaN;
+	end
+	methods
+		function obj = balancethickness2(varargin) % {{{
+			switch nargin
+				case 0
+					obj=setdefaultparameters(obj);
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+			%Early return
+			if solution~=Balancethickness2SolutionEnum(), return; end
+
+			md = checkfield(md,'fieldname','balancethickness.spcpotential','size',[md.mesh.numberofvertices 1]);
+			md = checkfield(md,'fieldname','balancethickness.apparent_massbalance','size',[md.mesh.numberofvertices 1],'NaN',1);
+			md = checkfield(md,'fieldname','balancethickness.nux','size',[md.mesh.numberofvertices 1],'NaN',1,'>',0,'<=',1);
+			md = checkfield(md,'fieldname','balancethickness.nuy','size',[md.mesh.numberofvertices 1],'NaN',1,'>',0,'<=',1);
+			md = checkfield(md,'fieldname','balancethickness.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+			md = checkfield(md,'fieldname','balancethickness.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+			md = checkfield(md,'fieldname','balancethickness.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1,'>=',0);
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   balance thickness solution parameters:'));
+
+			fielddisplay(obj,'spcpotential','potential constraints (NaN means no constraint)');
+			fielddisplay(obj,'apparent_massbalance','Apparent mass balance [m/yr]');
+
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','spcpotential','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','apparent_massbalance','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','nux','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','nuy','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','vx_obs','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','vy_obs','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','Balancethickness','fieldname','thickness_obs','format','DoubleMat','mattype',1);
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/damage.m
===================================================================
--- /issm/trunk/src/m/classes/damage.m	(revision 17988)
+++ /issm/trunk/src/m/classes/damage.m	(revision 17989)
@@ -7,5 +7,5 @@
 	properties (SetAccess=public)  
 		%damage 
-		isdamage            = NaN;
+		isdamage            = 0;
 		D                   = NaN;
 		law                 = '';
@@ -72,5 +72,11 @@
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="max_damage" type="',     class(obj.max_damage),'" default="',         num2str(obj.max_damage),'">',            '     <section name="damage" />','     <help> maximum possible damage (0&amp;lt;=max_damage&amp;lt;1) </help>','</parameter>');
              
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="stabilization" type="',       class(obj.stabilization),'" default="',              num2str(obj.stabilization),'">',              '     <section name="damage" />','     <help> 0: no, 1: artificial_diffusivity, 2: SUPG </help>','</parameter>');
+            % stabilization (0,1, or 2) drop-down
+            fprintf(fid,'%s\n%s\n%s\n%s\n',    '<parameter key ="stabilization" type="alternative" optional="false">','     <section name="damage" />','     <help> 0: no, 1: artificial_diffusivity, 2: SUPG </help>');
+            fprintf(fid, '%s\n', '       <option value="0" type="string" default="true"></option>');
+            fprintf(fid, '%s\n', '       <option value="1" type="string" default="false"></option>');
+            fprintf(fid, '%s\n', '       <option value="2" type="string" default="false"></option>');
+            fprintf(fid, '%s\n','</parameter>');
+            
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="maxiter" type="',             class(obj.maxiter),'" default="',   num2str(obj.maxiter),'">',   '     <section name="damage" />','     <help> maximum number of non linear iterations </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="penalty_lock" type="',        class(obj.penalty_lock),'" default="',            num2str(obj.penalty_lock),'">',            '     <section name="damage" />','     <help> stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization) </help>','</parameter>');
@@ -146,5 +152,4 @@
 				md = checkfield(md,'fieldname','damage.spcdamage','forcing',1);
 				md = checkfield(md,'fieldname','damage.max_damage','<',1,'>=',0);
-				
 				md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0 1 2]);
 				md = checkfield(md,'fieldname','damage.maxiter','>=0',0);
Index: /issm/trunk/src/m/classes/damage.py
===================================================================
--- /issm/trunk/src/m/classes/damage.py	(revision 17988)
+++ /issm/trunk/src/m/classes/damage.py	(revision 17989)
@@ -17,5 +17,5 @@
 			
 		#damage: 
-		self.isdamage           = float('NaN')
+		self.isdamage           = 0.
 		self.D						= float('NaN')
 		self.law						= ''
@@ -24,10 +24,10 @@
 		
 		#numerical
-		stabilization				= float('NaN')
-		maxiter						= float('NaN')
-		elementinterp           = ''
-		penalty_threshold			= float('NaN')
-		penalty_lock				= float('NaN')
-		penalty_factor				= float('NaN')
+		self.stabilization		= float('NaN')
+		self.maxiter				= float('NaN')
+		self.elementinterp      = ''
+		self.penalty_threshold	= float('NaN')
+		self.penalty_lock			= float('NaN')
+		self.penalty_factor		= float('NaN')
 
 		#general parameters for evolution law: 
@@ -59,5 +59,5 @@
 			s+="%s\n" % fielddisplay(self,"stabilization","0: no, 1: artificial_diffusivity, 2: SUPG")
 			s+="%s\n" % fielddisplay(self,"maxiter","maximum number of non linear iterations")
-			s+="%s\n" %	fielddisplay(self,"elementinterp","interpolation scheme for finite elements {''P1'',''P2''}")
+			s+="%s\n" %	fielddisplay(self,"elementinterp","interpolation scheme for finite elements [''P1'',''P2'']")
 			s+="%s\n" % fielddisplay(self,"penalty_lock","stabilize unstable damage constraints that keep zigzagging after n iteration (default is 0, no stabilization)")
 			s+="%s\n" % fielddisplay(self,"penalty_threshold","threshold to declare convergence of damage evolution solution (default is 0)")
@@ -134,5 +134,4 @@
 			md = checkfield(md,'fieldname','damage.law','values',['undamaged','pralong'])
 			md = checkfield(md,'fieldname','damage.spcdamage','forcing',1)
-				
 			md = checkfield(md,'fieldname','damage.stabilization','numel',[1],'values',[0,1,2])
 			md = checkfield(md,'fieldname','damage.maxiter','>=0',0)
@@ -166,5 +165,4 @@
 			WriteData(fid,'object',self,'fieldname','spcdamage','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
 			WriteData(fid,'object',self,'fieldname','max_damage','format','Double')
-
 			WriteData(fid,'object',self,'fieldname','stabilization','format','Integer')
 			WriteData(fid,'object',self,'fieldname','elementinterp','format','String')
Index: /issm/trunk/src/m/classes/debug.m
===================================================================
--- /issm/trunk/src/m/classes/debug.m	(revision 17988)
+++ /issm/trunk/src/m/classes/debug.m	(revision 17989)
@@ -14,7 +14,12 @@
             fprintf(fid, '\n\n');
             fprintf(fid, '%s\n', '<!-- Debug -->');
-			 fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="valgrind" type="',              class(obj.valgrind),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.valgrind),'" type="string" default="true"></option>','     <help> use Valgrind to debug (0 or 1) </help>','</parameter>');
-             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="gprof" type="',              class(obj.gprof),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.gprof),'" type="string" default="true"></option>','     <help> use gnu-profiler to find out where the time is spent </help>','</parameter>');
-             fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n',    '<parameter key ="profiling" type="',              class(obj.profiling),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.profiling),'" type="string" default="true"></option>','     <help> enables profiling (memory, flops, time) </help>','</parameter>');
+            
+            %valgrind drop-down (0 or 1)
+			fprintf(fid,'%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="valgrind" type="alternative" optional="false">','     <section name="debug" />','     <help> use Valgrind to debug (0 or 1) </help>');
+            fprintf(fid,'%s\n','       <option value="0" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="1" type="string" default="false"> </option>','</parameter>');
+          
+            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n',    '<parameter key ="gprof" type="',              class(obj.gprof),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.gprof),'" type="string" default="true"></option>','     <help> use gnu-profiler to find out where the time is spent </help>','</parameter>');
+            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n',    '<parameter key ="profiling" type="',              class(obj.profiling),'" optional="false">',              '     <section name="debug" />','        <option value="',convert2str(obj.profiling),'" type="string" default="true"></option>','     <help> enables profiling (memory, flops, time) </help>','</parameter>');
         end % }}}
 		function obj = debug(varargin) % {{{
Index: /issm/trunk/src/m/classes/flowequation.m
===================================================================
--- /issm/trunk/src/m/classes/flowequation.m	(revision 17988)
+++ /issm/trunk/src/m/classes/flowequation.m	(revision 17989)
@@ -70,7 +70,29 @@
             
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="isFS" type="',       class(obj.isFS),'" default="',              convert2str(obj.isFS),'">',              '     <section name="flowequation" />','     <help> are the Full-FS (FS) equations used ? </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="fe_SSA" type="',             class(obj.fe_SSA),'" default="',   convert2str(obj.fe_SSA),'">',   '     <section name="flowequation" />','     <help> Finite Element for SSA  "P1", "P1bubble" "P1bubblecondensed" "P2" </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="fe_HO" type="',        class(obj.fe_HO),'" default="',            convert2str(obj.fe_HO),'">',            '     <section name="flowequation" />','     <help> Finite Element for HO   "P1" "P1bubble" "P1bubblecondensed" "P1xP2" "P2xP1" "P2" </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="fe_FS" type="',   class(obj.fe_FS),'" default="',            convert2str(obj.fe_FS),'">',            '     <section name="flowequation" />','     <help> Finite Element for FS   "P1P1" (debugging only) "P1P1GLS" "MINIcondensed" "MINI" "TaylorHood" </help>','</parameter>');
+            
+            % fe_SSA drop-down (P1, P1bubble, P1bubblecondensed, P2)
+            fprintf(fid,'%s\n%s\n%s\n%s\n',    '<parameter key ="fe_SSA" type="alternative" optional="false">','     <section name="flowequation" />','     <help> Finite Element for SSA  "P1", "P1bubble" "P1bubblecondensed" "P2" </help>');
+            fprintf(fid,'%s\n','       <option value="P1" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="P1bubble" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="P1bubblecondensed" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="P2" type="string" default="false"> </option>','</parameter>');
+            
+            %fe_HO drop-down (P1, P1bubble, P1bubblecondensed, P1xP2, P2xP1, P2)
+            fprintf(fid,'%s\n%s\n%s\n%s\n',        '<parameter key ="fe_HO" type="alternative" optional="false">','     <section name="flowequation" />','     <help> Finite Element for HO   "P1" "P1bubble" "P1bubblecondensed" "P1xP2" "P2xP1" "P2" </help>');
+            fprintf(fid,'%s\n','       <option value="P1" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="P1bubble" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="P1bubblecondensed" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="P1xP2" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="P2xP1" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="P2" type="string" default="false"> </option>','</parameter>');
+            
+            % fe_FS drop-down (P1P1, P1P1GLS, MINIcondensed, MINI, TaylowHood)
+            fprintf(fid,'%s\n%s\n%s\n%s\n',        '<parameter key ="fe_FS" type="alternative" optional="false">','     <section name="flowequation" />','     <help> Finite Element for FS   "P1P1" (debugging only) "P1P1GLS" "MINIcondensed" "MINI" "TaylorHood" </help>');
+            fprintf(fid,'%s\n','       <option value="P1P1" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="P1P1GLS" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="MINIcondensed" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="MINI" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="TaylorHood" type="string" default="false"> </option>','</parameter>');
+            
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="vertex_equation" type="',      class(obj.vertex_equation),'" default="',            convert2str(obj.vertex_equation),'">',            '     <section name="flowequation" />','     <help> flow equation for each vertex </help>','</parameter>');
        
Index: /issm/trunk/src/m/classes/friction.m
===================================================================
--- /issm/trunk/src/m/classes/friction.m	(revision 17988)
+++ /issm/trunk/src/m/classes/friction.m	(revision 17989)
@@ -40,5 +40,5 @@
 		end % }}}
 		function disp(obj) % {{{
-			disp(sprintf('Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p'));
+			disp(sprintf('Basal shear stress parameters: Sigma_b = coefficient^2 * Neff ^r * |u_b|^(s-1) * u_b\n(effective stress Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p)'));
 			fielddisplay(obj,'coefficient','friction coefficient [SI]');
 			fielddisplay(obj,'p','p exponent');
@@ -48,4 +48,5 @@
 			yts=365.0*24.0*3600.0;
 
+			WriteData(fid,'enum',FrictionLawEnum,'data',1,'format','Integer');
 			WriteData(fid,'object',obj,'fieldname','coefficient','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
 			%WriteData(fid,'object',obj,'fieldname','coefficient','format','DoubleMat','mattype',1);
Index: /issm/trunk/src/m/classes/friction.py
===================================================================
--- /issm/trunk/src/m/classes/friction.py	(revision 17988)
+++ /issm/trunk/src/m/classes/friction.py	(revision 17989)
@@ -22,5 +22,5 @@
 		#}}}
 	def __repr__(self): # {{{
-		string="Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p"
+		string="Basal shear stress parameters: Sigma_b = coefficient^2 * Neff ^r * |u_b|^(s-1) * u_b,\n(effective stress Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p)"
 
 		string="%s\n%s"%(string,fielddisplay(self,"coefficient","friction coefficient [SI]"))
@@ -45,4 +45,5 @@
 	# }}}
 	def marshall(self,md,fid):    # {{{
+		WriteData(fid,'enum',FrictionLawEnum(),'data',1,'format','Integer')
 		WriteData(fid,'object',self,'fieldname','coefficient','format','DoubleMat','mattype',1)
 		WriteData(fid,'object',self,'fieldname','p','format','DoubleMat','mattype',2)
Index: /issm/trunk/src/m/classes/frictionweertman.m
===================================================================
--- /issm/trunk/src/m/classes/frictionweertman.m	(revision 17989)
+++ /issm/trunk/src/m/classes/frictionweertman.m	(revision 17989)
@@ -0,0 +1,54 @@
+%FRICTIONWEERTMAN class definition
+%
+%   Usage:
+%      frictionweertman=frictionweertman();
+
+classdef frictionweertman
+	properties (SetAccess=public) 
+		C = NaN;
+		m = NaN;
+	end
+	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '\n\n');
+            fprintf(fid, '%s\n', '<!-- Friction: Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p -->');
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Friction: Sigma= drag^2 * Neff ^r * u ^s, with Neff=rho_ice*g*thickness+rho_water*g*bed, r=q/p and s=1/p">','<section name="frictionweertman" />');   
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="coefficient" type="',   	class(obj.coefficient),'" default="',     	convert2str(obj.coefficient),'">',              '     <section name="frictionweertman" />','     <help> frictionweertman coefficient [SI] </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="p" type="',               class(obj.p),'" default="',                 convert2str(obj.p),'">',   '     <section name="frictionweertman" />','     <help> p exponent </help>','</parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',        '<parameter key ="q" type="',               class(obj.q),'" default="',                 convert2str(obj.q),'">',            '     <section name="frictionweertman" />','     <help> q exponent </help>','</parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        end % }}}
+		function obj = frictionweertman(varargin) % {{{
+			switch nargin
+				case 0
+					obj=setdefaultparameters(obj);
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function obj = setdefaultparameters(obj) % {{{
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			%Early return
+			if ~ismember(StressbalanceAnalysisEnum(),analyses) & ~ismember(ThermalAnalysisEnum(),analyses), return; end
+			md = checkfield(md,'fieldname','frictionweertman.C','forcing',1,'NaN',1);
+			md = checkfield(md,'fieldname','frictionweertman.m','NaN',1,'size',[md.mesh.numberofelements 1]);
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('Weertman sliding law parameters: Sigma_b = C^2 * |u_b|^(1/m-1) * u_b'));
+			fielddisplay(obj,'coefficient','friction coefficient [SI]');
+			fielddisplay(obj,'m','m exponent');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'enum',FrictionLawEnum,'data',1,'format','Integer');
+			WriteData(fid,'class','friction','object',obj,'fieldname','C','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
+			WriteData(fid,'class','friction','object',obj,'fieldname','m','format','DoubleMat','mattype',2);
+			
+
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/frictionweertman.py
===================================================================
--- /issm/trunk/src/m/classes/frictionweertman.py	(revision 17989)
+++ /issm/trunk/src/m/classes/frictionweertman.py	(revision 17989)
@@ -0,0 +1,47 @@
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from checkfield import checkfield
+from WriteData import WriteData
+
+class frictionweertman(object):
+	"""
+	FRICTIONWEERTMAN class definition
+
+	   Usage:
+	      frictionweertman=frictionweertman();
+	"""
+
+	def __init__(self): # {{{
+		self.C = float('NaN')
+		self.m = float('NaN')
+
+		#set defaults
+		self.setdefaultparameters()
+
+		#}}}
+	def __repr__(self): # {{{
+		string="Weertman sliding law parameters: Sigma_b = C^2 * |u_b|^(1/m-1) * u_b"
+
+		string="%s\n%s"%(string,fielddisplay(self,"C","friction coefficient [SI]"))
+		string="%s\n%s"%(string,fielddisplay(self,"m","m exponent"))
+		return string
+		#}}}
+	def setdefaultparameters(self): # {{{
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		#Early return
+		if StressbalanceAnalysisEnum() not in analyses and ThermalAnalysisEnum() not in analyses:
+			return md
+
+		md = checkfield(md,'fieldname','friction.C','forcing',1,'NaN',1)
+		md = checkfield(md,'fieldname','friction.m','NaN',1,'size',[md.mesh.numberofelements])
+
+		return md
+	# }}}
+	def marshall(self,md,fid):    # {{{
+		WriteData(fid,'enum',FrictionLawEnum(),'data',2,'format','Integer')
+		WriteData(fid,'class','friction','object',self,'fieldname','C','format','DoubleMat','mattype',1)
+		WriteData(fid,'class','friction','object',self,'fieldname','m','format','DoubleMat','mattype',2)
+	# }}}
Index: /issm/trunk/src/m/classes/geometry.m
===================================================================
--- /issm/trunk/src/m/classes/geometry.m	(revision 17988)
+++ /issm/trunk/src/m/classes/geometry.m	(revision 17989)
@@ -33,5 +33,6 @@
 	end
 	methods
-        function createxml(obj,fid) % {{{
+        %function createxml(obj,fid)
+        function createxml(obj, fid)% {{{
             fprintf(fid, '\n\n');
             fprintf(fid, '%s\n', '<!-- geometry -->');
@@ -40,5 +41,5 @@
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thickness" type="','path','" optional="','false','">','     <section name="geometry" />','     <help> ice thickness [m] </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="bed" type="','path','" optional="','false','">','     <section name="geometry" />','     <help> bed elevation [m] </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="bathymetry" type="',class(obj.bathymetry),'" default="',convert2str(obj.bathymetry),'">','     <section name="geometry" />','     <help> bathymetry elevation [m] </help>','</parameter>');
+            %fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="bathymetry" type="',class(obj.bathymetry),'" default="',convert2str(obj.bathymetry),'">','     <section name="geometry" />','     <help> bathymetry elevation [m] </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','<parameter key ="hydrostatic_ratio" type="',class(obj.hydrostatic_ratio),'" default="',convert2str(obj.hydrostatic_ratio),'">','     <section name="geometry" />','     <help> coefficient for ice shelves; thickness correction: hydrostatic_ratio H_obs+ (1-hydrostatic_ratio) H_hydro </help>','</parameter>');
             fprintf(fid,'%s\n%s\n','</frame>');
Index: /issm/trunk/src/m/classes/gia.m
===================================================================
--- /issm/trunk/src/m/classes/gia.m	(revision 17988)
+++ /issm/trunk/src/m/classes/gia.m	(revision 17989)
@@ -18,5 +18,9 @@
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="mantle_viscosity" type="',class(obj.mantle_viscosity),'" default="',convert2str(obj.mantle_viscosity),'">','     <section name="gia" />','     <help> mantle viscosity[Pa s] </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lithosphere_thickness" type="',class(obj.lithosphere_thickness),'" default="',convert2str(obj.lithosphere_thickness),'">','     <section name="gia" />','     <help> lithosphere thickness (km) </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="cross_section_shape" type="',class(obj.cross_section_shape),'" default="',convert2str(obj.cross_section_shape),'">','     <section name="gia" />','     <help> 1: square-edged (default). 2: elliptical.  See iedge in GiaDeflectionCore </help>','  </parameter>');
+            %cross_section_shape drop-down (1 o r 2)
+            fprintf(fid,'%s\n%s\n%s\n%s\n','  <parameter key ="cross_section_shape" type="alternative" optional="false">','     <section name="gia" />','     <help> 1: square-edged (default). 2: elliptical.  See iedge in GiaDeflectionCore </help>');
+            fprintf(fid,'%s\n','       <option value="1" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="2" type="string" default="false"> </option>','</parameter>');
+            
             fprintf(fid,'%s\n%s\n','</frame>');    
         
Index: /issm/trunk/src/m/classes/groundingline.m
===================================================================
--- /issm/trunk/src/m/classes/groundingline.m	(revision 17988)
+++ /issm/trunk/src/m/classes/groundingline.m	(revision 17989)
@@ -16,5 +16,11 @@
             % Convergence criteria          
             fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Grounding line migration parameters">','<section name="groundingline" />');  
-			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="migration" type="',      class(obj.migration),'" default="',        convert2str(obj.migration),'">',	'     <section name="groundingline" />','     <help> type of grounding line migration: "SoftMigration","AgressiveMigration" or "None" </help>','</parameter>');
+			
+            % migration (SoftMigration, AggressiveMigration, or None)drop-down
+            fprintf(fid,'%s\n%s\n%s\n%s\n','<parameter key ="migration" type="alternative" optional="false">','     <section name="groundingline" />','     <help> type of grounding line migration: "SoftMigration","AggressiveMigration" or "None" </help>');
+            fprintf(fid,'%s\n','       <option value="SoftMigration" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="AggressiveMigration" type="string" default="false"> </option>');
+            fprintf(fid, '%s\n%s\n','       <option value="None" type="string" default="false"></option>','</parameter>');
+
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n',    '<parameter key ="melting_rate" type="',          class(obj.melting_rate),'" default="',            convert2str(obj.melting_rate),'">',     '     <section name="groundingline" />','     <help> melting rate applied when previously grounded parts start floating [m/yr] </help>','</parameter>');
             fprintf(fid,'%s\n%s\n','</frame>');
@@ -39,5 +45,5 @@
 		function md = checkconsistency(obj,md,solution,analyses) % {{{
 
-			md = checkfield(md,'fieldname','groundingline.migration','values',{'None' 'AgressiveMigration' 'SoftMigration' 'SubelementMigration','SubelementMigration2' 'Contact'});
+			md = checkfield(md,'fieldname','groundingline.migration','values',{'None' 'AggressiveMigration' 'SoftMigration' 'SubelementMigration' 'SubelementMigration2' 'Contact' 'None'});
 
 			if ~strcmp(obj.migration,'None'),
@@ -57,5 +63,5 @@
 		function disp(obj) % {{{
 			disp(sprintf('   grounding line migration parameters:'));
-			fielddisplay(obj,'migration','type of grounding line migration: ''SoftMigration'',''AgressiveMigration'' or ''None''');
+			fielddisplay(obj,'migration','type of grounding line migration: ''SoftMigration'',''AggressiveMigration'' or ''None''');
 			fielddisplay(obj,'melting_rate','melting rate applied when previously grounded parts start floating [m/yr]');
 
Index: /issm/trunk/src/m/classes/groundingline.py
===================================================================
--- /issm/trunk/src/m/classes/groundingline.py	(revision 17988)
+++ /issm/trunk/src/m/classes/groundingline.py	(revision 17989)
@@ -26,5 +26,5 @@
 		string='   grounding line migration parameters:'
 
-		string="%s\n%s"%(string,fielddisplay(self,'migration','type of grounding line migration: ''SoftMigration'',''AgressiveMigration'' or ''None'''))
+		string="%s\n%s"%(string,fielddisplay(self,'migration','type of grounding line migration: ''SoftMigration'',''AggressiveMigration'',''SubelementMigration'',''SubelementMigration2'',''Contact'',''None'''))
 		string="%s\n%s"%(string,fielddisplay(self,'melting_rate','melting rate applied when previously grounded parts start floating [m/yr]'))
 		return string
@@ -42,5 +42,5 @@
 	def checkconsistency(self,md,solution,analyses):    # {{{
 
-		md = checkfield(md,'fieldname','groundingline.migration','values',['None','AgressiveMigration','SoftMigration','SubelementMigration','SubelementMigration2','Contact'])
+		md = checkfield(md,'fieldname','groundingline.migration','values',['None','AggressiveMigration','SoftMigration','SubelementMigration','SubelementMigration2','Contact'])
 
 		if not m.strcmp(self.migration,'None'):
Index: /issm/trunk/src/m/classes/hydrologyshreve.m
===================================================================
--- /issm/trunk/src/m/classes/hydrologyshreve.m	(revision 17988)
+++ /issm/trunk/src/m/classes/hydrologyshreve.m	(revision 17989)
@@ -7,9 +7,4 @@
 	properties (SetAccess=public) 
 		spcwatercolumn = NaN;
-		n              = 0;
-		CR             = 0;
-		p              = 0;
-		q              = 0;
-		kn             = 0;
 		stabilization  = 0;
 	end
@@ -23,9 +18,4 @@
             
 			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="spcwatercolumn" type="',      class(obj.spcwatercolumn),'" default="',        convert2str(obj.spcwatercolumn),'">',	'     <section name="hydrologyshreve" />','     <help> water thickness constraints (NaN means no constraint) [m] </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="n" type="',          class(obj.n),'" default="',            convert2str(obj.n),'">',     '     <section name="hydrologyshreve" />','     <help> Manning roughness coefficient </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="CR" type="',        class(obj.CR),'" default="',          convert2str(obj.CR),'">',	'     <section name="hydrologyshreve" />','     <help> tortuosity parameter </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="p" type="',          class(obj.p),'" default="',            convert2str(obj.p),'">',	'     <section name="hydrologyshreve" />','     <help> dimensionless exponent in Manning velocity formula </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="q" type="',  	class(obj.q),'" default="',       convert2str(obj.q),'">',     '     <section name="hydrologyshreve" />','     <help> dimensionless exponent in Manning velocity formula </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="kn" type="',         class(obj.kn),'" default="',           convert2str(obj.kn),'">',	'     <section name="hydrologyshreve" />','     <help> parameter in effective pressure formula </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="stabilization" type="',         class(obj.stabilization),'" default="',           convert2str(obj.stabilization),'">',	'     <section name="hydrologyshreve" />','     <help> artificial diffusivity (default is 1). can be more than 1 to increase diffusivity. </help>','</parameter>');
             fprintf(fid,'%s\n%s\n','</frame>');
@@ -42,11 +32,4 @@
 		end % }}}
 		function obj = setdefaultparameters(obj) % {{{
-
-			%Parameters from Johnson's 2002 thesis, section 3.5.4			 
-			obj.n  = .02;
-			obj.CR = .01;
-			obj.p  = 2;
-			obj.q  = 1;
-			obj.kn = 0;
 
 			%Type of stabilization to use 0:nothing 1:artificial_diffusivity
@@ -65,11 +48,5 @@
 		function disp(obj) % {{{
 			disp(sprintf('   hydrologyshreve solution parameters:'));
-
 			fielddisplay(obj,'spcwatercolumn','water thickness constraints (NaN means no constraint) [m]');
-			fielddisplay(obj,'n','Manning roughness coefficient');
-			fielddisplay(obj,'CR','tortuosity parameter');
-			fielddisplay(obj,'p','dimensionless exponent in Manning velocity formula');
-			fielddisplay(obj,'q','dimensionless exponent in Manning velocity formula');
-			fielddisplay(obj,'kn','parameter in effective pressure formula');
 			fielddisplay(obj,'stabilization','artificial diffusivity (default is 1). can be more than 1 to increase diffusivity.');
 
@@ -78,11 +55,7 @@
 			WriteData(fid,'enum',HydrologyModelEnum(),'data',HydrologyshreveEnum(),'format','Integer');
 			WriteData(fid,'object',obj,'fieldname','spcwatercolumn','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1);
-			WriteData(fid,'object',obj,'fieldname','n','format','Double');
-			WriteData(fid,'object',obj,'fieldname','CR','format','Double');
-			WriteData(fid,'object',obj,'fieldname','p','format','Double');
-			WriteData(fid,'object',obj,'fieldname','q','format','Double');
-			WriteData(fid,'object',obj,'fieldname','kn','format','Double');
 			WriteData(fid,'object',obj,'fieldname','stabilization','format','Double');
 		end % }}}
 	end
 end
+
Index: /issm/trunk/src/m/classes/hydrologyshreve.py
===================================================================
--- /issm/trunk/src/m/classes/hydrologyshreve.py	(revision 17988)
+++ /issm/trunk/src/m/classes/hydrologyshreve.py	(revision 17989)
@@ -14,9 +14,4 @@
 	def __init__(self): # {{{
 		self.spcwatercolumn = float('NaN')
-		self.n              = 0
-		self.CR             = 0
-		self.p              = 0
-		self.q              = 0
-		self.kn             = 0
 		self.stabilization  = 0
 
@@ -29,9 +24,4 @@
 		string='   hydrologyshreve solution parameters:'
 		string="%s\n%s"%(string,fielddisplay(self,'spcwatercolumn','water thickness constraints (NaN means no constraint) [m]'))
-		string="%s\n%s"%(string,fielddisplay(self,'n','Manning roughness coefficient'))
-		string="%s\n%s"%(string,fielddisplay(self,'CR','tortuosity parameter'))
-		string="%s\n%s"%(string,fielddisplay(self,'p','dimensionless exponent in Manning velocity formula'))
-		string="%s\n%s"%(string,fielddisplay(self,'q','dimensionless exponent in Manning velocity formula'))
-		string="%s\n%s"%(string,fielddisplay(self,'kn','parameter in effective pressure formula'))
 		string="%s\n%s"%(string,fielddisplay(self,'stabilization','artificial diffusivity (default is 1). can be more than 1 to increase diffusivity.'))
 		return string
@@ -39,11 +29,4 @@
 	def setdefaultparameters(self): # {{{
 		
-		#Parameters from Johnson's 2002 thesis, section 3.5.4			 
-		self.n=.02			
-		self.CR=.01
-		self.p=2
-		self.q=1
-		self.kn=0
-
 		#Type of stabilization to use 0:nothing 1:artificial_diffusivity
 		self.stabilization=1
@@ -65,9 +48,4 @@
 		WriteData(fid,'enum',HydrologyModelEnum(),'data',HydrologyshreveEnum(),'format','Integer');
 		WriteData(fid,'object',self,'fieldname','spcwatercolumn','format','DoubleMat','mattype',1,'forcinglength',md.mesh.numberofvertices+1)
-		WriteData(fid,'object',self,'fieldname','n','format','Double')
-		WriteData(fid,'object',self,'fieldname','CR','format','Double')
-		WriteData(fid,'object',self,'fieldname','p','format','Double')
-		WriteData(fid,'object',self,'fieldname','q','format','Double')
-		WriteData(fid,'object',self,'fieldname','kn','format','Double')
 		WriteData(fid,'object',self,'fieldname','stabilization','format','Double')
 	# }}}
Index: /issm/trunk/src/m/classes/inversion.m
===================================================================
--- /issm/trunk/src/m/classes/inversion.m	(revision 17988)
+++ /issm/trunk/src/m/classes/inversion.m	(revision 17989)
@@ -7,5 +7,4 @@
 	properties (SetAccess=public) 
 		iscontrol                   = 0
-		tao                         = 0
 		incomplete_adjoint          = 0
 		control_parameters          = NaN
@@ -32,5 +31,10 @@
             fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="inversion parameters">','<section name="inversion" />');                    
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="iscontrol" type="',class(obj.iscontrol),'" default="',convert2str(obj.iscontrol),'">','     <section name="inversion" />','     <help> is inversion activated? </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="incomplete_adjoint" type="',class(obj.incomplete_adjoint),'" default="',convert2str(obj.incomplete_adjoint),'">','     <section name="inversion" />','     <help> 1: linear viscosity, 0: non-linear viscosity </help>','  </parameter>');
+            
+            % incompleteadjoing drop-down (0 or 1)
+            fprintf(fid,'%s\n%s\n%s\n%s\n','  <parameter key ="incomplete_adjoint" type="alternative" optional="false">','     <section name="inversion" />','     <help> 1: linear viscosity, 0: non-linear viscosity </help>');
+            fprintf(fid,'%s\n','       <option value="0" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="1" type="string" default="false"> </option>','</parameter>');
+            
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="control_parameters" type="',class(obj.control_parameters),'" default="',convert2str(obj.control_parameters),'">','     <section name="inversion" />','     <help> ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''} </help>','  </parameter>');
                 
@@ -75,31 +79,5 @@
 					obj=setdefaultparameters(obj);
 				case 1
-					if isa(varargin{1},'taoinversion'),
-						disp('converting taoinversion');
-						in=varargin{1};
-						obj=inversion();
-						obj.iscontrol                   = in.iscontrol;
-						obj.tao                         = 1;rsion to inve
-						obj.incomplete_adjoint          = in.incomplete_adjoint;
-						obj.control_parameters          = in.control_parameters;
-						obj.nsteps                      = in.nsteps;
-						obj.maxiter_per_step            = 10*ones(in.nsteps,1);
-						obj.cost_functions              = in.cost_functions;
-						obj.cost_functions_coefficients = in.cost_functions_coefficients;
-						obj.gradient_scaling            = 100*ones(in.nsteps,1);
-						obj.cost_function_threshold     = NaN;
-						obj.min_parameters              = in.min_parameters;
-						obj.max_parameters              = in.max_parameters;
-						obj.step_threshold              = .99*ones(in.nsteps,1);
-						obj.vx_obs                      = in.vx_obs;
-						obj.vy_obs                      = in.vy_obs;
-						obj.vz_obs                      = in.vz_obs;
-						obj.vel_obs                     = in.vel_obs;
-						obj.thickness_obs               = in.thickness_obs;
-					elseif isa(varargin{1},'inversion'),
-						obj = varargin{1};
-					else
-						error('constructor not supported');
-					end
+					obj=structtoobj(inversion(),varargin{1});
 				otherwise
 					error('constructor not supported');
@@ -152,5 +130,4 @@
 
 			md = checkfield(md,'fieldname','inversion.iscontrol','values',[0 1]);
-			md = checkfield(md,'fieldname','inversion.tao','values',[0 1]);
 			md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0 1]);
 			md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',...
@@ -214,6 +191,6 @@
 			yts=365.0*24.0*3600.0;
 
+			WriteData(fid,'enum',InversionTypeEnum(),'data',0,'format','Integer');
 			WriteData(fid,'object',obj,'fieldname','iscontrol','format','Boolean');
-			WriteData(fid,'object',obj,'fieldname','tao','format','Boolean');
 			WriteData(fid,'object',obj,'fieldname','incomplete_adjoint','format','Boolean');
 			if ~obj.iscontrol, return; end
Index: /issm/trunk/src/m/classes/inversion.py
===================================================================
--- /issm/trunk/src/m/classes/inversion.py	(revision 17988)
+++ /issm/trunk/src/m/classes/inversion.py	(revision 17989)
@@ -12,10 +12,9 @@
 
 	   Usage:
-	      inversion=inversion();
+	      inversion=inversion()
 	"""
 
 	def __init__(self): # {{{
 		self.iscontrol                   = 0
-		self.tao                         = 0
 		self.incomplete_adjoint          = 0
 		self.control_parameters          = float('NaN')
@@ -117,5 +116,4 @@
 
 		md = checkfield(md,'fieldname','inversion.iscontrol','values',[0,1])
-		md = checkfield(md,'fieldname','inversion.tao','values',[0,1])
 		md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0,1])
 		md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',['BalancethicknessThickeningRate','FrictionCoefficient','MaterialsRheologyBbar','DamageDbar','Vx','Vy'])
@@ -146,6 +144,6 @@
 		yts=365.0*24.0*3600.0
 
+		WriteData(fid,'enum',InversionTypeEnum(),'data',0,'format','Integer')
 		WriteData(fid,'object',self,'fieldname','iscontrol','format','Boolean')
-		WriteData(fid,'object',self,'fieldname','tao','format','Boolean')
 		WriteData(fid,'object',self,'fieldname','incomplete_adjoint','format','Boolean')
 		if not self.iscontrol:
Index: /issm/trunk/src/m/classes/m1qn3inversion.m
===================================================================
--- /issm/trunk/src/m/classes/m1qn3inversion.m	(revision 17989)
+++ /issm/trunk/src/m/classes/m1qn3inversion.m	(revision 17989)
@@ -0,0 +1,170 @@
+%M1QN3INVERSION class definition
+%
+%   Usage:
+%      m1qn3inversion=m1qn3inversion();
+
+classdef m1qn3inversion
+	properties (SetAccess=public) 
+		iscontrol                   = 0
+		incomplete_adjoint          = 0
+		control_parameters          = NaN
+		maxsteps                    = 0
+		maxiter                     = 0
+		dxmin                       = 0;
+		gttol                       = 0;
+		cost_functions              = NaN
+		cost_functions_coefficients = NaN
+		min_parameters              = NaN
+		max_parameters              = NaN
+		vx_obs                      = NaN
+		vy_obs                      = NaN
+		vz_obs                      = NaN
+		vel_obs                     = NaN
+		thickness_obs               = NaN
+
+	end
+	methods
+		function obj = m1qn3inversion(varargin) % {{{
+			switch nargin
+				case 0
+					obj=setdefaultparameters(obj);
+				case 1
+					obj=structtoobj(m1qn3inversion(),varargin{1});
+				otherwise
+					error('constructor not supported');
+			end
+		end % }}}
+		function self = setdefaultparameters(self) % {{{
+
+			%default is incomplete adjoint for now
+			self.incomplete_adjoint=1;
+
+			%parameter to be inferred by control methods (only
+			%drag and B are supported yet)
+			self.control_parameters={'FrictionCoefficient'};
+
+			%number of iterations
+			self.maxsteps=20;
+			self.maxiter=40;
+
+			%several responses can be used:
+			self.cost_functions=101;
+
+			%m1qn3 parameters
+			self.dxmin  = 0.1;
+			self.gttol = 1e-4;
+
+		end % }}}
+		function md = checkconsistency(obj,md,solution,analyses) % {{{
+
+			%Early return
+			if ~obj.iscontrol, return; end
+
+			if ~IssmConfig('_HAVE_M1QN3_'),
+				md = checkmessage(md,['M1QN3 has not been installed, ISSM needs to be reconfigured and recompiled with M1QN3']);
+			end
+
+			num_controls=numel(md.inversion.control_parameters);
+			num_costfunc=size(md.inversion.cost_functions,2);
+
+			md = checkfield(md,'fieldname','inversion.iscontrol','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0 1]);
+			md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',...
+				{'BalancethicknessThickeningRate' 'FrictionCoefficient' 'MaterialsRheologyBbar' 'MaterialsRheologyZbar' 'Vx' 'Vy' 'Thickness'});
+			md = checkfield(md,'fieldname','inversion.maxsteps','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.maxiter','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.dxmin','numel',1,'>',0);
+			md = checkfield(md,'fieldname','inversion.gttol','numel',1,'>',0);
+			md = checkfield(md,'fieldname','inversion.cost_functions','size',[1 num_costfunc],'values',[101:105 201 501:506]);
+			md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
+			md = checkfield(md,'fieldname','inversion.min_parameters','size',[md.mesh.numberofvertices num_controls]);
+			md = checkfield(md,'fieldname','inversion.max_parameters','size',[md.mesh.numberofvertices num_controls]);
+
+			if solution==BalancethicknessSolutionEnum()
+				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+			elseif solution==BalancethicknessSoftSolutionEnum()
+				md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+			else
+				md = checkfield(md,'fieldname','inversion.vx_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				if ~strcmp(domaintype(md.mesh),'2Dvertical'),
+					md = checkfield(md,'fieldname','inversion.vy_obs','size',[md.mesh.numberofvertices 1],'NaN',1);
+				end
+			end
+		end % }}}
+		function disp(obj) % {{{
+			disp(sprintf('   m1qn3inversion parameters:'));
+			fielddisplay(obj,'iscontrol','is inversion activated?');
+			fielddisplay(obj,'incomplete_adjoint','1: linear viscosity, 0: non-linear viscosity');
+			fielddisplay(obj,'control_parameters','ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''}');
+			fielddisplay(obj,'maxsteps','maximum number of iterations (gradient computation)');
+			fielddisplay(obj,'maxiter','maximum number of Function evaluation (forward run)');
+			fielddisplay(obj,'dxmin','convergence criterion: two points less than dxmin from eachother (sup-norm) are considered identical');
+			fielddisplay(obj,'gttol','convergence criterion: ||g(X)||/||g(X0)|| (g(X0): gradient at initial guess X0)');
+			fielddisplay(obj,'cost_functions','indicate the type of response for each optimization step');
+			fielddisplay(obj,'cost_functions_coefficients','cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter');
+			fielddisplay(obj,'min_parameters','absolute minimum acceptable value of the inversed parameter on each vertex');
+			fielddisplay(obj,'max_parameters','absolute maximum acceptable value of the inversed parameter on each vertex');
+			fielddisplay(obj,'vx_obs','observed velocity x component [m/yr]');
+			fielddisplay(obj,'vy_obs','observed velocity y component [m/yr]');
+			fielddisplay(obj,'vel_obs','observed velocity magnitude [m/yr]');
+			fielddisplay(obj,'thickness_obs','observed thickness [m]');
+			disp('Available cost functions:');
+			disp('   101: SurfaceAbsVelMisfit');
+			disp('   102: SurfaceRelVelMisfit');
+			disp('   103: SurfaceLogVelMisfit');
+			disp('   104: SurfaceLogVxVyMisfit');
+			disp('   105: SurfaceAverageVelMisfit');
+			disp('   201: ThicknessAbsMisfit');
+			disp('   501: DragCoefficientAbsGradient');
+			disp('   502: RheologyBbarAbsGradient');
+			disp('   503: ThicknessAbsGradient');
+		end % }}}
+		function marshall(obj,md,fid) % {{{
+
+			yts=365.0*24.0*3600.0;
+
+			WriteData(fid,'object',obj,'class','inversion','fieldname','iscontrol','format','Boolean');
+			WriteData(fid,'enum',InversionTypeEnum(),'data',2,'format','Integer');
+			if ~obj.iscontrol, return; end
+			WriteData(fid,'object',obj,'class','inversion','fieldname','incomplete_adjoint','format','Boolean');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','maxsteps','format','Integer');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','maxiter','format','Integer');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','dxmin','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','gttol','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','cost_functions_coefficients','format','DoubleMat','mattype',1);
+			WriteData(fid,'object',obj,'class','inversion','fieldname','min_parameters','format','DoubleMat','mattype',3);
+			WriteData(fid,'object',obj,'class','inversion','fieldname','max_parameters','format','DoubleMat','mattype',3);
+			WriteData(fid,'object',obj,'class','inversion','fieldname','vx_obs','format','DoubleMat','mattype',1,'scale',1./yts);
+			WriteData(fid,'object',obj,'class','inversion','fieldname','vy_obs','format','DoubleMat','mattype',1,'scale',1./yts);
+			WriteData(fid,'object',obj,'class','inversion','fieldname','vz_obs','format','DoubleMat','mattype',1,'scale',1./yts);
+			WriteData(fid,'object',obj,'class','inversion','fieldname','thickness_obs','format','DoubleMat','mattype',1);
+
+			%process control parameters
+			num_control_parameters=numel(obj.control_parameters);
+			data=zeros(1,num_control_parameters);
+			for i=1:num_control_parameters,
+				data(i)=StringToEnum(obj.control_parameters{i});
+			end
+			WriteData(fid,'data',data,'enum',InversionControlParametersEnum(),'format','DoubleMat','mattype',3);
+			WriteData(fid,'data',num_control_parameters,'enum',InversionNumControlParametersEnum(),'format','Integer');
+
+			%process cost functions
+			num_cost_functions=size(obj.cost_functions,2);
+			data=obj.cost_functions;
+			pos=find(obj.cost_functions==101); data(pos)=SurfaceAbsVelMisfitEnum();
+			pos=find(obj.cost_functions==102); data(pos)=SurfaceRelVelMisfitEnum();
+			pos=find(obj.cost_functions==103); data(pos)=SurfaceLogVelMisfitEnum();
+			pos=find(obj.cost_functions==104); data(pos)=SurfaceLogVxVyMisfitEnum();
+			pos=find(obj.cost_functions==105); data(pos)=SurfaceAverageVelMisfitEnum();
+			pos=find(obj.cost_functions==201); data(pos)=ThicknessAbsMisfitEnum();
+			pos=find(obj.cost_functions==501); data(pos)=DragCoefficientAbsGradientEnum();
+			pos=find(obj.cost_functions==502); data(pos)=RheologyBbarAbsGradientEnum();
+			pos=find(obj.cost_functions==503); data(pos)=ThicknessAbsGradientEnum();
+			pos=find(obj.cost_functions==504); data(pos)=ThicknessAlongGradientEnum();
+			pos=find(obj.cost_functions==505); data(pos)=ThicknessAcrossGradientEnum();
+			pos=find(obj.cost_functions==506); data(pos)=BalancethicknessMisfitEnum();
+			WriteData(fid,'data',data,'enum',InversionCostFunctionsEnum(),'format','DoubleMat','mattype',3);
+			WriteData(fid,'data',num_cost_functions,'enum',InversionNumCostFunctionsEnum(),'format','Integer');
+		end % }}}
+	end
+end
Index: /issm/trunk/src/m/classes/m1qn3inversion.py
===================================================================
--- /issm/trunk/src/m/classes/m1qn3inversion.py	(revision 17989)
+++ /issm/trunk/src/m/classes/m1qn3inversion.py	(revision 17989)
@@ -0,0 +1,193 @@
+import numpy
+import copy
+from fielddisplay import fielddisplay
+from EnumDefinitions import *
+from StringToEnum import StringToEnum
+from checkfield import checkfield
+from WriteData import WriteData
+
+class m1qn3inversion(object):
+	'''
+	M1QN3 class definition
+
+   Usage:
+      m1qn3inversion=m1qn3inversion()
+	'''
+
+	def __init__(self,*args): # {{{
+
+		if not len(args):
+			print 'empty init'
+			self.iscontrol                   = 0
+			self.incomplete_adjoint          = 0
+			self.control_parameters          = float('NaN')
+			self.maxsteps                    = 0
+			self.maxiter                     = 0
+			self.dxmin                       = 0.
+			self.gttol                       = 0.
+			self.cost_functions              = float('NaN')
+			self.cost_functions_coefficients = float('NaN')
+			self.min_parameters              = float('NaN')
+			self.max_parameters              = float('NaN')
+			self.vx_obs                      = float('NaN')
+			self.vy_obs                      = float('NaN')
+			self.vz_obs                      = float('NaN')
+			self.vel_obs                     = float('NaN')
+			self.thickness_obs               = float('NaN')
+
+			#set defaults
+			self.setdefaultparameters()
+		elif len(args)==1 and args[0].__module__=='inversion':
+			print 'converting inversion to m1qn3inversion'
+			inv=args[0]
+			self.iscontrol                   = inv.iscontrol
+			self.incomplete_adjoint          = inv.incomplete_adjoint
+			self.control_parameters          = inv.control_parameters
+			self.maxsteps                    = inv.nsteps
+			self.cost_functions              = inv.cost_functions
+			self.cost_functions_coefficients = inv.cost_functions_coefficients
+			self.min_parameters              = inv.min_parameters
+			self.max_parameters              = inv.max_parameters
+			self.vx_obs                      = inv.vx_obs
+			self.vy_obs                      = inv.vy_obs
+			self.vz_obs                      = inv.vz_obs
+			self.vel_obs                     = inv.vel_obs
+			self.thickness_obs               = inv.thickness_obs
+		else:
+			raise Exception('constructor not supported')
+		#}}}
+	def __repr__(self): # {{{
+		string='   m1qn3inversion parameters:'
+		string="%s\n%s"%(string,fielddisplay(self,'iscontrol','is inversion activated?'))
+		string="%s\n%s"%(string,fielddisplay(self,'incomplete_adjoint','1: linear viscosity, 0: non-linear viscosity'))
+		string="%s\n%s"%(string,fielddisplay(self,'control_parameters','ex: [''FrictionCoefficient''], or [''MaterialsRheologyBbar'']'))
+		string="%s\n%s"%(string,fielddisplay(self,'maxsteps','maximum number of iterations (gradient computation)'))
+		string="%s\n%s"%(string,fielddisplay(self,'maxiter','maximum number of Function evaluation (forward run)'))
+		string="%s\n%s"%(string,fielddisplay(self,'dxmin','convergence criterion: two points less than dxmin from eachother (sup-norm) are considered identical'))
+		string="%s\n%s"%(string,fielddisplay(self,'gttol','||g(X)||/||g(X0)|| (g(X0): gradient at initial guess X0)'))
+		string="%s\n%s"%(string,fielddisplay(self,'cost_functions','indicate the type of response for each optimization step'))
+		string="%s\n%s"%(string,fielddisplay(self,'cost_functions_coefficients','cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter'))
+		string="%s\n%s"%(string,fielddisplay(self,'min_parameters','absolute minimum acceptable value of the inversed parameter on each vertex'))
+		string="%s\n%s"%(string,fielddisplay(self,'max_parameters','absolute maximum acceptable value of the inversed parameter on each vertex'))
+		string="%s\n%s"%(string,fielddisplay(self,'vx_obs','observed velocity x component [m/yr]'))
+		string="%s\n%s"%(string,fielddisplay(self,'vy_obs','observed velocity y component [m/yr]'))
+		string="%s\n%s"%(string,fielddisplay(self,'vel_obs','observed velocity magnitude [m/yr]'))
+		string="%s\n%s"%(string,fielddisplay(self,'thickness_obs','observed thickness [m]'))
+		string="%s\n%s"%(string,'Available cost functions:')
+		string="%s\n%s"%(string,'   101: SurfaceAbsVelMisfit')
+		string="%s\n%s"%(string,'   102: SurfaceRelVelMisfit')
+		string="%s\n%s"%(string,'   103: SurfaceLogVelMisfit')
+		string="%s\n%s"%(string,'   104: SurfaceLogVxVyMisfit')
+		string="%s\n%s"%(string,'   105: SurfaceAverageVelMisfit')
+		string="%s\n%s"%(string,'   201: ThicknessAbsMisfit')
+		string="%s\n%s"%(string,'   501: DragCoefficientAbsGradient')
+		string="%s\n%s"%(string,'   502: RheologyBbarAbsGradient')
+		string="%s\n%s"%(string,'   503: ThicknessAbsGradient')
+		return string
+		#}}}
+	def setdefaultparameters(self): # {{{
+		
+		#default is incomplete adjoint for now
+		self.incomplete_adjoint=1
+
+		#parameter to be inferred by control methods (only
+		#drag and B are supported yet)
+		self.control_parameters='FrictionCoefficient'
+
+		#number of iterations
+		self.maxsteps=20
+		self.maxiter=40
+
+		#several responses can be used:
+		self.cost_functions=101
+
+		#m1qn3 parameters
+		self.dxmin  = 0.1
+		self.gttol = 1e-4
+
+		return self
+	#}}}
+	def checkconsistency(self,md,solution,analyses):    # {{{
+
+		#Early return
+		if not self.iscontrol:
+			return md
+
+		num_controls=numpy.size(md.inversion.control_parameters)
+		num_costfunc=numpy.size(md.inversion.cost_functions)
+
+		md = checkfield(md,'fieldname','inversion.iscontrol','values',[0,1])
+		md = checkfield(md,'fieldname','inversion.incomplete_adjoint','values',[0,1])
+		md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',['BalancethicknessThickeningRate','FrictionCoefficient','MaterialsRheologyBbar','DamageDbar','Vx','Vy','Thickness'])
+		md = checkfield(md,'fieldname','inversion.maxsteps','numel',[1],'>=',0)
+		md = checkfield(md,'fieldname','inversion.maxiter','numel',[1],'>=',0)
+		md = checkfield(md,'fieldname','inversion.dxmin','numel',[1],'>',0.)
+		md = checkfield(md,'fieldname','inversion.gttol','numel',[1],'>',0.)
+		md = checkfield(md,'fieldname','inversion.cost_functions','size',[num_costfunc],'values',[101,102,103,104,105,201,501,502,503,504,505])
+		md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices,num_costfunc],'>=',0)
+		md = checkfield(md,'fieldname','inversion.min_parameters','size',[md.mesh.numberofvertices,num_controls])
+		md = checkfield(md,'fieldname','inversion.max_parameters','size',[md.mesh.numberofvertices,num_controls])
+
+		if solution==BalancethicknessSolutionEnum():
+			md = checkfield(md,'fieldname','inversion.thickness_obs','size',[md.mesh.numberofvertices],'NaN',1)
+		else:
+			md = checkfield(md,'fieldname','inversion.vx_obs','size',[md.mesh.numberofvertices],'NaN',1)
+			md = checkfield(md,'fieldname','inversion.vy_obs','size',[md.mesh.numberofvertices],'NaN',1)
+
+		return md
+	# }}}
+	def marshall(self,md,fid):    # {{{
+
+		yts=365.0*24.0*3600.0
+
+		WriteData(fid,'object',self,'class','inversion','fieldname','iscontrol','format','Boolean')
+		WriteData(fid,'enum',InversionTypeEnum(),'data',2,'format','Integer')
+		if not self.iscontrol:
+			return
+		WriteData(fid,'object',self,'class','inversion','fieldname','incomplete_adjoint','format','Boolean')
+		WriteData(fid,'object',self,'class','inversion','fieldname','maxsteps','format','Integer')
+		WriteData(fid,'object',self,'class','inversion','fieldname','maxiter','format','Integer')
+		WriteData(fid,'object',self,'class','inversion','fieldname','dxmin','format','Double')
+		WriteData(fid,'object',self,'class','inversion','fieldname','gttol','format','Double')
+		WriteData(fid,'object',self,'class','inversion','fieldname','cost_functions_coefficients','format','DoubleMat','mattype',1)
+		WriteData(fid,'object',self,'class','inversion','fieldname','min_parameters','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'class','inversion','fieldname','max_parameters','format','DoubleMat','mattype',3)
+		WriteData(fid,'object',self,'class','inversion','fieldname','vx_obs','format','DoubleMat','mattype',1,'scale',1./yts)
+		WriteData(fid,'object',self,'class','inversion','fieldname','vy_obs','format','DoubleMat','mattype',1,'scale',1./yts)
+		WriteData(fid,'object',self,'class','inversion','fieldname','vz_obs','format','DoubleMat','mattype',1,'scale',1./yts)
+		WriteData(fid,'object',self,'class','inversion','fieldname','thickness_obs','format','DoubleMat','mattype',1)
+
+		#process control parameters
+		num_control_parameters=len(self.control_parameters)
+		data=numpy.array([StringToEnum(control_parameter)[0] for control_parameter in self.control_parameters]).reshape(1,-1)
+		WriteData(fid,'data',data,'enum',InversionControlParametersEnum(),'format','DoubleMat','mattype',3)
+		WriteData(fid,'data',num_control_parameters,'enum',InversionNumControlParametersEnum(),'format','Integer')
+
+		#process cost functions
+		num_cost_functions=numpy.size(self.cost_functions)
+		data=copy.deepcopy(self.cost_functions)
+		pos=[i for i,x in enumerate(self.cost_functions) if x==101];
+		for i in pos: data[i]=SurfaceAbsVelMisfitEnum()        
+		pos=[i for i,x in enumerate(self.cost_functions) if x==102];
+		for i in pos: data[i]=SurfaceRelVelMisfitEnum()        
+		pos=[i for i,x in enumerate(self.cost_functions) if x==103];
+		for i in pos: data[i]=SurfaceLogVelMisfitEnum()        
+		pos=[i for i,x in enumerate(self.cost_functions) if x==104];
+		for i in pos: data[i]=SurfaceLogVxVyMisfitEnum()       
+		pos=[i for i,x in enumerate(self.cost_functions) if x==105];
+		for i in pos: data[i]=SurfaceAverageVelMisfitEnum()    
+		pos=[i for i,x in enumerate(self.cost_functions) if x==201];
+		for i in pos: data[i]=ThicknessAbsMisfitEnum()         
+		pos=[i for i,x in enumerate(self.cost_functions) if x==501];
+		for i in pos: data[i]=DragCoefficientAbsGradientEnum() 
+		pos=[i for i,x in enumerate(self.cost_functions) if x==502];
+		for i in pos: data[i]=RheologyBbarAbsGradientEnum()    
+		pos=[i for i,x in enumerate(self.cost_functions) if x==503];
+		for i in pos: data[i]=ThicknessAbsGradientEnum()       
+		pos=[i for i,x in enumerate(self.cost_functions) if x==504];
+		for i in pos: data[i]=ThicknessAlongGradientEnum()     
+		pos=[i for i,x in enumerate(self.cost_functions) if x==505];
+		for i in pos: data[i]=ThicknessAcrossGradientEnum()    
+		WriteData(fid,'data',numpy.array(data).reshape(1,-1),'enum',InversionCostFunctionsEnum(),'format','DoubleMat','mattype',3)
+		WriteData(fid,'data',num_cost_functions,'enum',InversionNumCostFunctionsEnum(),'format','Integer')
+	# }}}
Index: /issm/trunk/src/m/classes/masstransport.m
===================================================================
--- /issm/trunk/src/m/classes/masstransport.m	(revision 17988)
+++ /issm/trunk/src/m/classes/masstransport.m	(revision 17989)
@@ -52,6 +52,17 @@
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isfreesurface" type="',class(obj.isfreesurface),'" default="',convert2str(obj.isfreesurface),'">','     <section name="masstransport" />','     <help> do we use free surfaces (FS only) are mass conservation </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="min_thickness" type="',class(obj.min_thickness),'" default="',convert2str(obj.min_thickness),'">','     <section name="masstransport" />','     <help> minimum ice thickness allowed [m] </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="hydrostatic_adjustment" type="',class(obj.hydrostatic_adjustment),'" default="',convert2str(obj.hydrostatic_adjustment),'">','     <section name="masstransport" />','     <help> adjustment of ice shelves surface and bed elevations: ''Incremental'' or ''Absolute''  </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="stabilization" type="',class(obj.stabilization),'" default="',convert2str(obj.stabilization),'">','     <section name="masstransport" />','     <help> 0: no, 1:  artificial_diffusivity, 2: streamline upwinding, 3: discontinuous Galerkin </help>','  </parameter>');
+            
+            % hydrostatic_adjustment drop-down (incremental or absolute )
+            fprintf(fid,'%s\n%s\n%s\n%s\n','  <parameter key ="hydrostatic_adjustment" type="alternative" optional ="false">','     <section name="masstransport" />','     <help> adjustment of ice shelves surface and bed elevations: ''Incremental'' or ''Absolute''  </help>');
+            fprintf(fid,'%s\n','       <option value="Incremental" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="Absolute" type="string" default="false"> </option>','</parameter>');
+            
+            %stabilization drop-down (0, 1, 2, or 3)
+            fprintf(fid,'%s\n%s\n%s\n%s\n','  <parameter key ="stabilization" type="alternative" optional="false">','     <section name="masstransport" />','     <help> 0: no, 1:  artificial_diffusivity, 2: streamline upwinding, 3: discontinuous Galerkin </help>');
+            fprintf(fid,'%s\n','       <option value="0" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="1" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','       <option value="2" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="3" type="string" default="false"> </option>','</parameter>');
+
             fprintf(fid,'%s\n%s\n','</frame>');    
             
Index: /issm/trunk/src/m/classes/matdamageice.m
===================================================================
--- /issm/trunk/src/m/classes/matdamageice.m	(revision 17988)
+++ /issm/trunk/src/m/classes/matdamageice.m	(revision 17989)
@@ -30,38 +30,38 @@
 	end
 	methods
-        function createxml(obj,fid) % {{{
-            fprintf(fid, '\n\n');
-            fprintf(fid, '<!-- materials -->\n');
-			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_ice" type="',class(obj.rho_ice),'" default="',convert2str(obj.rho_ice),'">','     <section name="materials" />','     <help> ice density [kg/m^3] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_water" type="',class(obj.rho_water),'" default="',convert2str(obj.rho_water),'">','     <section name="materials" />','     <help> ocean water density [kg/m^3] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_freshwater" type="',class(obj.rho_freshwater),'" default="',convert2str(obj.rho_freshwater),'">','     <section name="materials" />','     <help> fresh water density [kg/m^3] </help>','</parameter>');
-             
-  
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mu_water" type="',class(obj.mu_water),'" default="',convert2str(obj.mu_water),'">','     <section name="materials" />','     <help> water viscosity [N s/m^2] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="heatcapacity" type="',class(obj.heatcapacity),'" default="',convert2str(obj.heatcapacity),'">','     <section name="materials" />','     <help> heat capacity [J/kg/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="latentheat" type="',class(obj.latentheat),'" default="',convert2str(obj.latentheat),'">','     <section name="materials" />','     <help> latent heat of fusion [J/kg] </help>','</parameter>');
-             
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermalconductivity" type="',class(obj.thermalconductivity),'" default="',convert2str(obj.thermalconductivity),'">','     <section name="materials" />','     <help> ice thermal conductivity [W/m/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperateiceconductivity" type="',class(obj.temperateiceconductivity),'" default="',convert2str(obj.temperateiceconductivity),'">','     <section name="materials" />','     <help> temperate ice thermal conductivity [W/m/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="meltingpoint" type="',class(obj.meltingpoint),'" default="',convert2str(obj.meltingpoint),'">','     <section name="materials" />','     <help> melting point of ice at 1atm in K </help>','</parameter>');
-             
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="beta" type="',class(obj.beta),'" default="',convert2str(obj.beta),'">','     <section name="materials" />','     <help> rate of change of melting point with pressure [K/Pa] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mixed_layer_capacity" type="',class(obj.mixed_layer_capacity),'" default="',convert2str(obj.mixed_layer_capacity),'">','     <section name="materials" />','     <help> mixed layer capacity [W/kg/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermal_exchange_velocity" type="',class(obj.thermal_exchange_velocity),'" default="',convert2str(obj.thermal_exchange_velocity),'">','     <section name="materials" />','     <help> thermal exchange velocity [m/s] </help>','</parameter>');
-             
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_B" type="',class(obj.rheology_B),'" default="',convert2str(obj.rheology_B),'">','     <section name="materials" />','     <help> flow law parameter [Pa/s^(1/n)] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_n" type="',class(obj.rheology_n),'" default="',convert2str(obj.rheology_n),'">','     <section name="materials" />','     <help> Glens flow law exponent </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_law" type="',class(obj.rheology_law),'" default="',convert2str(obj.rheology_law),'">','     <section name="materials" />','     <help> law for the temperature dependance of the rheology: "None", "Paterson",  "Arrhenius" or "LliboutryDuval" </help>','</parameter>');
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_shear_modulus" type="',class(obj.lithosphere_shear_modulus),'" default="',convert2str(obj.lithosphere_shear_modulus),'">','     <section name="materials" />','     <help> Lithosphere shear modulus [Pa] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_density" type="',class(obj.lithosphere_density),'" default="',convert2str(obj.lithosphere_density),'">','     <section name="materials" />','     <help> Lithosphere density [g/cm^-3] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_shear_modulus" type="',class(obj.mantle_shear_modulus),'" default="',convert2str(obj.mantle_shear_modulus),'">','     <section name="materials" />','     <help> Mantle shear modulus [Pa] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_density" type="',class(obj.mantle_density),'" default="',convert2str(obj.mantle_density),'">','     <section name="materials" />','     <help> Mantle density [g/cm^-3] </help>','</parameter>');
-        
-         
-        end % }}}
+		function createxml(obj,fid) % {{{
+			fprintf(fid, '\n\n');
+			fprintf(fid, '<!-- materials -->\n');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_ice" type="',class(obj.rho_ice),'" default="',convert2str(obj.rho_ice),'">','     <section name="materials" />','     <help> ice density [kg/m^3] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_water" type="',class(obj.rho_water),'" default="',convert2str(obj.rho_water),'">','     <section name="materials" />','     <help> ocean water density [kg/m^3] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_freshwater" type="',class(obj.rho_freshwater),'" default="',convert2str(obj.rho_freshwater),'">','     <section name="materials" />','     <help> fresh water density [kg/m^3] </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mu_water" type="',class(obj.mu_water),'" default="',convert2str(obj.mu_water),'">','     <section name="materials" />','     <help> water viscosity [N s/m^2] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="heatcapacity" type="',class(obj.heatcapacity),'" default="',convert2str(obj.heatcapacity),'">','     <section name="materials" />','     <help> heat capacity [J/kg/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="latentheat" type="',class(obj.latentheat),'" default="',convert2str(obj.latentheat),'">','     <section name="materials" />','     <help> latent heat of fusion [J/kg] </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermalconductivity" type="',class(obj.thermalconductivity),'" default="',convert2str(obj.thermalconductivity),'">','     <section name="materials" />','     <help> ice thermal conductivity [W/m/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperateiceconductivity" type="',class(obj.temperateiceconductivity),'" default="',convert2str(obj.temperateiceconductivity),'">','     <section name="materials" />','     <help> temperate ice thermal conductivity [W/m/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="meltingpoint" type="',class(obj.meltingpoint),'" default="',convert2str(obj.meltingpoint),'">','     <section name="materials" />','     <help> melting point of ice at 1atm in K </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="beta" type="',class(obj.beta),'" default="',convert2str(obj.beta),'">','     <section name="materials" />','     <help> rate of change of melting point with pressure [K/Pa] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mixed_layer_capacity" type="',class(obj.mixed_layer_capacity),'" default="',convert2str(obj.mixed_layer_capacity),'">','     <section name="materials" />','     <help> mixed layer capacity [W/kg/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermal_exchange_velocity" type="',class(obj.thermal_exchange_velocity),'" default="',convert2str(obj.thermal_exchange_velocity),'">','     <section name="materials" />','     <help> thermal exchange velocity [m/s] </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_B" type="',class(obj.rheology_B),'" default="',convert2str(obj.rheology_B),'">','     <section name="materials" />','     <help> flow law parameter [Pa/s^(1/n)] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_n" type="',class(obj.rheology_n),'" default="',convert2str(obj.rheology_n),'">','     <section name="materials" />','     <help> Glens flow law exponent </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_law" type="',class(obj.rheology_law),'" default="',convert2str(obj.rheology_law),'">','     <section name="materials" />','     <help> law for the temperature dependance of the rheology: "None", "Paterson",  "Arrhenius" or "LliboutryDuval" </help>','</parameter>');
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_shear_modulus" type="',class(obj.lithosphere_shear_modulus),'" default="',convert2str(obj.lithosphere_shear_modulus),'">','     <section name="materials" />','     <help> Lithosphere shear modulus [Pa] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_density" type="',class(obj.lithosphere_density),'" default="',convert2str(obj.lithosphere_density),'">','     <section name="materials" />','     <help> Lithosphere density [g/cm^-3] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_shear_modulus" type="',class(obj.mantle_shear_modulus),'" default="',convert2str(obj.mantle_shear_modulus),'">','     <section name="materials" />','     <help> Mantle shear modulus [Pa] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_density" type="',class(obj.mantle_density),'" default="',convert2str(obj.mantle_density),'">','     <section name="materials" />','     <help> Mantle density [g/cm^-3] </help>','</parameter>');
+
+
+		end % }}}
 		function obj = matdamageice(varargin) % {{{
 			switch nargin
@@ -174,5 +174,5 @@
 			WriteData(fid,'enum',MaterialsEnum(),'data',MatdamageiceEnum(),'format','Integer');
 			WriteData(fid,'object',obj,'class','materials','fieldname','rho_ice','format','Double');
-			WriteData(fid,'object',obj,'class','materials','fieldname','rho_water','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','rho_water','enum',MaterialsRhoSeawaterEnum(),'format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','rho_freshwater','format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','mu_water','format','Double');
Index: /issm/trunk/src/m/classes/matdamageice.py
===================================================================
--- /issm/trunk/src/m/classes/matdamageice.py	(revision 17988)
+++ /issm/trunk/src/m/classes/matdamageice.py	(revision 17989)
@@ -1,4 +1,4 @@
 from fielddisplay import fielddisplay
-from EnumDefinitions import MaterialsEnum, MatdamageiceEnum, MaterialsRheologyLawEnum
+from EnumDefinitions import MaterialsEnum, MatdamageiceEnum, MaterialsRheologyLawEnum, MaterialsRhoSeawaterEnum
 from StringToEnum import StringToEnum
 from checkfield import checkfield
@@ -129,5 +129,5 @@
 		WriteData(fid,'enum',MaterialsEnum(),'data',MatdamageiceEnum(),'format','Integer');
 		WriteData(fid,'object',self,'class','materials','fieldname','rho_ice','format','Double')
-		WriteData(fid,'object',self,'class','materials','fieldname','rho_water','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','rho_water','enum',MaterialsRhoSeawaterEnum(),'format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','rho_freshwater','format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','mu_water','format','Double')
Index: /issm/trunk/src/m/classes/matice.m
===================================================================
--- /issm/trunk/src/m/classes/matice.m	(revision 17988)
+++ /issm/trunk/src/m/classes/matice.m	(revision 17989)
@@ -30,38 +30,45 @@
 	end
 	methods
-        function createxml(obj,fid) % {{{
-            fprintf(fid, '\n\n');
-            fprintf(fid, '<!-- materials -->\n');
-			 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_ice" type="',class(obj.rho_ice),'" default="',convert2str(obj.rho_ice),'">','     <section name="materials" />','     <help> ice density [kg/m^3] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_water" type="',class(obj.rho_water),'" default="',convert2str(obj.rho_water),'">','     <section name="materials" />','     <help> ocean water density [kg/m^3] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_freshwater" type="',class(obj.rho_freshwater),'" default="',convert2str(obj.rho_freshwater),'">','     <section name="materials" />','     <help> fresh water density [kg/m^3] </help>','</parameter>');
-             
-  
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mu_water" type="',class(obj.mu_water),'" default="',convert2str(obj.mu_water),'">','     <section name="materials" />','     <help> water viscosity [N s/m^2] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="heatcapacity" type="',class(obj.heatcapacity),'" default="',convert2str(obj.heatcapacity),'">','     <section name="materials" />','     <help> heat capacity [J/kg/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="latentheat" type="',class(obj.latentheat),'" default="',convert2str(obj.latentheat),'">','     <section name="materials" />','     <help> latent heat of fusion [J/kg] </help>','</parameter>');
-             
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermalconductivity" type="',class(obj.thermalconductivity),'" default="',convert2str(obj.thermalconductivity),'">','     <section name="materials" />','     <help> ice thermal conductivity [W/m/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperateiceconductivity" type="',class(obj.temperateiceconductivity),'" default="',convert2str(obj.temperateiceconductivity),'">','     <section name="materials" />','     <help> temperate ice thermal conductivity [W/m/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="meltingpoint" type="',class(obj.meltingpoint),'" default="',convert2str(obj.meltingpoint),'">','     <section name="materials" />','     <help> melting point of ice at 1atm in K </help>','</parameter>');
-             
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="beta" type="',class(obj.beta),'" default="',convert2str(obj.beta),'">','     <section name="materials" />','     <help> rate of change of melting point with pressure [K/Pa] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mixed_layer_capacity" type="',class(obj.mixed_layer_capacity),'" default="',convert2str(obj.mixed_layer_capacity),'">','     <section name="materials" />','     <help> mixed layer capacity [W/kg/K] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermal_exchange_velocity" type="',class(obj.thermal_exchange_velocity),'" default="',convert2str(obj.thermal_exchange_velocity),'">','     <section name="materials" />','     <help> thermal exchange velocity [m/s] </help>','</parameter>');
-             
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_B" type="',class(obj.rheology_B),'" default="',convert2str(obj.rheology_B),'">','     <section name="materials" />','     <help> flow law parameter [Pa/s^(1/n)] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_n" type="',class(obj.rheology_n),'" default="',convert2str(obj.rheology_n),'">','     <section name="materials" />','     <help> Glens flow law exponent </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_law" type="',class(obj.rheology_law),'" default="',convert2str(obj.rheology_law),'">','     <section name="materials" />','     <help> law for the temperature dependance of the rheology: "None", "Paterson",  "Arrhenius" or "LliboutryDuval" </help>','</parameter>');
-             
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_shear_modulus" type="',class(obj.lithosphere_shear_modulus),'" default="',convert2str(obj.lithosphere_shear_modulus),'">','     <section name="materials" />','     <help> Lithosphere shear modulus [Pa] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_density" type="',class(obj.lithosphere_density),'" default="',convert2str(obj.lithosphere_density),'">','     <section name="materials" />','     <help> Lithosphere density [g/cm^-3] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_shear_modulus" type="',class(obj.mantle_shear_modulus),'" default="',convert2str(obj.mantle_shear_modulus),'">','     <section name="materials" />','     <help> Mantle shear modulus [Pa] </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_density" type="',class(obj.mantle_density),'" default="',convert2str(obj.mantle_density),'">','     <section name="materials" />','     <help> Mantle density [g/cm^-3] </help>','</parameter>');
-        
-         
-        end % }}}
+		function createxml(obj,fid) % {{{
+			fprintf(fid, '\n\n');
+			fprintf(fid, '<!-- materials -->\n');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_ice" type="',class(obj.rho_ice),'" default="',convert2str(obj.rho_ice),'">','     <section name="materials" />','     <help> ice density [kg/m^3] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_water" type="',class(obj.rho_water),'" default="',convert2str(obj.rho_water),'">','     <section name="materials" />','     <help> ocean water density [kg/m^3] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rho_freshwater" type="',class(obj.rho_freshwater),'" default="',convert2str(obj.rho_freshwater),'">','     <section name="materials" />','     <help> fresh water density [kg/m^3] </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mu_water" type="',class(obj.mu_water),'" default="',convert2str(obj.mu_water),'">','     <section name="materials" />','     <help> water viscosity [N s/m^2] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="heatcapacity" type="',class(obj.heatcapacity),'" default="',convert2str(obj.heatcapacity),'">','     <section name="materials" />','     <help> heat capacity [J/kg/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="latentheat" type="',class(obj.latentheat),'" default="',convert2str(obj.latentheat),'">','     <section name="materials" />','     <help> latent heat of fusion [J/kg] </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermalconductivity" type="',class(obj.thermalconductivity),'" default="',convert2str(obj.thermalconductivity),'">','     <section name="materials" />','     <help> ice thermal conductivity [W/m/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="temperateiceconductivity" type="',class(obj.temperateiceconductivity),'" default="',convert2str(obj.temperateiceconductivity),'">','     <section name="materials" />','     <help> temperate ice thermal conductivity [W/m/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="meltingpoint" type="',class(obj.meltingpoint),'" default="',convert2str(obj.meltingpoint),'">','     <section name="materials" />','     <help> melting point of ice at 1atm in K </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="beta" type="',class(obj.beta),'" default="',convert2str(obj.beta),'">','     <section name="materials" />','     <help> rate of change of melting point with pressure [K/Pa] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mixed_layer_capacity" type="',class(obj.mixed_layer_capacity),'" default="',convert2str(obj.mixed_layer_capacity),'">','     <section name="materials" />','     <help> mixed layer capacity [W/kg/K] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="thermal_exchange_velocity" type="',class(obj.thermal_exchange_velocity),'" default="',convert2str(obj.thermal_exchange_velocity),'">','     <section name="materials" />','     <help> thermal exchange velocity [m/s] </help>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_B" type="',class(obj.rheology_B),'" default="',convert2str(obj.rheology_B),'">','     <section name="materials" />','     <help> flow law parameter [Pa/s^(1/n)] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="rheology_n" type="',class(obj.rheology_n),'" default="',convert2str(obj.rheology_n),'">','     <section name="materials" />','     <help> Glens flow law exponent </help>','</parameter>');
+
+			% rheology_law drop-down
+			fprintf(fid,'%s\n%s\n%s\n%s\n','<parameter key ="rheology_law" type="alternative" optional="false">','     <section name="materials" />','     <help> law for the temperature dependance of the rheology: "None", "Paterson",  "Arrhenius" or "LliboutryDuval" </help>');
+			fprintf(fid,'%s\n','       <option value="None" type="string" default="true"> </option>');
+			fprintf(fid,'%s\n','       <option value="Paterson" type="string" default="false"> </option>');
+			fprintf(fid,'%s\n','       <option value="Arrhenius" type="string" default="false"> </option>');
+			fprintf(fid,'%s\n%s\n','       <option value="LliboutryDuval" type="string" default="false"> </option>','</parameter>');
+
+
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_shear_modulus" type="',class(obj.lithosphere_shear_modulus),'" default="',convert2str(obj.lithosphere_shear_modulus),'">','     <section name="materials" />','     <help> Lithosphere shear modulus [Pa] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="lithosphere_density" type="',class(obj.lithosphere_density),'" default="',convert2str(obj.lithosphere_density),'">','     <section name="materials" />','     <help> Lithosphere density [g/cm^-3] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_shear_modulus" type="',class(obj.mantle_shear_modulus),'" default="',convert2str(obj.mantle_shear_modulus),'">','     <section name="materials" />','     <help> Mantle shear modulus [Pa] </help>','</parameter>');
+			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','<parameter key ="mantle_density" type="',class(obj.mantle_density),'" default="',convert2str(obj.mantle_density),'">','     <section name="materials" />','     <help> Mantle density [g/cm^-3] </help>','</parameter>');
+
+
+		end % }}}
 		function obj = matice(varargin) % {{{
 			switch nargin
@@ -174,5 +181,5 @@
 			WriteData(fid,'enum',MaterialsEnum(),'data',MaticeEnum(),'format','Integer');
 			WriteData(fid,'object',obj,'class','materials','fieldname','rho_ice','format','Double');
-			WriteData(fid,'object',obj,'class','materials','fieldname','rho_water','format','Double');
+			WriteData(fid,'object',obj,'class','materials','fieldname','rho_water','enum',MaterialsRhoSeawaterEnum(),'format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','rho_freshwater','format','Double');
 			WriteData(fid,'object',obj,'class','materials','fieldname','mu_water','format','Double');
Index: /issm/trunk/src/m/classes/matice.py
===================================================================
--- /issm/trunk/src/m/classes/matice.py	(revision 17988)
+++ /issm/trunk/src/m/classes/matice.py	(revision 17989)
@@ -129,5 +129,5 @@
 		WriteData(fid,'enum',MaterialsEnum(),'data',MaticeEnum(),'format','Integer');
 		WriteData(fid,'object',self,'class','materials','fieldname','rho_ice','format','Double')
-		WriteData(fid,'object',self,'class','materials','fieldname','rho_water','format','Double')
+		WriteData(fid,'object',self,'class','materials','fieldname','rho_water','enum',MaterialsRhoSeawaterEnum(),'format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','rho_freshwater','format','Double')
 		WriteData(fid,'object',self,'class','materials','fieldname','mu_water','format','Double')
Index: /issm/trunk/src/m/classes/mesh2d.m
===================================================================
--- /issm/trunk/src/m/classes/mesh2d.m	(revision 17988)
+++ /issm/trunk/src/m/classes/mesh2d.m	(revision 17989)
@@ -105,56 +105,19 @@
 		end % }}}
         function createxml(obj,fid) % {{{
-            fprintf(fid, '<!-- mesh -->\n');
+            fprintf(fid, '<!-- 2D tria Mesh (horizontal) -->\n');
             
-            % drop-down 
-            fprintf(fid,'%s%s%s%s%s\n%s\n','<parameter key ="Dimension" type="','alternative','" optional="','false','">','     <section name="mesh" />');
-            
-                % dimension=0
-                fprintf(fid,'%s%s%s%s%s\n%s\n','     <option value="0" type="','string','" default="','true','">','        <help> dimension is 0 </help>');
-                % footer for dim=0
-                fprintf(fid,'%s\n%s\n','     </option>');
-
-                % dimension=3
-                fprintf(fid,'%s%s%s\n%s\n','     <option value="3" type="','string','">','        <help> dimension is 3 </help>');
-
-                    fprintf(fid,'       <!-- Elements and vertices of the original 2d mesh -->\n');
-                    %fprintf(fid,'%s\n%s\n%s\n','       <frame key="dim=3" label="Elements and vertices of the original 2d mesh">','       <section name="mesh" />');
-                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="x2d" type="',class(obj.x2d),'" default="',convert2str(obj.x2d),'">','              <help> vertices x coordinate [m] </help>','          </parameter>');
-                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="y2d" type="',class(obj.y2d),'" default="',convert2str(obj.y2d),'">','              <help> vertices y coordinate [m] </help>','          </parameter>');
-                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements2d" type="',class(obj.elements2d),'" default="',convert2str(obj.elements2d),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
-                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices2d" type="',class(obj.numberofvertices2d),'" default="',convert2str(obj.numberofvertices2d),'">','              <help> number of vertices </help>','          </parameter>');
-                    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements2d" type="',class(obj.numberofelements2d),'" default="',convert2str(obj.numberofelements2d),'">','              <help> number of elements </help>','          </parameter>');
-                    %fprintf(fid,'%s\n%s\n','       </frame>');
-                % footer for dim=3
-                fprintf(fid,'%s\n%s\n','     </option>');   
-            
-            % footer for drop-down
-            fprintf(fid,'%s\n%s\n%s','     <help> select a mesh dimension 0(default) or 3 </help>','</parameter>');
-            
-                    
-            % elements and vertices
-            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Elements and vertices">','<section name="mesh" />');                    
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofelements" type="',class(obj.numberofelements),'" default="',convert2str(obj.numberofelements),'">','     <section name="mesh" />','     <help> number of elements </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofvertices" type="',class(obj.numberofvertices),'" default="',convert2str(obj.numberofvertices),'">','     <section name="mesh" />','     <help> number of verticies </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elements" type="',class(obj.elements),'" default="',convert2str(obj.elements),'">','     <section name="mesh" />','     <help> vertex indices of the mesh elements </help>','  </parameter>');
+            %elements and vertices
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Elements and vertices">','<section name="mesh" />');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="numberofelements" type="',class(obj.numberofelements),'" default="',convert2str(obj.numberofelements),'">','     <section name="mesh" />','     <help> number of elements </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="numberofvertices" type="',class(obj.numberofvertices),'" default="',convert2str(obj.numberofvertices),'">','     <section name="mesh" />','     <help> number of vertices </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="elements" type="',class(obj.elements),'" default="',convert2str(obj.elements),'">','     <section name="mesh" />','     <help> vertex indices of the mesh elements </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x" type="',class(obj.x),'" default="',convert2str(obj.x),'">','     <section name="mesh" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
-		    fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="z" type="',class(obj.z),'" default="',convert2str(obj.z),'">','     <section name="mesh" />','     <help> vertices z coordinate [m] </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="edges" type="',class(obj.edges),'" default="',convert2str(obj.edges),'">','     <section name="mesh" />','     <help> edges of the 2d mesh (vertex1 vertex2 element1 element2) </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofedges" type="',class(obj.numberofedges),'" default="',convert2str(obj.numberofedges),'">','     <section name="mesh" />','     <help> number of edges of the 2d mesh </help>','  </parameter>');
             fprintf(fid,'%s\n%s\n','</frame>');
-            
+     
             % properties
             fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Properties">','<section name="mesh" />');             
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="selected dimension" type="',class(obj.dimension),'" default="',convert2str(obj.dimension),'">','     <section name="mesh" />','     <help> mesh dimension </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberoflayers" type="',class(obj.numberoflayers),'" default="',convert2str(obj.numberoflayers),'">','     <section name="mesh" />','     <help> number of extrusion layers </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonbed" type="',class(obj.vertexonbed),'" default="',convert2str(obj.vertexonbed),'">','     <section name="mesh" />','     <help> lower vertices flags list </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementonbed" type="',class(obj.elementonbed),'" default="',convert2str(obj.elementonbed),'">','     <section name="mesh" />','     <help> lower elements flags list </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonsurface" type="',class(obj.vertexonsurface),'" default="',convert2str(obj.vertexonsurface),'">','     <section name="mesh" />','     <help> upper vertices flags list </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementonsurface" type="',class(obj.elementonsurface),'" default="',convert2str(obj.elementonsurface),'">','     <section name="mesh" />','     <help> upper element flag list </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="uppervertex" type="',class(obj.uppervertex),'" default="',convert2str(obj.uppervertex),'">','     <section name="mesh" />','     <help> upper vertex list (NaN for vertex on the upper surface) </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="upperelements" type="',class(obj.upperelements),'" default="',convert2str(obj.upperelements),'">','     <section name="mesh" />','     <help> upper element list (NaN for element on the upper layer) </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowervertex" type="',class(obj.lowervertex),'" default="',convert2str(obj.lowervertex),'">','     <section name="mesh" />','     <help> lower vertex list (NaN for vertex on the lower surface) </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowerelements" type="',class(obj.lowerelements),'" default="',convert2str(obj.lowerelements),'">','     <section name="mesh" />','     <help> lower element list (NaN for element on the lower layer </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonboundary" type="',class(obj.vertexonboundary),'" default="',convert2str(obj.vertexonboundary),'">','     <section name="mesh" />','     <help> vertices on the boundary of the domain flag list </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="segments" type="',class(obj.segments),'" default="',convert2str(obj.segments),'">','     <section name="mesh" />','     <help> edges on domain boundary (vertex1 vertex2 element) </help>','  </parameter>');
@@ -175,5 +138,9 @@
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lat" type="',class(obj.lat),'" default="',convert2str(obj.lat),'">','     <section name="mesh" />','     <help> vertices latitude [degrees] </help>','  </parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="long" type="',class(obj.long),'" default="',convert2str(obj.long),'">','     <section name="mesh" />','     <help> verticies longitude [degrees] </help>','  </parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="hemisphere" type="',class(obj.hemisphere),'" default="',convert2str(obj.hemisphere),'">','     <section name="mesh" />','     <help> Indicate hemisphere ''n'' or ''s'' </help>','  </parameter>');
+            % choice (hemisphere) 'n' or 's'
+            fprintf(fid,'%s\n%s\n%s\n','  <parameter key ="hemisphere" type="alternative" optional="false">','     <section name="mesh" />','     <help> Indicate hemisphere ''n'' or ''s'' </help>');
+            fprintf(fid,'%s\n','       <option value="n" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="s" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n','  </parameter>');
             fprintf(fid,'%s\n%s\n','</frame>');
         
@@ -190,4 +157,5 @@
 			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices','format','Integer');
 			WriteData(fid,'object',obj,'class','mesh','fieldname','average_vertex_connectivity','format','Integer');
+			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonboundary','format','DoubleMat','mattype',1);
 		end % }}}
 		function t = domaintype(obj) % {{{
Index: /issm/trunk/src/m/classes/mesh2dvertical.m
===================================================================
--- /issm/trunk/src/m/classes/mesh2dvertical.m	(revision 17988)
+++ /issm/trunk/src/m/classes/mesh2dvertical.m	(revision 17989)
@@ -29,4 +29,37 @@
 	end
 	methods
+                function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- 2d Mesh (Vertical) -->\n');
+            
+            %elements and vertices
+            fprintf(fid,'%s\n%s\n%s\n','       <frame key="1" label="Elements and vertices">','       <section name="mesh" />');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements" type="',class(obj.numberofelements),'" default="',convert2str(obj.numberofelements),'">','              <help> number of elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices" type="',class(obj.numberofvertices),'" default="',convert2str(obj.numberofvertices),'">','              <help> number of vertices </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements" type="',class(obj.elements),'" default="',convert2str(obj.elements),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x" type="',class(obj.x),'" default="',convert2str(obj.x),'">','     <section name="mesh" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="edges" type="',class(obj.edges),'" default="',convert2str(obj.edges),'">','     <section name="mesh" />','     <help> edges of the 2d mesh (vertex1 vertex2 element1 element2) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberofedges" type="',class(obj.numberofedges),'" default="',convert2str(obj.numberofedges),'">','     <section name="mesh" />','     <help> number of edges of the 2d mesh </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','       </frame>');
+     
+            % properties
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Properties">','<section name="mesh" />');             
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonboundary" type="',class(obj.vertexonboundary),'" default="',convert2str(obj.vertexonboundary),'">','     <section name="mesh" />','     <help> vertices on the boundary of the domain flag list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonbase" type="',class(obj.vertexonbase),'" default="',convert2str(obj.vertexonbase),'">','     <section name="mesh" />','     <help> vertices on the bed of the domain flag list </help>','  </parameter>');            
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="segments" type="',class(obj.segments),'" default="',convert2str(obj.segments),'">','     <section name="mesh" />','     <help> edges on domain boundary (vertex1 vertex2 element) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="segmentmarkers" type="',class(obj.segmentmarkers),'" default="',convert2str(obj.segmentmarkers),'">','     <section name="mesh" />','     <help> number associated to each segment </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexconnectivity" type="',class(obj.vertexconnectivity),'" default="',convert2str(obj.vertexconnectivity),'">','     <section name="mesh" />','     <help> list of vertices connected to vertex_i </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementconnectivity" type="',class(obj.elementconnectivity),'" default="',convert2str(obj.elementconnectivity),'">','     <section name="mesh" />','     <help> list of vertices connected to element_i </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="average_vertex_connectivity" type="',class(obj.average_vertex_connectivity),'" default="',convert2str(obj.average_vertex_connectivity),'">','     <section name="mesh" />','     <help> average number of vertices connected to one vertex </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+
+            %projection
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Projection">','<section name="mesh" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lat" type="',class(obj.lat),'" default="',convert2str(obj.lat),'">','     <section name="mesh" />','     <help> vertices latitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="long" type="',class(obj.long),'" default="',convert2str(obj.long),'">','     <section name="mesh" />','     <help> verticies longitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="hemisphere" type="',class(obj.hemisphere),'" default="',convert2str(obj.hemisphere),'">','     <section name="mesh" />','     <help> Indicate hemisphere ''n'' or ''s'' </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        
+        end % }}}
 		function obj = mesh2dvertical(varargin) % {{{
 			switch nargin
Index: /issm/trunk/src/m/classes/mesh3dprisms.m
===================================================================
--- /issm/trunk/src/m/classes/mesh3dprisms.m	(revision 17988)
+++ /issm/trunk/src/m/classes/mesh3dprisms.m	(revision 17989)
@@ -42,4 +42,57 @@
 	end
 	methods
+           function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- 3D prism Mesh -->\n');
+            
+            % Elements and verticies of the original 2d mesh
+            fprintf(fid,'%s\n%s\n%s\n','       <frame key="1" label="Elements and vertices of the orginal 2d mesh">','       <section name="mesh3dprisms" />');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements2d" type="',class(obj.numberofelements2d),'" default="',convert2str(obj.numberofelements2d),'">','              <help> number of elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices2d" type="',class(obj.numberofvertices2d),'" default="',convert2str(obj.numberofvertices2d),'">','              <help> number of vertices </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements2d" type="',class(obj.elements2d),'" default="',convert2str(obj.elements2d),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x2d" type="',class(obj.x2d),'" default="',convert2str(obj.x2d),'">','     <section name="mesh3dprisms" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y2d" type="',class(obj.y2d),'" default="',convert2str(obj.y2d),'">','     <section name="mesh3dprisms" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','       </frame>');
+            
+            % Elements and vertices of the extruded 3d mesh
+            fprintf(fid,'%s\n%s\n%s\n','       <frame key="2" label="Elements and vertices of the orginal 3d mesh">','       <section name="mesh3dprisms" />');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements" type="',class(obj.numberofelements),'" default="',convert2str(obj.numberofelements),'">','              <help> number of elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices" type="',class(obj.numberofvertices),'" default="',convert2str(obj.numberofvertices),'">','              <help> number of vertices </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements" type="',class(obj.elements),'" default="',convert2str(obj.elements),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x" type="',class(obj.x),'" default="',convert2str(obj.x),'">','     <section name="mesh3dprisms" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh3dprisms" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="z" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh3dprisms" />','     <help> vertices z coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','       </frame>');
+     
+            % properties
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Properties">','<section name="mesh3dprisms" />');             
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberoflayers" type="',class(obj.numberoflayers),'" default="',convert2str(obj.numberoflayers),'">','     <section name="mesh3dprisms" />','     <help> number of extrusion layers </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonbase" type="',class(obj.vertexonbase),'" default="',convert2str(obj.vertexonbase),'">','     <section name="mesh3dprisms" />','     <help> lower vertices flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementontbase" type="',class(obj.elementontbase),'" default="',convert2str(obj.elementontbase),'">','     <section name="mesh3dprisms" />','     <help> lower elements flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonsurface" type="',class(obj.vertexonsurface),'" default="',convert2str(obj.vertexonsurface),'">','     <section name="mesh3dprisms" />','     <help> upper vertices flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementontsurface" type="',class(obj.elementontsurface),'" default="',convert2str(obj.elementontsurface),'">','     <section name="mesh3dprisms" />','     <help> upper elements flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="uppervertex" type="',class(obj.uppervertex),'" default="',convert2str(obj.uppervertex),'">','     <section name="mesh3dprisms" />','     <help> upper vertex list (NaN for vertex on the upper surface) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="upperelements" type="',class(obj.upperelements),'" default="',convert2str(obj.upperelements),'">','     <section name="mesh3dprisms" />','     <help> upper element list (NaN for element on the upper layer) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowervertex" type="',class(obj.lowervertex),'" default="',convert2str(obj.lowervertex),'">','     <section name="mesh3dprisms" />','     <help> lower vertex list (NaN for vertex on the lower surface) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowerelements" type="',class(obj.lowerelements),'" default="',convert2str(obj.lowerelements),'">','     <section name="mesh3dprisms" />','     <help> element list (NaN for element on the lower layer) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonboundary" type="',class(obj.vertexonboundary),'" default="',convert2str(obj.vertexonboundary),'">','     <section name="mesh3dprisms" />','     <help> vertices on the boundary of the domain flag list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexconnectivity" type="',class(obj.vertexconnectivity),'" default="',convert2str(obj.vertexconnectivity),'">','     <section name="mesh3dprisms" />','     <help> list of vertices connected to vertex_i </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementconnectivity" type="',class(obj.elementconnectivity),'" default="',convert2str(obj.elementconnectivity),'">','     <section name="mesh3dprisms" />','     <help> average number of vertices connected to one vertex </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="average_vertex_connectivity" type="',class(obj.average_vertex_connectivity),'" default="',convert2str(obj.average_vertex_connectivity),'">','     <section name="mesh3dprisms" />','     <help> average number of vertices connected to one vertex </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % Extracted model
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="4" label="Extracted Model">','<section name="mesh3dprisms" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="extractedvertices" type="',class(obj.extractedvertices),'" default="',convert2str(obj.extractedvertices),'">','     <section name="mesh3dprisms" />','     <help> vertices extracted from the model </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="extractedelements" type="',class(obj.extractedelements),'" default="',convert2str(obj.extractedelements),'">','     <section name="mesh3dprisms" />','     <help> elements extracted from the model </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % Projection
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="5" label="Projection">','<section name="mesh3dprisms" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lat" type="',class(obj.lat),'" default="',convert2str(obj.lat),'">','     <section name="mesh3dprisms" />','     <help> vertices latitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="long" type="',class(obj.long),'" default="',convert2str(obj.long),'">','     <section name="mesh3dprisms" />','     <help> verticies longitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="hemisphere" type="',class(obj.hemisphere),'" default="',convert2str(obj.hemisphere),'">','     <section name="mesh3dprisms" />','     <help> Indicate hemisphere ''n'' or ''s'' </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        
+        end % }}}cd
 		function self = mesh3dprisms(varargin) % {{{
 			switch nargin
@@ -83,6 +136,4 @@
 			md = checkfield(md,'fieldname','mesh.numberofvertices','>',0);
 			%no checks for numberofedges lat long and hemisphere
-			md = checkfield(md,'fieldname','mesh.elementonbase','size',[md.mesh.numberofelements 1],'values',[0 1]);
-			md = checkfield(md,'fieldname','mesh.elementonsurface','size',[md.mesh.numberofelements 1],'values',[0 1]);
 			md = checkfield(md,'fieldname','mesh.vertexonbase','size',[md.mesh.numberofvertices 1],'values',[0 1]);
 			md = checkfield(md,'fieldname','mesh.vertexonsurface','size',[md.mesh.numberofvertices 1],'values',[0 1]);
@@ -145,6 +196,4 @@
 			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofelements','format','Integer');
 			WriteData(fid,'object',obj,'class','mesh','fieldname','numberofvertices','format','Integer');
-			WriteData(fid,'object',obj,'class','mesh','fieldname','elementonbase','format','BooleanMat','mattype',2);
-			WriteData(fid,'object',obj,'class','mesh','fieldname','elementonsurface','format','BooleanMat','mattype',2);
 			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonbase','format','BooleanMat','mattype',1);
 			WriteData(fid,'object',obj,'class','mesh','fieldname','vertexonsurface','format','BooleanMat','mattype',1);
Index: /issm/trunk/src/m/classes/mesh3dprisms.py
===================================================================
--- /issm/trunk/src/m/classes/mesh3dprisms.py	(revision 17988)
+++ /issm/trunk/src/m/classes/mesh3dprisms.py	(revision 17989)
@@ -121,6 +121,4 @@
 		md = checkfield(md,'fieldname','mesh.numberofvertices','>',0)
 		#no checks for numberofedges lat long and hemisphere
-		md = checkfield(md,'fieldname','mesh.elementonbase','size',[md.mesh.numberofelements],'values',[0,1])
-		md = checkfield(md,'fieldname','mesh.elementonsurface','size',[md.mesh.numberofelements],'values',[0,1])
 		md = checkfield(md,'fieldname','mesh.vertexonbase','size',[md.mesh.numberofvertices],'values',[0,1])
 		md = checkfield(md,'fieldname','mesh.vertexonsurface','size',[md.mesh.numberofvertices],'values',[0,1])
@@ -149,6 +147,4 @@
 		WriteData(fid,'object',self,'class','mesh','fieldname','numberofelements','format','Integer')
 		WriteData(fid,'object',self,'class','mesh','fieldname','numberofvertices','format','Integer')
-		WriteData(fid,'object',self,'class','mesh','fieldname','elementonbase','format','BooleanMat','mattype',2)
-		WriteData(fid,'object',self,'class','mesh','fieldname','elementonsurface','format','BooleanMat','mattype',2)
 		WriteData(fid,'object',self,'class','mesh','fieldname','vertexonbase','format','BooleanMat','mattype',1)
 		WriteData(fid,'object',self,'class','mesh','fieldname','vertexonsurface','format','BooleanMat','mattype',1)
Index: /issm/trunk/src/m/classes/mesh3dtetras.m
===================================================================
--- /issm/trunk/src/m/classes/mesh3dtetras.m	(revision 17988)
+++ /issm/trunk/src/m/classes/mesh3dtetras.m	(revision 17989)
@@ -40,4 +40,57 @@
 	end
 	methods
+        function createxml(obj,fid) % {{{
+            fprintf(fid, '<!-- 3D Tetra Mesh -->\n');
+            
+            % Elements and verticies of the original 2d mesh
+            fprintf(fid,'%s\n%s\n%s\n','       <frame key="1" label="Elements and vertices of the orginal 2d mesh">','       <section name="mesh3dprisms" />');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements2d" type="',class(obj.numberofelements2d),'" default="',convert2str(obj.numberofelements2d),'">','              <help> number of elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices2d" type="',class(obj.numberofvertices2d),'" default="',convert2str(obj.numberofvertices2d),'">','              <help> number of vertices </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements2d" type="',class(obj.elements2d),'" default="',convert2str(obj.elements2d),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x2d" type="',class(obj.x2d),'" default="',convert2str(obj.x2d),'">','     <section name="mesh3dprisms" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y2d" type="',class(obj.y2d),'" default="',convert2str(obj.y2d),'">','     <section name="mesh3dprisms" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','       </frame>');
+            
+            % Elements and vertices of the extruded 3d mesh
+            fprintf(fid,'%s\n%s\n%s\n','       <frame key="2" label="Elements and vertices of the orginal 3d mesh">','       <section name="mesh3dprisms" />');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofelements" type="',class(obj.numberofelements),'" default="',convert2str(obj.numberofelements),'">','              <help> number of elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="numberofvertices" type="',class(obj.numberofvertices),'" default="',convert2str(obj.numberofvertices),'">','              <help> number of vertices </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','          <parameter key ="elements" type="',class(obj.elements),'" default="',convert2str(obj.elements),'">','              <help> vertex indices of the mesh elements </help>','          </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="x" type="',class(obj.x),'" default="',convert2str(obj.x),'">','     <section name="mesh3dprisms" />','     <help> vertices x coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="y" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh3dprisms" />','     <help> vertices y coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="z" type="',class(obj.y),'" default="',convert2str(obj.y),'">','     <section name="mesh3dprisms" />','     <help> vertices z coordinate [m] </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','       </frame>');
+     
+            % properties
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Properties">','<section name="mesh3dprisms" />');             
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="numberoflayers" type="',class(obj.numberoflayers),'" default="',convert2str(obj.numberoflayers),'">','     <section name="mesh3dprisms" />','     <help> number of extrusion layers </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonbase" type="',class(obj.vertexonbase),'" default="',convert2str(obj.vertexonbase),'">','     <section name="mesh3dprisms" />','     <help> lower vertices flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementontbase" type="',class(obj.elementontbase),'" default="',convert2str(obj.elementontbase),'">','     <section name="mesh3dprisms" />','     <help> lower elements flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonsurface" type="',class(obj.vertexonsurface),'" default="',convert2str(obj.vertexonsurface),'">','     <section name="mesh3dprisms" />','     <help> upper vertices flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementontsurface" type="',class(obj.elementontsurface),'" default="',convert2str(obj.elementontsurface),'">','     <section name="mesh3dprisms" />','     <help> upper elements flags list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="uppervertex" type="',class(obj.uppervertex),'" default="',convert2str(obj.uppervertex),'">','     <section name="mesh3dprisms" />','     <help> upper vertex list (NaN for vertex on the upper surface) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="upperelements" type="',class(obj.upperelements),'" default="',convert2str(obj.upperelements),'">','     <section name="mesh3dprisms" />','     <help> upper element list (NaN for element on the upper layer) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowervertex" type="',class(obj.lowervertex),'" default="',convert2str(obj.lowervertex),'">','     <section name="mesh3dprisms" />','     <help> lower vertex list (NaN for vertex on the lower surface) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lowerelements" type="',class(obj.lowerelements),'" default="',convert2str(obj.lowerelements),'">','     <section name="mesh3dprisms" />','     <help> element list (NaN for element on the lower layer) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexonboundary" type="',class(obj.vertexonboundary),'" default="',convert2str(obj.vertexonboundary),'">','     <section name="mesh3dprisms" />','     <help> vertices on the boundary of the domain flag list </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="vertexconnectivity" type="',class(obj.vertexconnectivity),'" default="',convert2str(obj.vertexconnectivity),'">','     <section name="mesh3dprisms" />','     <help> list of vertices connected to vertex_i </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="elementconnectivity" type="',class(obj.elementconnectivity),'" default="',convert2str(obj.elementconnectivity),'">','     <section name="mesh3dprisms" />','     <help> average number of vertices connected to one vertex </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="average_vertex_connectivity" type="',class(obj.average_vertex_connectivity),'" default="',convert2str(obj.average_vertex_connectivity),'">','     <section name="mesh3dprisms" />','     <help> average number of vertices connected to one vertex </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % Extracted model
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="4" label="Extracted Model">','<section name="mesh3dprisms" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="extractedvertices" type="',class(obj.extractedvertices),'" default="',convert2str(obj.extractedvertices),'">','     <section name="mesh3dprisms" />','     <help> vertices extracted from the model </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="extractedelements" type="',class(obj.extractedelements),'" default="',convert2str(obj.extractedelements),'">','     <section name="mesh3dprisms" />','     <help> elements extracted from the model </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+            
+            % Projection
+            fprintf(fid,'%s\n%s\n%s\n','<frame key="5" label="Projection">','<section name="mesh3dprisms" />'); 
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="lat" type="',class(obj.lat),'" default="',convert2str(obj.lat),'">','     <section name="mesh3dprisms" />','     <help> vertices latitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="long" type="',class(obj.long),'" default="',convert2str(obj.long),'">','     <section name="mesh3dprisms" />','     <help> verticies longitude [degrees] </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n','  <parameter key ="hemisphere" type="',class(obj.hemisphere),'" default="',convert2str(obj.hemisphere),'">','     <section name="mesh3dprisms" />','     <help> Indicate hemisphere ''n'' or ''s'' </help>','  </parameter>');
+            fprintf(fid,'%s\n%s\n','</frame>');
+        
+        end % }}}cd
 		function self = mesh3dtetras(varargin) % {{{
 			switch nargin
Index: /issm/trunk/src/m/classes/model.m
===================================================================
--- /issm/trunk/src/m/classes/model.m	(revision 17988)
+++ /issm/trunk/src/m/classes/model.m	(revision 17989)
@@ -216,5 +216,7 @@
 			
 			%damage: 
-			md.damage.D=DepthAverage(md,md.damage.D);
+			if md.damage.isdamage,
+				md.damage.D=DepthAverage(md,md.damage.D);
+			end
 
 			%special for thermal modeling:
@@ -234,6 +236,4 @@
 			md.geometry.base=project2d(md,md.geometry.base,1);
 			md.geometry.bed=project2d(md,md.geometry.bed,1);
-			md.mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1);
-			md.mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1);
 			md.mask.groundedice_levelset=project2d(md,md.mask.groundedice_levelset,1);
 			md.mask.ice_levelset=project2d(md,md.mask.ice_levelset,1);
@@ -247,23 +247,10 @@
 			mesh.x=md.mesh.x2d;
 			mesh.y=md.mesh.y2d;
-			mesh.z=zeros(size(md.mesh.x2d));
 			mesh.numberofvertices=md.mesh.numberofvertices2d;
 			mesh.numberofelements=md.mesh.numberofelements2d;
 			mesh.elements=md.mesh.elements2d;
+			mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1);
+			mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1);
 			md.mesh=mesh;
-
-			%Keep a trace of lower and upper nodes
-			md.mesh.lowervertex=NaN;
-			md.mesh.uppervertex=NaN;
-			md.mesh.lowerelements=NaN;
-			md.mesh.upperelements=NaN;
-
-			%Remove old mesh 
-			md.mesh.x2d=NaN;
-			md.mesh.y2d=NaN;
-			md.mesh.elements2d=NaN;
-			md.mesh.numberofelements2d=md.mesh.numberofelements;
-			md.mesh.numberofvertices2d=md.mesh.numberofvertices;
-			md.mesh.numberoflayers=0;
 
 		end % }}}
@@ -1030,5 +1017,5 @@
 			if isfield(structmd,'groundingline_migration') & isnumeric(structmd.groundingline_migration),
 				if (structmd.groundingline_migration==272), md.groundingline.migration='None';      end
-				if (structmd.groundingline_migration==273), md.groundingline.migration='AgressiveMigration';  end
+				if (structmd.groundingline_migration==273), md.groundingline.migration='AggressiveMigration';  end
 				if (structmd.groundingline_migration==274), md.groundingline.migration='SoftMigration'; end
 			end
Index: /issm/trunk/src/m/classes/model.py
===================================================================
--- /issm/trunk/src/m/classes/model.py	(revision 17988)
+++ /issm/trunk/src/m/classes/model.py	(revision 17989)
@@ -268,20 +268,20 @@
 						#size = number of nodes * n
 						if   fieldsize[0]==numberofvertices1:
-							setattr(getattr(md2,fieldi),fieldj,field[pos_node,:])
+							setattr(getattr(md2,fieldi),fieldj,field[pos_node])
 						elif fieldsize[0]==numberofvertices1+1:
-							setattr(getattr(md2,fieldi),fieldj,numpy.vstack((field[pos_node,:],field[-1,:])))
+							setattr(getattr(md2,fieldi),fieldj,numpy.vstack((field[pos_node],field[-1,:])))
 						#size = number of elements * n
 						elif fieldsize[0]==numberofelements1:
-							setattr(getattr(md2,fieldi),fieldj,field[pos_elem,:])
+							setattr(getattr(md2,fieldi),fieldj,field[pos_elem])
 			else:
 				if len(fieldsize):
 					#size = number of nodes * n
 					if   fieldsize[0]==numberofvertices1:
-						setattr(md2,fieldi,field[pos_node,:])
+						setattr(md2,fieldi,field[pos_node])
 					elif fieldsize[0]==numberofvertices1+1:
-						setattr(md2,fieldi,numpy.hstack((field[pos_node,:],field[-1,:])))
+						setattr(md2,fieldi,numpy.hstack((field[pos_node],field[-1,:])))
 					#size = number of elements * n
 					elif fieldsize[0]==numberofelements1:
-						setattr(md2,fieldi,field[pos_elem,:])
+						setattr(md2,fieldi,field[pos_elem])
 
 		#modify some specific fields
@@ -772,5 +772,6 @@
 		
 		#damage: 
-		md.damage.D=DepthAverage(md,md.damage.D)
+		if md.damage.isdamage:
+			md.damage.D=DepthAverage(md,md.damage.D)
 
 		#special for thermal modeling:
@@ -790,6 +791,4 @@
 		md.geometry.base=project2d(md,md.geometry.base,1)
 		md.geometry.bed=project2d(md,md.geometry.bed,1)
-		md.mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1)
-		md.mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1)
 		md.mask.groundedice_levelset=project2d(md,md.mask.groundedice_levelset,1)
 		md.mask.ice_levelset=project2d(md,md.mask.ice_levelset,1)
@@ -803,24 +802,11 @@
 		mesh.x=md.mesh.x2d
 		mesh.y=md.mesh.y2d
-		mesh.z=numpy.zeros_like(md.mesh.x2d)
 		mesh.numberofvertices=md.mesh.numberofvertices2d
 		mesh.numberofelements=md.mesh.numberofelements2d
 		mesh.elements=md.mesh.elements2d
+		mesh.vertexonboundary=project2d(md,md.mesh.vertexonboundary,1)
+		mesh.elementconnectivity=project2d(md,md.mesh.elementconnectivity,1)
 		md.mesh=mesh
 
-		#Keep a trace of lower and upper nodes
-		md.mesh.lowervertex=numpy.nan
-		md.mesh.uppervertex=numpy.nan
-		md.mesh.lowerelements=numpy.nan
-		md.mesh.upperelements=numpy.nan
-
-		#Remove old mesh 
-		md.mesh.x2d=numpy.nan
-		md.mesh.y2d=numpy.nan
-		md.mesh.elements2d=numpy.nan
-		md.mesh.numberofelements2d=md.mesh.numberofelements
-		md.mesh.numberofvertices2d=md.mesh.numberofvertices
-		md.mesh.numberoflayers=0
-
 		return md
 
Index: /issm/trunk/src/m/classes/settings.m
===================================================================
--- /issm/trunk/src/m/classes/settings.m	(revision 17988)
+++ /issm/trunk/src/m/classes/settings.m	(revision 17989)
@@ -24,5 +24,10 @@
 			fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="results_on_nodes" type="',      class(obj.results_on_nodes),'" default="',        convert2str(obj.results_on_nodes),'">',	'     <section name="settings" />','     <help> results are output for all the nodes of each element </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="io_gather" type="',          class(obj.io_gather),'" default="',           convert2str(obj.io_gather),'">',     '     <section name="settings" />','     <help> I/O gathering strategy for result outputs (default 1) </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="lowmem" type="',        class(obj.lowmem),'" default="',         convert2str(obj.lowmem),'">',	'     <section name="settings" />','     <help> is the memory limited ? (0 or 1) </help>','</parameter>');
+            
+            % lowmen drop-down (0 or 1)
+            fprintf(fid,'%s\n%s\n%s\n%s\n',	'<parameter key ="lowmem" type="alternative" optional="true">',	'     <section name="settings" />','     <help> is the memory limited ? (0 or 1) </help>');
+            fprintf(fid,'%s\n','       <option value="0" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="1" type="string" default="false"> </option>','</parameter>');
+
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="output_frequency" type="',          class(obj.output_frequency),'" default="',           convert2str(obj.output_frequency),'">',	'     <section name="settings" />','     <help> frequency at which results are saved in all solutions with multiple time_steps </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="waitonlock" type="',  	class(obj.waitonlock),'" default="',      convert2str(obj.waitonlock),'">',     '     <section name="settings" />','     <help> maximum number of minutes to wait for batch results (NaN to deactivate) </help>','</parameter>');
Index: /issm/trunk/src/m/classes/stressbalance.m
===================================================================
--- /issm/trunk/src/m/classes/stressbalance.m	(revision 17988)
+++ /issm/trunk/src/m/classes/stressbalance.m	(revision 17989)
@@ -35,5 +35,11 @@
              fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="reltol" type="',          class(obj.reltol),'" default="',            convert2str(obj.reltol),'">',     '     <section name="stressbalance" />','     <help> velocity relative convergence criterion, NaN: not applied </help>','</parameter>');
              fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',	'<parameter key ="abstol" type="',        class(obj.abstol),'" default="',          convert2str(obj.abstol),'">',	'     <section name="stressbalance" />','     <help> velocity absolute convergence criterion, NaN: not applied </help>','</parameter>');
-             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="isnewton" type="',          class(obj.isnewton),'" default="',            convert2str(obj.isnewton),'">',	'     <section name="stressbalance" />','     <help> 0: Picards fixed point, 1: Newtons method, 2: hybrid </help>','</parameter>');
+             
+             %is newton drop-down (0,1,or 2)
+             fprintf(fid,'%s\n%s\n%s\n%s\n',    '<parameter key ="isnewton" type="alternative" optional="false">',	'     <section name="stressbalance" />','     <help> 0: Picards fixed point, 1: Newtons method, 2: hybrid </help>');
+             fprintf(fid,'%s\n','       <option value="0" type="string" default="true"> </option>');
+             fprintf(fid,'%s\n','       <option value="1" type="string" default="false"> </option>');
+             fprintf(fid,'%s\n%s\n','       <option value="2" type="string" default="false"> </option>','</parameter>');
+    
              fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="maxiter" type="',  	class(obj.maxiter),'" default="',       convert2str(obj.maxiter),'">',     '     <section name="stressbalance" />','     <help> maximum number of nonlinear iterations </help>','</parameter>');
              fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="viscosity_overshoot" type="',         class(obj.viscosity_overshoot),'" default="',           convert2str(obj.viscosity_overshoot),'">',	'     <section name="stressbalance" />','     <help> over-shooting constant new=new+C*(new-old) </help>','</parameter>');
Index: /issm/trunk/src/m/classes/taoinversion.m
===================================================================
--- /issm/trunk/src/m/classes/taoinversion.m	(revision 17988)
+++ /issm/trunk/src/m/classes/taoinversion.m	(revision 17989)
@@ -9,5 +9,12 @@
 		incomplete_adjoint          = 0
 		control_parameters          = NaN
-		nsteps                      = 0
+		maxsteps                    = 0
+		maxiter                     = 0
+		fatol                       = 0
+		frtol                       = 0
+		gatol                       = 0
+		grtol                       = 0
+		gttol                       = 0
+		algorithm                   = ''
 		cost_functions              = NaN
 		cost_functions_coefficients = NaN
@@ -26,21 +33,5 @@
 					obj=setdefaultparameters(obj);
 				case 1
-					if isa(varargin{1},'inversion'),
-						disp('converting inversion to taoinversion');
-						in=varargin{1};
-						obj.iscontrol                   = in.iscontrol;
-						obj.incomplete_adjoint          = in.incomplete_adjoint;
-						obj.control_parameters          = in.control_parameters;
-						obj.nsteps                      = in.nsteps;
-						obj.cost_functions              = in.cost_functions(1,:); %Keep first line only
-						obj.cost_functions_coefficients = in.cost_functions_coefficients;
-						obj.min_parameters              = in.min_parameters;
-						obj.max_parameters              = in.max_parameters;
-						obj.vx_obs                      = in.vx_obs;
-						obj.vy_obs                      = in.vy_obs;
-						obj.vz_obs                      = in.vz_obs;
-						obj.vel_obs                     = in.vel_obs;
-						obj.thickness_obs               = in.thickness_obs;
-					end
+					obj=structtoobj(taoinversion(),varargin{1});
 				otherwise
 					error('constructor not supported');
@@ -56,9 +47,20 @@
 			obj.control_parameters={'FrictionCoefficient'};
 
-			%number of steps in the control methods
-			obj.nsteps=20;
+			%number of iterations and steps
+			obj.maxsteps=20;
+			obj.maxiter =30;
+
+			%default tolerances
+			obj.fatol = 0;
+			obj.frtol = 0;
+			obj.gatol = 0;
+			obj.grtol = 0;
+			obj.gttol = 1e-4;
+
+			%minimization algorithm
+			obj.algorithm = 'tao_blmvm';
 
 			%several responses can be used:
-			obj.cost_functions=101*ones(obj.nsteps,1);
+			obj.cost_functions=101;
 
 		end % }}}
@@ -79,5 +81,12 @@
 			md = checkfield(md,'fieldname','inversion.control_parameters','cell',1,'values',...
 				{'BalancethicknessThickeningRate' 'FrictionCoefficient' 'MaterialsRheologyBbar' 'MaterialsRheologyZbar' 'Vx' 'Vy' 'Thickness'});
-			md = checkfield(md,'fieldname','inversion.nsteps','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.maxsteps','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.maxiter','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.fatol','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.frtol','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.gatol','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.grtol','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.gttol','numel',1,'>=',0);
+			md = checkfield(md,'fieldname','inversion.algorithm','values',{'tao_blmvm','tao_cg','tao_lmvm'});
 			md = checkfield(md,'fieldname','inversion.cost_functions','size',[1 num_costfunc],'values',[101:105 201 501:506]);
 			md = checkfield(md,'fieldname','inversion.cost_functions_coefficients','size',[md.mesh.numberofvertices num_costfunc],'>=',0);
@@ -99,5 +108,12 @@
 			fielddisplay(obj,'incomplete_adjoint','1: linear viscosity, 0: non-linear viscosity');
 			fielddisplay(obj,'control_parameters','ex: {''FrictionCoefficient''}, or {''MaterialsRheologyBbar''}');
-			fielddisplay(obj,'nsteps','number of optimization searches');
+			fielddisplay(obj,'maxsteps','maximum number of iterations (gradient computation)');
+			fielddisplay(obj,'maxiter','maximum number of Function evaluation (forward run)');
+			fielddisplay(obj,'fatol','convergence criterion: f(X)-f(X*) (X: current iteration, X*: "true" solution, f: cost function)');
+			fielddisplay(obj,'frtol','convergence criterion: |f(X)-f(X*)|/|f(X*)|');
+			fielddisplay(obj,'gatol','convergence criterion: ||g(X)|| (g: gradient of the cost function)');
+			fielddisplay(obj,'grtol','convergence criterion: ||g(X)||/|f(X)|');
+			fielddisplay(obj,'gttol','convergence criterion: ||g(X)||/||g(X0)|| (g(X0): gradient at initial guess X0)');
+			fielddisplay(obj,'algorithm','minimization algorithm: ''tao_blmvm'', ''tao_cg'', ''tao_lmvm''');
 			fielddisplay(obj,'cost_functions','indicate the type of response for each optimization step');
 			fielddisplay(obj,'cost_functions_coefficients','cost_functions_coefficients applied to the misfit of each vertex and for each control_parameter');
@@ -124,8 +140,15 @@
 
 			WriteData(fid,'object',obj,'class','inversion','fieldname','iscontrol','format','Boolean');
-			WriteData(fid,'enum',InversionTaoEnum(),'data',true,'format','Boolean');
+			WriteData(fid,'enum',InversionTypeEnum(),'data',1,'format','Integer');
 			if ~obj.iscontrol, return; end
 			WriteData(fid,'object',obj,'class','inversion','fieldname','incomplete_adjoint','format','Boolean');
-			WriteData(fid,'object',obj,'class','inversion','fieldname','nsteps','format','Integer');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','maxsteps','format','Integer');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','maxiter','format','Integer');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','fatol','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','frtol','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','gatol','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','grtol','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','gttol','format','Double');
+			WriteData(fid,'object',obj,'class','inversion','fieldname','algorithm','format','String');
 			WriteData(fid,'object',obj,'class','inversion','fieldname','cost_functions_coefficients','format','DoubleMat','mattype',1);
 			WriteData(fid,'object',obj,'class','inversion','fieldname','min_parameters','format','DoubleMat','mattype',3);
@@ -148,16 +171,16 @@
 			num_cost_functions=size(obj.cost_functions,2);
 			data=obj.cost_functions;
-			pos=find(data==101); data(pos)=SurfaceAbsVelMisfitEnum();
-			pos=find(data==102); data(pos)=SurfaceRelVelMisfitEnum();
-			pos=find(data==103); data(pos)=SurfaceLogVelMisfitEnum();
-			pos=find(data==104); data(pos)=SurfaceLogVxVyMisfitEnum();
-			pos=find(data==105); data(pos)=SurfaceAverageVelMisfitEnum();
-			pos=find(data==201); data(pos)=ThicknessAbsMisfitEnum();
-			pos=find(data==501); data(pos)=DragCoefficientAbsGradientEnum();
-			pos=find(data==502); data(pos)=RheologyBbarAbsGradientEnum();
-			pos=find(data==503); data(pos)=ThicknessAbsGradientEnum();
-			pos=find(data==504); data(pos)=ThicknessAlongGradientEnum();
-			pos=find(data==505); data(pos)=ThicknessAcrossGradientEnum();
-			pos=find(data==506); data(pos)=BalancethicknessMisfitEnum();
+			pos=find(obj.cost_functions==101); data(pos)=SurfaceAbsVelMisfitEnum();
+			pos=find(obj.cost_functions==102); data(pos)=SurfaceRelVelMisfitEnum();
+			pos=find(obj.cost_functions==103); data(pos)=SurfaceLogVelMisfitEnum();
+			pos=find(obj.cost_functions==104); data(pos)=SurfaceLogVxVyMisfitEnum();
+			pos=find(obj.cost_functions==105); data(pos)=SurfaceAverageVelMisfitEnum();
+			pos=find(obj.cost_functions==201); data(pos)=ThicknessAbsMisfitEnum();
+			pos=find(obj.cost_functions==501); data(pos)=DragCoefficientAbsGradientEnum();
+			pos=find(obj.cost_functions==502); data(pos)=RheologyBbarAbsGradientEnum();
+			pos=find(obj.cost_functions==503); data(pos)=ThicknessAbsGradientEnum();
+			pos=find(obj.cost_functions==504); data(pos)=ThicknessAlongGradientEnum();
+			pos=find(obj.cost_functions==505); data(pos)=ThicknessAcrossGradientEnum();
+			pos=find(obj.cost_functions==506); data(pos)=BalancethicknessMisfitEnum();
 			WriteData(fid,'data',data,'enum',InversionCostFunctionsEnum(),'format','DoubleMat','mattype',3);
 			WriteData(fid,'data',num_cost_functions,'enum',InversionNumCostFunctionsEnum(),'format','Integer');
Index: /issm/trunk/src/m/classes/thermal.m
===================================================================
--- /issm/trunk/src/m/classes/thermal.m	(revision 17988)
+++ /issm/trunk/src/m/classes/thermal.m	(revision 17989)
@@ -22,13 +22,19 @@
             % thermal solution parameters
             fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Thermal solution parameters">','<section name="thermal" />');                    
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="spctemperature" type="',class(obj.spctemperature),'" default="',convert2str(obj.spctemperature),'">','     <section name="thermal" />','     <help> temperature constraints (NaN means no constraint) [K] </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_threshold" type="',class(obj.penalty_threshold),'" default="',convert2str(obj.penalty_threshold),'">','     <section name="thermal" />','     <help> 0: no, 1: artificial_diffusivity, 2: SUPG </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="stabilization" type="',class(obj.stabilization),'" default="',convert2str(obj.stabilization),'">','     <section name="thermal" />','     <help> maximum number of non linear iterations </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="maxiter" type="',class(obj.maxiter),'" default="',convert2str(obj.maxiter),'">','     <section name="thermal" />','     <help> stabilize unstable thermal constraints that keep zigzagging after n iteration (default is 0, no stabilization) </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_lock" type="',class(obj.penalty_lock),'" default="',convert2str(obj.penalty_lock),'">','     <section name="thermal" />','     <help> threshold to declare convergence of thermal solution (default is 0)  </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_factor" type="',class(obj.penalty_factor),'" default="',convert2str(obj.penalty_factor),'">','     <section name="thermal" />','     <help> scaling exponent (default is 3) </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isenthalpy" type="',class(obj.isenthalpy),'" default="',convert2str(obj.isenthalpy),'">','     <section name="thermal" />','     <help> use an enthalpy formulation to include temperate ice (default is 0) </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdynamicbasalspc" type="',class(obj.isdynamicbasalspc),'" default="',convert2str(obj.isdynamicbasalspc),'">','     <section name="thermal" />','     <help> enable dynamic setting of basal forcing. required for enthalpy formulation (default is 0)  </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="thermal" />','     <help> additional outputs requested </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="spctemperature" type="',class(obj.spctemperature),'" default="',convert2str(obj.spctemperature),'">','     <section name="thermal" />','     <help> temperature constraints (NaN means no constraint) [K] </help>','  </parameter>');
+                
+            % penalty_threshold drop-down (0, 1, or 2)
+            fprintf(fid,'%s\n%s\n%s\n%s\n','  <parameter key ="penalty_threshold" type="alternative"  optional="false">','     <section name="thermal" />','     <help> 0: no, 1: artificial_diffusivity, 2: SUPG </help>');
+            fprintf(fid,'%s\n','       <option value="0" type="string" default="true"> </option>');
+            fprintf(fid,'%s\n','       <option value="1" type="string" default="false"> </option>');
+            fprintf(fid,'%s\n%s\n','       <option value="2" type="string" default="false"> </option>','</parameter>');
+
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="stabilization" type="',class(obj.stabilization),'" default="',convert2str(obj.stabilization),'">','     <section name="thermal" />','     <help> maximum number of non linear iterations </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="maxiter" type="',class(obj.maxiter),'" default="',convert2str(obj.maxiter),'">','     <section name="thermal" />','     <help> stabilize unstable thermal constraints that keep zigzagging after n iteration (default is 0, no stabilization) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_lock" type="',class(obj.penalty_lock),'" default="',convert2str(obj.penalty_lock),'">','     <section name="thermal" />','     <help> threshold to declare convergence of thermal solution (default is 0)  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="penalty_factor" type="',class(obj.penalty_factor),'" default="',convert2str(obj.penalty_factor),'">','     <section name="thermal" />','     <help> scaling exponent (default is 3) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isenthalpy" type="',class(obj.isenthalpy),'" default="',convert2str(obj.isenthalpy),'">','     <section name="thermal" />','     <help> use an enthalpy formulation to include temperate ice (default is 0) </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdynamicbasalspc" type="',class(obj.isdynamicbasalspc),'" default="',convert2str(obj.isdynamicbasalspc),'">','     <section name="thermal" />','     <help> enable dynamic setting of basal forcing. required for enthalpy formulation (default is 0)  </help>','  </parameter>');
+            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="thermal" />','     <help> additional outputs requested </help>','  </parameter>');
             fprintf(fid,'%s\n%s\n','</frame>');    
         
Index: /issm/trunk/src/m/classes/timestepping.m
===================================================================
--- /issm/trunk/src/m/classes/timestepping.m	(revision 17988)
+++ /issm/trunk/src/m/classes/timestepping.m	(revision 17989)
@@ -19,5 +19,8 @@
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="final_time" type="',            class(obj.final_time),'" default="',                convert2str(obj.final_time),'">',   '     <section name="timestepping" />','     <help> final time to stop the simulation [yr] </help>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="time_step" type="',      class(obj.time_step),'" default="',          convert2str(obj.time_step),'">',            '     <section name="timestepping" />','     <help> length of time steps [yr] </help>','</parameter>');
-            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',        '<parameter key ="time_adapt" type="',     class(obj.time_adapt),'" default="',         convert2str(obj.time_adapt),'">',            '     <section name="timestepping" />','     <help> use cfl condition to define time step ? (0 or 1)  </help>','</parameter>');
+            % time_adapt 0 or 1 drop down
+            fprintf(fid,'%s\n%s\n%s\n%s\n','<parameter key ="time_adapt" type="alternative" optional="false">','     <section name="timestepping" />','     <help> use cfl condition to define time step ? (0 or 1)  </help>');
+            fprintf(fid, '%s\n',   '       <option value="0" type="string" default="true"></option>');
+            fprintf(fid, '%s\n%s\n',   '       <option value="1" type="string" default="false"></option>','</parameter>');
             fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n',    '<parameter key ="cfl_coefficient" type="',       class(obj.cfl_coefficient),'" default="',              convert2str(obj.cfl_coefficient),'">',              '     <section name="timestepping" />','     <help> coefficient applied to cfl condition </help>','</parameter>');
             
Index: /issm/trunk/src/m/classes/transient.m
===================================================================
--- /issm/trunk/src/m/classes/transient.m	(revision 17988)
+++ /issm/trunk/src/m/classes/transient.m	(revision 17989)
@@ -27,5 +27,5 @@
                 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isgroundingline" type="',class(obj.isgroundingline),'" default="',convert2str(obj.isgroundingline),'">','     <section name="transient" />','     <help> indicates whether a groundingline migration is used in the transient </help>','  </parameter>');
                 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isgia" type="',class(obj.isgia),'" default="',convert2str(obj.isgia),'">','     <section name="transient" />','     <help> indicates whether a postglacial rebound model is used in the transient </help>','  </parameter>');
-                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdamage" type="',class(obj.isdamage),'" default="',convert2str(obj.isdamage),'">','     <section name="transient" />','     <help> indicates whether damage evolution is used in the transient </help>','  </parameter>');
+                fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="isdamageevolution" type="',class(obj.isdamageevolution),'" default="',convert2str(obj.isdamageevolution),'">','     <section name="transient" />','     <help> indicates whether damage evolution is used in the transient </help>','  </parameter>');
                 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="islevelset" type="',class(obj.islevelset),'" default="',convert2str(obj.islevelset),'">','     <section name="transient" />','     <help> LEVEL SET DESCRIPTION...  </help>','  </parameter>');
                 fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="requested_outputs" type="',class(obj.requested_outputs),'" default="',convert2str(obj.requested_outputs),'">','     <section name="transient" />','     <help> list of additional outputs requested </help>','  </parameter>');
Index: /issm/trunk/src/m/classes/verbose.py
===================================================================
--- /issm/trunk/src/m/classes/verbose.py	(revision 17988)
+++ /issm/trunk/src/m/classes/verbose.py	(revision 17989)
@@ -50,5 +50,5 @@
 			binary=args[0]
 			if   isinstance(binary,(str,unicode)):
-				if strcmpi(binary,'all'):
+				if binary.lower()=='all':
 					binary=2**11-1    #all ones
 					self.BinaryToVerbose(binary)
Index: /issm/trunk/src/m/consistency/ismodelselfconsistent.m
===================================================================
--- /issm/trunk/src/m/consistency/ismodelselfconsistent.m	(revision 17988)
+++ /issm/trunk/src/m/consistency/ismodelselfconsistent.m	(revision 17989)
@@ -61,4 +61,7 @@
 		analyses=[BalancethicknessAnalysisEnum()];
 
+	case Balancethickness2SolutionEnum(),
+		analyses=[Balancethickness2AnalysisEnum()];
+
 	case BalancethicknessSoftSolutionEnum(),
 		analyses=[BalancethicknessAnalysisEnum()];
Index: /issm/trunk/src/m/contrib/bamg/gmsh.m
===================================================================
--- /issm/trunk/src/m/contrib/bamg/gmsh.m	(revision 17989)
+++ /issm/trunk/src/m/contrib/bamg/gmsh.m	(revision 17989)
@@ -0,0 +1,48 @@
+function md=gmsh(md,domainfile,h),
+
+%Read domain
+domain=expread(domainfile);
+x   = domain.x(1:end-1);
+y   = domain.y(1:end-1);
+nbv = numel(x);
+
+%write files
+t1=clock; fprintf('%s','      writing initial mesh files...');
+fid=fopen('model.geo','w');
+fprintf(fid,['// Gmsh input file, created by ISSM on ' date '\n']);
+for i=1:nbv,
+	fprintf(fid,'Point(%i) = {%8g, %8g, %8g};\n',i,x(i),y(i),0.);
+end
+for i=1:nbv-1
+	fprintf(fid,'Line(%i) = {%i, %i};\n',i,i,i+1);
+end
+fprintf(fid,'Line(%i) = {%i, %i};\n',nbv,nbv,1);
+fprintf(fid,'Line Loop(5) = {');
+for i=1:nbv-1
+	fprintf(fid,'%i,',i);
+end
+fprintf(fid,'%i};\n',nbv);
+fprintf(fid,'Plane Surface(6) = {5};\n');
+
+%Physical lines and surfaces
+fprintf(fid,'Physical Line(2) = {1};\n');
+fprintf(fid,'Physical Line(4) = {2};\n');
+fprintf(fid,'Physical Line(5) = {3};\n');
+fprintf(fid,'Physical Line(1) = {4};\n');
+fprintf(fid,'Physical Surface(7) = {6};\n');
+
+%resolution
+fprintf(fid,'Mesh.CharacteristicLengthMax = %g;',h);
+
+%fprintf(fid,'Plane Surface(7) = {6, 2};\n');
+fclose(fid);
+
+t2=clock;fprintf('%s\n',[' done (' num2str(etime(t2,t1)) ' seconds)']);
+
+%call gmsh
+fprintf('%s\n','      call gmsh...');
+system([issmdir() '/externalpackages/gmsh/install/gmsh -2 model.geo']);
+
+%plug new mesh
+t1=clock; fprintf('\n%s','      reading final mesh files...');
+md=importgmsh('model.msh',2);
Index: /issm/trunk/src/m/contrib/dassflow/importgmsh.m
===================================================================
--- /issm/trunk/src/m/contrib/dassflow/importgmsh.m	(revision 17988)
+++ /issm/trunk/src/m/contrib/dassflow/importgmsh.m	(revision 17989)
@@ -97,4 +97,7 @@
 				error('not supported');
 			end
+		case 15, %point
+			A=fscanf(fid,'%i',1);
+			continue;
 		otherwise,
 			error(['Type ' num2str(ty) ' not supported']);
@@ -124,5 +127,5 @@
 
 %Create model
-if 0, %2d triangles
+if dim==2, %2d triangles
 	md=meshconvert(model,index,x,y);
 	md.mesh=mesh2dvertical(md.mesh);
Index: /issm/trunk/src/m/dev/issmversion.m
===================================================================
--- /issm/trunk/src/m/dev/issmversion.m	(revision 17988)
+++ /issm/trunk/src/m/dev/issmversion.m	(revision 17989)
@@ -15,5 +15,5 @@
 disp([' ']);
 disp(['Build date: ' IssmConfig('PACKAGE_BUILD_DATE')]);
-disp(['Copyright (c) 2009-2013 California Institute of Technology']);
+disp(['Copyright (c) 2009-2014 California Institute of Technology']);
 disp([' ']);
 disp(['    to get started type: issmdoc']);
Index: /issm/trunk/src/m/enum/AdjointBalancethickness2AnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/AdjointBalancethickness2AnalysisEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/AdjointBalancethickness2AnalysisEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=AdjointBalancethickness2AnalysisEnum()
+%ADJOINTBALANCETHICKNESS2ANALYSISENUM - Enum of AdjointBalancethickness2Analysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=AdjointBalancethickness2AnalysisEnum()
+
+macro=StringToEnum('AdjointBalancethickness2Analysis');
Index: /issm/trunk/src/m/enum/AggressiveMigrationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/AggressiveMigrationEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/AggressiveMigrationEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=AggressiveMigrationEnum()
+%AGGRESSIVEMIGRATIONENUM - Enum of AggressiveMigration
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=AggressiveMigrationEnum()
+
+macro=StringToEnum('AggressiveMigration');
Index: sm/trunk/src/m/enum/AgressiveMigrationEnum.m
===================================================================
--- /issm/trunk/src/m/enum/AgressiveMigrationEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=AgressiveMigrationEnum()
-%AGRESSIVEMIGRATIONENUM - Enum of AgressiveMigration
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=AgressiveMigrationEnum()
-
-macro=StringToEnum('AgressiveMigration');
Index: /issm/trunk/src/m/enum/Balancethickness2AnalysisEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Balancethickness2AnalysisEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/Balancethickness2AnalysisEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=Balancethickness2AnalysisEnum()
+%BALANCETHICKNESS2ANALYSISENUM - Enum of Balancethickness2Analysis
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=Balancethickness2AnalysisEnum()
+
+macro=StringToEnum('Balancethickness2Analysis');
Index: /issm/trunk/src/m/enum/Balancethickness2MisfitEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Balancethickness2MisfitEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/Balancethickness2MisfitEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=Balancethickness2MisfitEnum()
+%BALANCETHICKNESS2MISFITENUM - Enum of Balancethickness2Misfit
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=Balancethickness2MisfitEnum()
+
+macro=StringToEnum('Balancethickness2Misfit');
Index: /issm/trunk/src/m/enum/Balancethickness2SolutionEnum.m
===================================================================
--- /issm/trunk/src/m/enum/Balancethickness2SolutionEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/Balancethickness2SolutionEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=Balancethickness2SolutionEnum()
+%BALANCETHICKNESS2SOLUTIONENUM - Enum of Balancethickness2Solution
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=Balancethickness2SolutionEnum()
+
+macro=StringToEnum('Balancethickness2Solution');
Index: /issm/trunk/src/m/enum/BalancethicknessApparentMassbalanceEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessApparentMassbalanceEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessApparentMassbalanceEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessApparentMassbalanceEnum()
+%BALANCETHICKNESSAPPARENTMASSBALANCEENUM - Enum of BalancethicknessApparentMassbalance
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessApparentMassbalanceEnum()
+
+macro=StringToEnum('BalancethicknessApparentMassbalance');
Index: /issm/trunk/src/m/enum/BalancethicknessNuxEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessNuxEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessNuxEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessNuxEnum()
+%BALANCETHICKNESSNUXENUM - Enum of BalancethicknessNux
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessNuxEnum()
+
+macro=StringToEnum('BalancethicknessNux');
Index: /issm/trunk/src/m/enum/BalancethicknessNuyEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessNuyEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessNuyEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessNuyEnum()
+%BALANCETHICKNESSNUYENUM - Enum of BalancethicknessNuy
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessNuyEnum()
+
+macro=StringToEnum('BalancethicknessNuy');
Index: /issm/trunk/src/m/enum/BalancethicknessSpcpotentialEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessSpcpotentialEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessSpcpotentialEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessSpcpotentialEnum()
+%BALANCETHICKNESSSPCPOTENTIALENUM - Enum of BalancethicknessSpcpotential
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessSpcpotentialEnum()
+
+macro=StringToEnum('BalancethicknessSpcpotential');
Index: /issm/trunk/src/m/enum/BalancethicknessThicknessObsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessThicknessObsEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessThicknessObsEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessThicknessObsEnum()
+%BALANCETHICKNESSTHICKNESSOBSENUM - Enum of BalancethicknessThicknessObs
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessThicknessObsEnum()
+
+macro=StringToEnum('BalancethicknessThicknessObs');
Index: /issm/trunk/src/m/enum/BalancethicknessVxObsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessVxObsEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessVxObsEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessVxObsEnum()
+%BALANCETHICKNESSVXOBSENUM - Enum of BalancethicknessVxObs
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessVxObsEnum()
+
+macro=StringToEnum('BalancethicknessVxObs');
Index: /issm/trunk/src/m/enum/BalancethicknessVyObsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/BalancethicknessVyObsEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/BalancethicknessVyObsEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=BalancethicknessVyObsEnum()
+%BALANCETHICKNESSVYOBSENUM - Enum of BalancethicknessVyObs
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=BalancethicknessVyObsEnum()
+
+macro=StringToEnum('BalancethicknessVyObs');
Index: /issm/trunk/src/m/enum/EnumDefinitions.py
===================================================================
--- /issm/trunk/src/m/enum/EnumDefinitions.py	(revision 17988)
+++ /issm/trunk/src/m/enum/EnumDefinitions.py	(revision 17989)
@@ -84,12 +84,10 @@
 def FrictionPEnum(): return StringToEnum("FrictionP")[0]
 def FrictionQEnum(): return StringToEnum("FrictionQ")[0]
+def FrictionMEnum(): return StringToEnum("FrictionM")[0]
+def FrictionCEnum(): return StringToEnum("FrictionC")[0]
+def FrictionLawEnum(): return StringToEnum("FrictionLaw")[0]
 def GeometryHydrostaticRatioEnum(): return StringToEnum("GeometryHydrostaticRatio")[0]
 def HydrologyModelEnum(): return StringToEnum("HydrologyModel")[0]
 def HydrologyshreveEnum(): return StringToEnum("Hydrologyshreve")[0]
-def HydrologyshreveCREnum(): return StringToEnum("HydrologyshreveCR")[0]
-def HydrologyshreveKnEnum(): return StringToEnum("HydrologyshreveKn")[0]
-def HydrologyshreveNEnum(): return StringToEnum("HydrologyshreveN")[0]
-def HydrologyshrevePEnum(): return StringToEnum("HydrologyshreveP")[0]
-def HydrologyshreveQEnum(): return StringToEnum("HydrologyshreveQ")[0]
 def HydrologyshreveSpcwatercolumnEnum(): return StringToEnum("HydrologyshreveSpcwatercolumn")[0]
 def HydrologyshreveStabilizationEnum(): return StringToEnum("HydrologyshreveStabilization")[0]
@@ -140,10 +138,19 @@
 def InversionGradientScalingEnum(): return StringToEnum("InversionGradientScaling")[0]
 def InversionIscontrolEnum(): return StringToEnum("InversionIscontrol")[0]
-def InversionTaoEnum(): return StringToEnum("InversionTao")[0]
+def InversionTypeEnum(): return StringToEnum("InversionType")[0]
 def InversionIncompleteAdjointEnum(): return StringToEnum("InversionIncompleteAdjoint")[0]
 def InversionMaxParametersEnum(): return StringToEnum("InversionMaxParameters")[0]
 def InversionMaxiterPerStepEnum(): return StringToEnum("InversionMaxiterPerStep")[0]
+def InversionMaxiterEnum(): return StringToEnum("InversionMaxiter")[0]
+def InversionMaxstepsEnum(): return StringToEnum("InversionMaxsteps")[0]
+def InversionFatolEnum(): return StringToEnum("InversionFatol")[0]
+def InversionFrtolEnum(): return StringToEnum("InversionFrtol")[0]
+def InversionGatolEnum(): return StringToEnum("InversionGatol")[0]
+def InversionGrtolEnum(): return StringToEnum("InversionGrtol")[0]
+def InversionGttolEnum(): return StringToEnum("InversionGttol")[0]
+def InversionAlgorithmEnum(): return StringToEnum("InversionAlgorithm")[0]
 def InversionMinParametersEnum(): return StringToEnum("InversionMinParameters")[0]
 def InversionNstepsEnum(): return StringToEnum("InversionNsteps")[0]
+def InversionDxminEnum(): return StringToEnum("InversionDxmin")[0]
 def InversionNumControlParametersEnum(): return StringToEnum("InversionNumControlParameters")[0]
 def InversionNumCostFunctionsEnum(): return StringToEnum("InversionNumCostFunctions")[0]
@@ -188,5 +195,5 @@
 def DamageEvolutionRequestedOutputsEnum(): return StringToEnum("DamageEvolutionRequestedOutputs")[0]
 def MaterialsRhoIceEnum(): return StringToEnum("MaterialsRhoIce")[0]
-def MaterialsRhoWaterEnum(): return StringToEnum("MaterialsRhoWater")[0]
+def MaterialsRhoSeawaterEnum(): return StringToEnum("MaterialsRhoSeawater")[0]
 def MaterialsRhoFreshwaterEnum(): return StringToEnum("MaterialsRhoFreshwater")[0]
 def MaterialsMuWaterEnum(): return StringToEnum("MaterialsMuWater")[0]
@@ -199,6 +206,4 @@
 def MaterialsMantleDensityEnum(): return StringToEnum("MaterialsMantleDensity")[0]
 def MeshAverageVertexConnectivityEnum(): return StringToEnum("MeshAverageVertexConnectivity")[0]
-def MeshElementonbaseEnum(): return StringToEnum("MeshElementonbase")[0]
-def MeshElementonsurfaceEnum(): return StringToEnum("MeshElementonsurface")[0]
 def MeshElements2dEnum(): return StringToEnum("MeshElements2d")[0]
 def MeshElementsEnum(): return StringToEnum("MeshElements")[0]
@@ -212,4 +217,5 @@
 def MeshVertexonbaseEnum(): return StringToEnum("MeshVertexonbase")[0]
 def MeshVertexonsurfaceEnum(): return StringToEnum("MeshVertexonsurface")[0]
+def MeshVertexonboundaryEnum(): return StringToEnum("MeshVertexonboundary")[0]
 def MeshXEnum(): return StringToEnum("MeshX")[0]
 def MeshYEnum(): return StringToEnum("MeshY")[0]
@@ -277,4 +283,5 @@
 def TimesteppingTimeAdaptEnum(): return StringToEnum("TimesteppingTimeAdapt")[0]
 def TimesteppingTimeStepEnum(): return StringToEnum("TimesteppingTimeStep")[0]
+def TimesteppingInterpForcingsEnum(): return StringToEnum("TimesteppingInterpForcings")[0]
 def TransientIsstressbalanceEnum(): return StringToEnum("TransientIsstressbalance")[0]
 def TransientIsgroundinglineEnum(): return StringToEnum("TransientIsgroundingline")[0]
@@ -286,4 +293,13 @@
 def TransientNumRequestedOutputsEnum(): return StringToEnum("TransientNumRequestedOutputs")[0]
 def TransientRequestedOutputsEnum(): return StringToEnum("TransientRequestedOutputs")[0]
+def PotentialEnum(): return StringToEnum("Potential")[0]
+def BalancethicknessSpcpotentialEnum(): return StringToEnum("BalancethicknessSpcpotential")[0]
+def BalancethicknessApparentMassbalanceEnum(): return StringToEnum("BalancethicknessApparentMassbalance")[0]
+def Balancethickness2MisfitEnum(): return StringToEnum("Balancethickness2Misfit")[0]
+def BalancethicknessNuxEnum(): return StringToEnum("BalancethicknessNux")[0]
+def BalancethicknessNuyEnum(): return StringToEnum("BalancethicknessNuy")[0]
+def BalancethicknessVxObsEnum(): return StringToEnum("BalancethicknessVxObs")[0]
+def BalancethicknessVyObsEnum(): return StringToEnum("BalancethicknessVyObs")[0]
+def BalancethicknessThicknessObsEnum(): return StringToEnum("BalancethicknessThicknessObs")[0]
 def SurfaceforcingsEnum(): return StringToEnum("Surfaceforcings")[0]
 def SMBEnum(): return StringToEnum("SMB")[0]
@@ -312,4 +328,5 @@
 def ConfigurationTypeEnum(): return StringToEnum("ConfigurationType")[0]
 def AdjointBalancethicknessAnalysisEnum(): return StringToEnum("AdjointBalancethicknessAnalysis")[0]
+def AdjointBalancethickness2AnalysisEnum(): return StringToEnum("AdjointBalancethickness2Analysis")[0]
 def AdjointHorizAnalysisEnum(): return StringToEnum("AdjointHorizAnalysis")[0]
 def AnalysisCounterEnum(): return StringToEnum("AnalysisCounter")[0]
@@ -317,4 +334,6 @@
 def BalancethicknessAnalysisEnum(): return StringToEnum("BalancethicknessAnalysis")[0]
 def BalancethicknessSolutionEnum(): return StringToEnum("BalancethicknessSolution")[0]
+def Balancethickness2AnalysisEnum(): return StringToEnum("Balancethickness2Analysis")[0]
+def Balancethickness2SolutionEnum(): return StringToEnum("Balancethickness2Solution")[0]
 def BalancethicknessSoftAnalysisEnum(): return StringToEnum("BalancethicknessSoftAnalysis")[0]
 def BalancethicknessSoftSolutionEnum(): return StringToEnum("BalancethicknessSoftSolution")[0]
@@ -520,4 +539,5 @@
 def HydrologyWaterVxEnum(): return StringToEnum("HydrologyWaterVx")[0]
 def HydrologyWaterVyEnum(): return StringToEnum("HydrologyWaterVy")[0]
+def SigmaNNEnum(): return StringToEnum("SigmaNN")[0]
 def StressTensorEnum(): return StringToEnum("StressTensor")[0]
 def StressTensorxxEnum(): return StringToEnum("StressTensorxx")[0]
@@ -605,5 +625,5 @@
 def AugmentedLagrangianThetaEnum(): return StringToEnum("AugmentedLagrangianTheta")[0]
 def NoneEnum(): return StringToEnum("None")[0]
-def AgressiveMigrationEnum(): return StringToEnum("AgressiveMigration")[0]
+def AggressiveMigrationEnum(): return StringToEnum("AggressiveMigration")[0]
 def SoftMigrationEnum(): return StringToEnum("SoftMigration")[0]
 def SubelementMigrationEnum(): return StringToEnum("SubelementMigration")[0]
Index: /issm/trunk/src/m/enum/FrictionCEnum.m
===================================================================
--- /issm/trunk/src/m/enum/FrictionCEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/FrictionCEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=FrictionCEnum()
+%FRICTIONCENUM - Enum of FrictionC
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=FrictionCEnum()
+
+macro=StringToEnum('FrictionC');
Index: /issm/trunk/src/m/enum/FrictionLawEnum.m
===================================================================
--- /issm/trunk/src/m/enum/FrictionLawEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/FrictionLawEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=FrictionLawEnum()
+%FRICTIONLAWENUM - Enum of FrictionLaw
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=FrictionLawEnum()
+
+macro=StringToEnum('FrictionLaw');
Index: /issm/trunk/src/m/enum/FrictionMEnum.m
===================================================================
--- /issm/trunk/src/m/enum/FrictionMEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/FrictionMEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=FrictionMEnum()
+%FRICTIONMENUM - Enum of FrictionM
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=FrictionMEnum()
+
+macro=StringToEnum('FrictionM');
Index: sm/trunk/src/m/enum/HydrologyshreveCREnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologyshreveCREnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologyshreveCREnum()
-%HYDROLOGYSHREVECRENUM - Enum of HydrologyshreveCR
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologyshreveCREnum()
-
-macro=StringToEnum('HydrologyshreveCR');
Index: sm/trunk/src/m/enum/HydrologyshreveKnEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologyshreveKnEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologyshreveKnEnum()
-%HYDROLOGYSHREVEKNENUM - Enum of HydrologyshreveKn
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologyshreveKnEnum()
-
-macro=StringToEnum('HydrologyshreveKn');
Index: sm/trunk/src/m/enum/HydrologyshreveNEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologyshreveNEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologyshreveNEnum()
-%HYDROLOGYSHREVENENUM - Enum of HydrologyshreveN
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologyshreveNEnum()
-
-macro=StringToEnum('HydrologyshreveN');
Index: sm/trunk/src/m/enum/HydrologyshrevePEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologyshrevePEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologyshrevePEnum()
-%HYDROLOGYSHREVEPENUM - Enum of HydrologyshreveP
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologyshrevePEnum()
-
-macro=StringToEnum('HydrologyshreveP');
Index: sm/trunk/src/m/enum/HydrologyshreveQEnum.m
===================================================================
--- /issm/trunk/src/m/enum/HydrologyshreveQEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=HydrologyshreveQEnum()
-%HYDROLOGYSHREVEQENUM - Enum of HydrologyshreveQ
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=HydrologyshreveQEnum()
-
-macro=StringToEnum('HydrologyshreveQ');
Index: /issm/trunk/src/m/enum/InversionAlgorithmEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionAlgorithmEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionAlgorithmEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionAlgorithmEnum()
+%INVERSIONALGORITHMENUM - Enum of InversionAlgorithm
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionAlgorithmEnum()
+
+macro=StringToEnum('InversionAlgorithm');
Index: /issm/trunk/src/m/enum/InversionDxminEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionDxminEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionDxminEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionDxminEnum()
+%INVERSIONDXMINENUM - Enum of InversionDxmin
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionDxminEnum()
+
+macro=StringToEnum('InversionDxmin');
Index: /issm/trunk/src/m/enum/InversionFatolEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionFatolEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionFatolEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionFatolEnum()
+%INVERSIONFATOLENUM - Enum of InversionFatol
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionFatolEnum()
+
+macro=StringToEnum('InversionFatol');
Index: /issm/trunk/src/m/enum/InversionFrtolEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionFrtolEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionFrtolEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionFrtolEnum()
+%INVERSIONFRTOLENUM - Enum of InversionFrtol
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionFrtolEnum()
+
+macro=StringToEnum('InversionFrtol');
Index: /issm/trunk/src/m/enum/InversionGatolEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionGatolEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionGatolEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionGatolEnum()
+%INVERSIONGATOLENUM - Enum of InversionGatol
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionGatolEnum()
+
+macro=StringToEnum('InversionGatol');
Index: /issm/trunk/src/m/enum/InversionGrtolEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionGrtolEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionGrtolEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionGrtolEnum()
+%INVERSIONGRTOLENUM - Enum of InversionGrtol
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionGrtolEnum()
+
+macro=StringToEnum('InversionGrtol');
Index: /issm/trunk/src/m/enum/InversionGttolEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionGttolEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionGttolEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionGttolEnum()
+%INVERSIONGTTOLENUM - Enum of InversionGttol
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionGttolEnum()
+
+macro=StringToEnum('InversionGttol');
Index: /issm/trunk/src/m/enum/InversionMaxiterEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionMaxiterEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionMaxiterEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionMaxiterEnum()
+%INVERSIONMAXITERENUM - Enum of InversionMaxiter
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionMaxiterEnum()
+
+macro=StringToEnum('InversionMaxiter');
Index: /issm/trunk/src/m/enum/InversionMaxstepsEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionMaxstepsEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionMaxstepsEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionMaxstepsEnum()
+%INVERSIONMAXSTEPSENUM - Enum of InversionMaxsteps
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionMaxstepsEnum()
+
+macro=StringToEnum('InversionMaxsteps');
Index: sm/trunk/src/m/enum/InversionTaoEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionTaoEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=InversionTaoEnum()
-%INVERSIONTAOENUM - Enum of InversionTao
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=InversionTaoEnum()
-
-macro=StringToEnum('InversionTao');
Index: /issm/trunk/src/m/enum/InversionTypeEnum.m
===================================================================
--- /issm/trunk/src/m/enum/InversionTypeEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/InversionTypeEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=InversionTypeEnum()
+%INVERSIONTYPEENUM - Enum of InversionType
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=InversionTypeEnum()
+
+macro=StringToEnum('InversionType');
Index: /issm/trunk/src/m/enum/MaterialsRhoSeawaterEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MaterialsRhoSeawaterEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/MaterialsRhoSeawaterEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=MaterialsRhoSeawaterEnum()
+%MATERIALSRHOSEAWATERENUM - Enum of MaterialsRhoSeawater
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MaterialsRhoSeawaterEnum()
+
+macro=StringToEnum('MaterialsRhoSeawater');
Index: sm/trunk/src/m/enum/MaterialsRhoWaterEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MaterialsRhoWaterEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=MaterialsRhoWaterEnum()
-%MATERIALSRHOWATERENUM - Enum of MaterialsRhoWater
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=MaterialsRhoWaterEnum()
-
-macro=StringToEnum('MaterialsRhoWater');
Index: sm/trunk/src/m/enum/MeshElementonbaseEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshElementonbaseEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=MeshElementonbaseEnum()
-%MESHELEMENTONBASEENUM - Enum of MeshElementonbase
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=MeshElementonbaseEnum()
-
-macro=StringToEnum('MeshElementonbase');
Index: sm/trunk/src/m/enum/MeshElementonsurfaceEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshElementonsurfaceEnum.m	(revision 17988)
+++ 	(revision )
@@ -1,11 +1,0 @@
-function macro=MeshElementonsurfaceEnum()
-%MESHELEMENTONSURFACEENUM - Enum of MeshElementonsurface
-%
-%   WARNING: DO NOT MODIFY THIS FILE
-%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
-%            Please read src/c/shared/Enum/README for more information
-%
-%   Usage:
-%      macro=MeshElementonsurfaceEnum()
-
-macro=StringToEnum('MeshElementonsurface');
Index: /issm/trunk/src/m/enum/MeshVertexonboundaryEnum.m
===================================================================
--- /issm/trunk/src/m/enum/MeshVertexonboundaryEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/MeshVertexonboundaryEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=MeshVertexonboundaryEnum()
+%MESHVERTEXONBOUNDARYENUM - Enum of MeshVertexonboundary
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=MeshVertexonboundaryEnum()
+
+macro=StringToEnum('MeshVertexonboundary');
Index: /issm/trunk/src/m/enum/PotentialEnum.m
===================================================================
--- /issm/trunk/src/m/enum/PotentialEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/PotentialEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=PotentialEnum()
+%POTENTIALENUM - Enum of Potential
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=PotentialEnum()
+
+macro=StringToEnum('Potential');
Index: /issm/trunk/src/m/enum/SigmaNNEnum.m
===================================================================
--- /issm/trunk/src/m/enum/SigmaNNEnum.m	(revision 17989)
+++ /issm/trunk/src/m/enum/SigmaNNEnum.m	(revision 17989)
@@ -0,0 +1,11 @@
+function macro=SigmaNNEnum()
+%SIGMANNENUM - Enum of SigmaNN
+%
+%   WARNING: DO NOT MODIFY THIS FILE
+%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
+%            Please read src/c/shared/Enum/README for more information
+%
+%   Usage:
+%      macro=SigmaNNEnum()
+
+macro=StringToEnum('SigmaNN');
Index: /issm/trunk/src/m/exp/expwrite.py
===================================================================
--- /issm/trunk/src/m/exp/expwrite.py	(revision 17988)
+++ /issm/trunk/src/m/exp/expwrite.py	(revision 17989)
@@ -5,8 +5,8 @@
 	EXPWRITE - write an Argus file from a structure given in input
 
-	   This routine write an Argus file form a structure containing the fields:
+	   This routine writes an Argus file from a list of dict's containing the fields:
 	   x and y of the coordinates of the points.
-	   The first argument is the structure containing the points coordinates 
-	   and the second one the file to be write.
+	   The first argument is the list containing the points coordinates 
+	   and the second one the file to be written.
 
 	   Usage:
Index: /issm/trunk/src/m/extrusion/DepthAverage.m
===================================================================
--- /issm/trunk/src/m/extrusion/DepthAverage.m	(revision 17988)
+++ /issm/trunk/src/m/extrusion/DepthAverage.m	(revision 17989)
@@ -9,5 +9,5 @@
 
 %check that the model given in input is 3d
-if ~strcmp(md.mesh.elementtype(),'3D');
+if ~strcmp(md.mesh.elementtype(),'Penta');
 	error('DepthAverage error message: the model given in input must be 3d')
 end
Index: /issm/trunk/src/m/extrusion/DepthAverage.py
===================================================================
--- /issm/trunk/src/m/extrusion/DepthAverage.py	(revision 17988)
+++ /issm/trunk/src/m/extrusion/DepthAverage.py	(revision 17989)
@@ -15,5 +15,5 @@
 
 	#check that the model given in input is 3d
-	if md.mesh.domaintype().lower() != '3d':
+	if md.mesh.elementtype() != 'Penta':
 		raise TypeError('DepthAverage error message: the model given in input must be 3d')
 
Index: /issm/trunk/src/m/extrusion/project2d.py
===================================================================
--- /issm/trunk/src/m/extrusion/project2d.py	(revision 17988)
+++ /issm/trunk/src/m/extrusion/project2d.py	(revision 17989)
@@ -34,8 +34,8 @@
 
 	vec2d=False
-	if value.ndim==2: 
+	if value.ndim==2 and value.shape[1]==1: 
 		value=value.reshape(-1,)
 		vec2d=True
-	
+
 	if value.size==1:
 		projection_value=value[(layer-1)*md3d.mesh.numberofelements2d:layer*md3d.mesh.numberofelements2d]
Index: /issm/trunk/src/m/interp/SectionValues.py
===================================================================
--- /issm/trunk/src/m/interp/SectionValues.py	(revision 17988)
+++ /issm/trunk/src/m/interp/SectionValues.py	(revision 17989)
@@ -5,5 +5,5 @@
 #from InterpFromMesh2d import InterpFromMesh2d
 from InterpFromMeshToMesh2d import InterpFromMeshToMesh2d
-#from InterpFromMeshToMesh3d import InterpFromMeshToMesh3d
+from InterpFromMeshToMesh3d import InterpFromMeshToMesh3d
 
 def SectionValues(md,data,infile,resolution):
@@ -80,5 +80,5 @@
 	
 	#New mesh and Data interpolation
-	if md.mesh.domaintype().lower() == '2d':
+	if '2d' in md.mesh.domaintype().lower():
 	
 		#Interpolation of data on specified points
@@ -103,5 +103,4 @@
 		#Some useful parameters
 		layers=int(npy.ceil(npy.mean(md.geometry.thickness)/res_v))
-		print 'layers=', layers
 		nodesperlayer=int(numberofnodes)
 		nodestot=int(nodesperlayer*layers)
@@ -128,5 +127,5 @@
 
 		#Interpolation of data on specified points
-		# TODO data_interp=InterpFromMeshToMesh3d(md.mesh.elements,md.mesh.x,md.mesh.y,md.mesh.z,data,X3,Y3,Z3,npy.nan)
+		data_interp=InterpFromMeshToMesh3d(md.mesh.elements,md.mesh.x,md.mesh.y,md.mesh.z,data,X3,Y3,Z3,npy.nan)
 	
 		#build outputs
@@ -138,3 +137,3 @@
 		index=index3
 
-		return index,X,Y,Z,S,data_interp
+	return index,X,Y,Z,S,data_interp
Index: /issm/trunk/src/m/interp/averaging.py
===================================================================
--- /issm/trunk/src/m/interp/averaging.py	(revision 17988)
+++ /issm/trunk/src/m/interp/averaging.py	(revision 17989)
@@ -79,7 +79,6 @@
 		average_node = csc_matrix(average_node)
 	else:
-		average_node=data
+		average_node=csc_matrix(data.reshape(-1,1))
 
-	
 	#loop over iteration
 	for i in npy.arange(1,iterations+1):
@@ -87,4 +86,5 @@
 		average_node=csc_matrix( (npy.tile(areas*average_el.reshape(-1),(rep,1)).reshape(-1,),(line,npy.zeros(linesize,))), shape=(numberofnodes,1))
 		average_node=average_node/weights
+		average_node=csc_matrix(average_node)
 	
 	#return output as a full matrix (C code do not like sparse matrices)
Index: /issm/trunk/src/m/interp/holefiller.py
===================================================================
--- /issm/trunk/src/m/interp/holefiller.py	(revision 17988)
+++ /issm/trunk/src/m/interp/holefiller.py	(revision 17989)
@@ -2,9 +2,10 @@
 from scipy.spatial import cKDTree
 
-def nearestneighbors(md,data,goodids,badids,knn):
+def nearestneighbors(x,y,data,goodids,badids,knn):
 	'''
 	fill holes using nearest neigbors.  Arguments include:
 
-	md:		the model
+
+	x,y:		the coordinates of data to be filled 
 	data:		the data field to be filled (full field, including holes)
 	goodids:	id's into the vertices that have good data
@@ -15,8 +16,8 @@
 
 	Usage:
-		filleddata=nearestneighbors(md,goodids,badids,knn)
+		filleddata=nearestneighbors(x,y,data,goodids,badids,knn)
 
 	Example:
-		filledthickness=nearestneighbors(md,goodids,badids,5)
+		filledthickness=nearestneighbors(x,y,data,goodids,badids,5)
 	'''
 
@@ -24,11 +25,11 @@
 		raise TypeError('nearestneighbors error: knn should be an integer>1')
 
-	if len(data) != md.mesh.numberofvertices:
-		raise StandardError('nearestneighbors error: "data" should have length md.mesh.numberofvertices')
+	if len(x) != len(data) or len(y) != len(data):
+		raise StandardError('nearestneighbors error: x and y should have the same length as "data"')
 
 	filled=data
 	
-	XYGood=npy.dstack([md.mesh.x[goodids],md.mesh.y[goodids]])[0]
-	XYBad=npy.dstack([md.mesh.x[badids],md.mesh.y[badids]])[0]
+	XYGood=npy.dstack([x[goodids],y[goodids]])[0]
+	XYBad=npy.dstack([x[badids],y[badids]])[0]
 	tree=cKDTree(XYGood)
 	nearest=tree.query(XYBad,k=knn)[1]
Index: /issm/trunk/src/m/interp/interp.py
===================================================================
--- /issm/trunk/src/m/interp/interp.py	(revision 17988)
+++ /issm/trunk/src/m/interp/interp.py	(revision 17989)
@@ -178,5 +178,5 @@
 	return interpdata
 #}}}
-def RadialInterp(x,y,data,**kwargs):#{{{
+def RadialInterp(x,y,data,xi,yi,**kwargs):#{{{
 	'''
 	Interpolation using a radial basis function in 2 or 3 dimensions.
@@ -187,18 +187,19 @@
 	x,y:			data point coordinates
 	data:			data to be interpolated (same length as x,y)
-
-		function: form of radial basis function for interpolation:
-			'multiquadric': sqrt((r/self.epsilon)**2 + 1) (default)
-			'inverse': 1.0/sqrt((r/self.epsilon)**2 + 1)
-			'gaussian': exp(-(r/self.epsilon)**2)
-			'linear': r
-			'cubic': r**3
-			'quintic': r**5
-			'thin_plate': r**2 * log(r)
-		epsilon: adjustable constant for scaling radial distance.  Defaults to 
+	xi,yi:		coordinates to interpolate onto
+	function:	form of radial basis function for interpolation:
+					'multiquadric': sqrt((r/self.epsilon)**2 + 1) (default)
+					'inverse': 1.0/sqrt((r/self.epsilon)**2 + 1)
+					'gaussian': exp(-(r/self.epsilon)**2)
+					'linear': r
+					'cubic': r**3
+					'quintic': r**5
+					'thin_plate': r**2 * log(r)
+	epsilon:		adjustable constant for scaling radial distance.  Defaults to 
 					approximate average distance between nodes.
-		smooth: float>0, adjusts the amount of smoothing applied.  Defaults to 0,
+	smooth:		float>0, adjusts the amount of smoothing applied.  Defaults to 0,
 					such that the function always passes through nodal points.
-		z:	coordinate array if interpolating in 3 dimensions
+	z:				coordinate array if interpolating in 3 dimensions
+	zi:			coordinate array if interpolating in 3 dimensions
 
 	Usage:
@@ -211,5 +212,5 @@
 
 	# unpack kwargs
-	function=kwargs.pop('function','multiquadric')
+	function=kwargs.pop('function','gaussian')
 	if 'function' in kwargs: del kwargs['function']
 	epsilon=kwargs.pop('epsilon',None)
@@ -226,5 +227,5 @@
 		else:
 			rbfi=Rbf(x,y,z,data,function=function,smooth=smooth)
-		interpdata=rbfi(x,y,z)
+		interpdata=rbfi(xi,yi,zi)
 	else:
 		if epsilon:
@@ -232,5 +233,5 @@
 		else:
 			rbfi=Rbf(x,y,data,function=function,smooth=smooth)
-		interpdata=rbfi(x,y)
+		interpdata=rbfi(xi,yi)
 	
 	return interpdata
Index: /issm/trunk/src/m/materials/DepthAvgTempCond.m
===================================================================
--- /issm/trunk/src/m/materials/DepthAvgTempCond.m	(revision 17989)
+++ /issm/trunk/src/m/materials/DepthAvgTempCond.m	(revision 17989)
@@ -0,0 +1,25 @@
+function Tbar=DepthAvgTempCond(md)
+%DEPTHAVGTEMPCOND- compute conduction dependent temperature profile for an ice sheet. 
+%
+%   Usage:
+%   Tbar=DepthAvgTempCond(md)
+
+Tpmp=TMeltingPoint(md.materials.meltingpoint,0); %pressure melting point at 0 pressure.
+k=md.materials.thermalconductivity;
+G=md.basalforcings.geothermalflux; 
+H=md.geometry.thickness;
+Ts=md.initialization.temperature;
+alpha=G.*H/k;
+
+Tbar=zeros(md.mesh.numberofvertices,1);
+
+%find temperature average when we are below melting point: 
+pos=find( (Ts+alpha) <Tpmp);
+Tbar(pos)=Ts(pos)+alpha(pos)/2;
+
+pos=find( (Ts+alpha) >=Tpmp);
+Tbar(pos)=Tpmp+(Tpmp^2-Ts(pos).^2)/2./alpha(pos)+ Tpmp*(Ts(pos)-Tpmp)./alpha(pos);
+
+%on ice shelf, easier: 
+pos=find(md.mask.groundedice_levelset<=0);
+Tbar(pos)=(Ts(pos)+Tpmp)/2;
Index: /issm/trunk/src/m/materials/DepthAvgTempCond.py
===================================================================
--- /issm/trunk/src/m/materials/DepthAvgTempCond.py	(revision 17989)
+++ /issm/trunk/src/m/materials/DepthAvgTempCond.py	(revision 17989)
@@ -0,0 +1,34 @@
+import numpy as npy
+from TMeltingPoint  import TMeltingPoint
+
+def DepthAvgTempCond(md):
+   ''' compute conduction dependent temperature profile for an ice sheet. 
+   Usage:
+   Tbar=DepthAvgTempCond(md)
+   '''
+
+   Tpmp=TMeltingPoint(md.materials.meltingpoint,0) #pressure melting point at 0 pressure.
+
+   k=md.materials.thermalconductivity
+   G=md.basalforcings.geothermalflux
+   H=md.geometry.thickness[:,0]
+   Ts=md.initialization.temperature
+   alpha=G*H/k
+
+   Tbar=npy.zeros(md.mesh.numberofvertices,)
+
+   #find temperature average when we are below melting point: 
+   pos=npy.nonzero( Ts+alpha < Tpmp)
+   if pos:
+	   Tbar[pos]=Ts[pos]+alpha[pos]/2 
+
+   pos=npy.nonzero( Ts+alpha>= Tpmp)
+   if pos:
+	   Tbar[pos]=Tpmp+(Tpmp**2-Ts[pos]**2)/2/alpha[pos]+ Tpmp*(Ts[pos]-Tpmp)/alpha[pos]
+   
+   #on ice shelf, easier: 
+   pos=npy.nonzero(md.mask.groundedice_levelset[0]<=0)
+   if pos:
+	   Tbar[pos]=(Ts[pos]+Tpmp)/2
+
+   return Tbar
Index: /issm/trunk/src/m/materials/paterson.py
===================================================================
--- /issm/trunk/src/m/materials/paterson.py	(revision 17988)
+++ /issm/trunk/src/m/materials/paterson.py	(revision 17989)
@@ -16,7 +16,10 @@
 
 	if numpy.ndim(temperature)==2:
-		T = temperature.reshape(-1,)-273.15
+		#T = temperature.reshape(-1,)-273.15
+		T = temperature.flatten()-273.15
+	elif isinstance(temperature,float) or isinstance(temperature,int):
+		T = numpy.array([temperature])-273.15
 	else:
-		T = numpy.array([temperature])-273.15
+		T = temperature-273.15
 
 	#The routine below is equivalent to:
@@ -71,5 +74,5 @@
 	pos=numpy.nonzero(rigidity<0)[0]
 	if len(pos):
-		rigidity[pos]=1**6 
+		rigidity[pos]=1.e6 
 
 	return rigidity
Index: /issm/trunk/src/m/mech/analyticaldamage.py
===================================================================
--- /issm/trunk/src/m/mech/analyticaldamage.py	(revision 17988)
+++ /issm/trunk/src/m/mech/analyticaldamage.py	(revision 17989)
@@ -1,5 +1,5 @@
 import numpy as npy
 from averaging import averaging
-from plotmodel import plotmodel
+#from plotmodel import plotmodel
 from thomasparams import thomasparams
 
@@ -53,5 +53,5 @@
 	assert len(kwargs)==0, 'error, unexpected or misspelled kwargs'
 
-	if len(sigmab)==1:
+	if isinstance(sigmab,(int,float)):
 		sigmab=sigmab*npy.ones((md.mesh.numberofvertices,))
 
@@ -83,5 +83,5 @@
 	
 	backstress=npy.zeros((md.mesh.numberofvertices,))
-	
+
 	# backstress to bring D down to one 
 	backstress[pos]=T[pos]-(1.-D[pos])*B[pos]*npy.sign(ex[pos])*(2.+a[pos])*npy.abs(ex[pos])**(1./n[pos])/(1.+a[pos]+a[pos]**2)**((n[pos]-1.)/2./n[pos])
Index: /issm/trunk/src/m/mech/mechanicalproperties.py
===================================================================
--- /issm/trunk/src/m/mech/mechanicalproperties.py	(revision 17988)
+++ /issm/trunk/src/m/mech/mechanicalproperties.py	(revision 17989)
@@ -76,5 +76,6 @@
 		nu[location]=10^18
 	elif 'matdamageice' in md.materials.__module__:
-		Zinv=npy.dot(md.materials.rheology_Z[index-1],summation/3.).reshape(-1,)
+		print 'computing damage-dependent properties!'
+		Zinv=npy.dot(1-md.damage.D[index-1],summation/3.).reshape(-1,)
 		location=npy.nonzero(second_inv)
 		nu[location]=Zinv[location]*B_bar[location]/npy.power(second_inv[location],power[location])
Index: /issm/trunk/src/m/mech/robintemperature.py
===================================================================
--- /issm/trunk/src/m/mech/robintemperature.py	(revision 17988)
+++ /issm/trunk/src/m/mech/robintemperature.py	(revision 17989)
@@ -37,5 +37,6 @@
 	
 	tprofile=surftemp+npy.sqrt(2.*thickness*npy.pi/accumrate/alphaT)*(-heatflux)/2./rho/c*(erf(z/zstar)-erf(thickness/zstar))
-	
+
+	return tprofile	
 	# difference between surface and base temperature for check (Cuffey2010 p412):
 	# print tprofile-surftemp
Index: /issm/trunk/src/m/mech/thomasparams.py
===================================================================
--- /issm/trunk/src/m/mech/thomasparams.py	(revision 17988)
+++ /issm/trunk/src/m/mech/thomasparams.py	(revision 17989)
@@ -134,5 +134,5 @@
 	elif eq=='Weertman2D':
 		theta=1./9
-		a=npy.ones((md.mesh.numberofvertices,1))
+		a=npy.ones((md.mesh.numberofvertices,))
 	elif eq=='Thomas':
 		theta=((1.+a+a**2+b**2)**((n-1.)/2.))/(npy.abs(2.+a)**n)
Index: /issm/trunk/src/m/parameterization/setflowequation.py
===================================================================
--- /issm/trunk/src/m/parameterization/setflowequation.py	(revision 17988)
+++ /issm/trunk/src/m/parameterization/setflowequation.py	(revision 17989)
@@ -89,5 +89,5 @@
 		                              numpy.logical_not(numpy.isnan(md.stressbalance.spcvy)).astype(int)+ \
 		                              numpy.logical_not(numpy.isnan(md.stressbalance.spcvz)).astype(int)==3, \
-		                              numpy.logical_and(nodeonHO,nodeonFS).reshape(-1,1)).astype(int)    #find all the nodes on the boundary of the domain without icefront
+		                              numpy.logical_and(nodeonHO,nodeonFS)).astype(int)    #find all the nodes on the boundary of the domain without icefront
 #		fullspcelems=double(sum(fullspcnodes(md.mesh.elements),2)==6);         %find all the nodes on the boundary of the domain without icefront
 		fullspcelems=(numpy.sum(fullspcnodes[md.mesh.elements-1],axis=1)==6).astype(int)    #find all the nodes on the boundary of the domain without icefront
Index: /issm/trunk/src/m/parameterization/setmask.py
===================================================================
--- /issm/trunk/src/m/parameterization/setmask.py	(revision 17988)
+++ /issm/trunk/src/m/parameterization/setmask.py	(revision 17989)
@@ -55,9 +55,9 @@
 
 	#level sets
-	md.mask.groundedice_levelset = -1.*numpy.ones((md.mesh.numberofvertices,1))
+	md.mask.groundedice_levelset = -1.*numpy.ones(md.mesh.numberofvertices)
 	md.mask.groundedice_levelset[md.mesh.elements[numpy.nonzero(elementongroundedice),:]-1]=1.
 
 	if(len(args)):
-		md.mask.ice_levelset = 1.*numpy.ones((md.mesh.numberofvertices,1))
+		md.mask.ice_levelset = 1.*numpy.ones(md.mesh.numberofvertices)
 		icedomainfile = options.getfieldvalue('icedomain','none')
 		if not os.path.exists(icedomainfile):
@@ -67,5 +67,5 @@
 		md.mask.ice_levelset[numpy.nonzero(vertexinsideicedomain)[0]] = -1.
 	else:
-		md.mask.ice_levelset = -1.*numpy.ones((md.mesh.numberofvertices,1))
+		md.mask.ice_levelset = -1.*numpy.ones(md.mesh.numberofvertices)
 
 	return md
Index: /issm/trunk/src/m/plot/applyoptions.py
===================================================================
--- /issm/trunk/src/m/plot/applyoptions.py	(revision 17988)
+++ /issm/trunk/src/m/plot/applyoptions.py	(revision 17989)
@@ -59,5 +59,5 @@
 		titlefont['size']=titlefontsize
 		titlefont['weight']=titlefontweight
-		fig.set_title(title,**titlefont)
+		ax.set_title(title,**titlefont)
 	#}}}
 		
@@ -107,16 +107,17 @@
 
 	#xticklabels,yticklabels,zticklabels {{{
+	if options.getfieldvalue('ticklabels','off')=='off' or options.getfieldvalue('ticklabels',0)==0:
+		options.addfielddefault('xticklabels',[])
+		options.addfielddefault('yticklabels',[])
+		# TODO check if ax has a z-axis (e.g. is 3D)
 	if options.exist('xticklabels'):
 		xticklabels=options.getfieldvalue('xticklabels')
-		xtickloc=p.xticks()[0]	
-		ax.set_xticks(xtickloc,xticklabels)
+		ax.set_xticklabels(xticklabels)
 	if options.exist('yticklabels'):
 		yticklabels=options.getfieldvalue('yticklabels')
-		ytickloc=p.yticks()[0]	
-		ax.set_yticks(ytickloc,yticklabels)
+		ax.set_yticklabels(yticklabels)
 	if options.exist('zticklabels'):
 		zticklabels=options.getfieldvalue('zticklabels')
-		ztickloc=p.zticks()[0]	
-		ax.set_zticks(ztickloc,zticklabels)
+		ax.set_zticklabels(zticklabels)
 	#}}}
 
@@ -171,4 +172,5 @@
 	else:
 		if len(data)>0: lims=[data.min(),data.max()]
+		else: lims=[0,1]
 	#}}}
 
@@ -229,6 +231,11 @@
 			cb.add_lines(locs,['k' for i in range(len(locs))],npy.ones_like(locs))
 		if options.exist('colorbartitle'):
-			cb.set_label(options.getfieldvalue('colorbartitle'),fontsize=fontsize)
+			if options.exist('colorbartitlepad'):
+				cb.set_label(options.getfieldvalue('colorbartitle'),\
+						labelpad=options.getfieldvalue('colorbartitlepad'),fontsize=fontsize)
+			else:
+				cb.set_label(options.getfieldvalue('colorbartitle'),fontsize=fontsize)
 		cb.ax.tick_params(labelsize=fontsize)
+		plt.sca(ax) # return to original axes control
 	#}}}
 
@@ -237,5 +244,16 @@
 	#expdisp
 
-	#text
+	#text {{{
+	if options.exist('text'):
+		text=options.getfieldvalue('text')
+		textx=options.getfieldvalue('textx')
+		texty=options.getfieldvalue('texty')
+		textsize=options.getfieldvalue('textsize')
+		textcolor=options.getfieldvalue('textcolor')
+		textweight=options.getfieldvalue('textweight')
+		textrotation=options.getfieldvalue('textrotation')
+		for label,x,y,size,color,weight,rotation in zip(text,textx,texty,textsize,textcolor,textweight,textrotation):
+			ax.text(x,y,label,transform=ax.transAxes,fontsize=size,color=color,weight=weight,rotation=rotation)
+	#}}}
 
 	#north arrow
Index: /issm/trunk/src/m/plot/checkplotoptions.py
===================================================================
--- /issm/trunk/src/m/plot/checkplotoptions.py	(revision 17988)
+++ /issm/trunk/src/m/plot/checkplotoptions.py	(revision 17989)
@@ -50,48 +50,67 @@
 	#text
 	if options.exist('text'):
-		#1: textvalue
-		textvalues=options.getfieldvalue('text')
-		numtext=len(textvalues)
 
-		#2: textweight
+		# text values (coerce to list for consistent functionality)
+		textlist=[]
+		text=options.getfieldvalue('text','default text')
+		textlist.extend([text] if isinstance(text,str) else text)
+		numtext=len(textlist)
+
+		# text position	
+		textpos=options.getfieldvalue('textposition',[0.5,0.5])
+		if not isinstance(textpos,list):
+			raise Exception('textposition should be passed as a list')
+		textx=[item[0] for item in textpos]
+		texty=[item[1] for item in textpos]
+		if len(textx)!=numtext or len(texty)!=numtext:
+			raise Exception('textposition should contain one list of x,y vertices for every text instance')
+
+		# font size
+		if options.exist('textsize'):
+			textsize=options.getfieldvalue('textsize',12)
+			sizelist=[]
+			sizelist.extend(textsize if isinstance(textsize,list) else [textsize])
+		else:
+			sizelist=[12]
+		if len(sizelist)==1:
+			sizelist=npy.tile(sizelist,numtext)
+
+		# font color
+		if options.exist('textcolor'):
+			textcolor=options.getfieldvalue('textcolor','k')
+			colorlist=[]
+			colorlist.extend(textcolor if isinstance(textcolor,list) else [textcolor])
+		else:
+			colorlist=['k']
+		if len(colorlist)==1:
+			colorlist=npy.tile(colorlist,numtext)
+
+		# textweight
 		if options.exist('textweight'):
 			textweightvalues=options.getfieldvalue('textweight')
+			weightlist=[]
+			weightlist.extend(textweight if isinstance(textwieght,list) else [textweight])
 		else:
-			textweightvalues='n'
-		textweightvalues=npy.tile(textweightvalues,numtext)
+			weightlist=['normal']
+		if len(weightlist)==1:
+			weightlist=npy.tile(weightlist,numtext)
 
-		#3 textsize
-		if options.exist('textsize'):
-			textsizevalues=options.getfieldvalue('textsize')
+		# text rotation
+		if options.exist('textrotation'):
+			textrotation=options.getfieldvalue('textrotation',0)
+			rotationlist=[]
+			rotationlist.extend(textrotation if isinstance(textrotation,list) else [textrotation])
 		else:
-			textsizevalues=14
-		textsizevalues=npy.tile(textsizevalues,numtext)
+			rotationlist=[0]
+		if len(rotationlist)==1:
+				rotationlist=npy.tile(rotationlist,numtext)
 
-		#4 textcolor
-		if options.exist('textcolor'):
-			textcolorvalues=options.getfieldvalue('textcolor')
-		else:
-			textcolorvalues='k'
-		textcolorvalues=npy.tile(textsizevalues,numtext)
-
-		#5 textposition
-		if options.exist('textposition'):
-			options.getfieldvalue('textposition')
-		else:
-			raise Exception("plotmodel error message: 'textposition' option is missing")
-
-		#6 textrotation
-		if options.exist('textrotation'):
-			textrotationvalues=options.getfieldvalue('textrotation')
-		else:
-			textrotationvalues=0
-		textrotationvalues=npy.tile(textrotationvalues,numtext)
-
-		options.changfieldvalue('text',textvalues)
-		options.changfieldvalue('textsize',textsizevalues)
-		options.changfieldvalue('textweight',textweightvalues)
-		options.changfieldvalue('textcolor',textcolorvalues)
-		options.changfieldvalue('textposition',textpositionvalues)
-		options.changfieldvalue('textrotation',textrotationvalues)
+		options.changefieldvalue('text',textlist)
+		options.addfield('textx',textx)
+		options.addfield('texty',texty)
+		options.changefieldvalue('textsize',sizelist)
+		options.changefieldvalue('textcolor',colorlist)
+		options.changefieldvalue('textweight',weightlist)
+		options.changefieldvalue('textrotation',rotationlist)
 
 	#expdisp
Index: /issm/trunk/src/m/plot/plot_manager.py
===================================================================
--- /issm/trunk/src/m/plot/plot_manager.py	(revision 17988)
+++ /issm/trunk/src/m/plot/plot_manager.py	(revision 17989)
@@ -11,5 +11,14 @@
 from plot_unit import plot_unit
 from applyoptions import applyoptions
-from plot_overlay import plot_overlay
+
+try:
+	from osgeo import gdal
+	overlaysupport=True
+except ImportError:
+	print 'osgeo/gdal for python not installed, overlay plots are not enabled'
+	overlaysupport=False
+
+if overlaysupport:
+	from plot_overlay import plot_overlay
 
 def plot_manager(md,options,fig,ax):
@@ -45,5 +54,5 @@
 
 	#overlay plot
-	if options.exist('overlay'):
+	if options.exist('overlay') and overlaysupport:
 		plot_overlay(md,data,options,ax)
 		options.addfielddefault('alpha',0.5)
@@ -57,7 +66,10 @@
 		if data.lower()=='mesh': 
 			plot_mesh(md,options,ax)
+			applyoptions(md,[],options,fig,ax)
+			fig.delaxes(fig.axes[1]) # hack to remove colorbar after the fact
 			return
 		elif data.lower()=='none':
 			print 'no data provided to plot (TODO: write plot_none.py)'
+			applyoptions(md,[],options,fig,ax)
 			return
 		else:
Index: /issm/trunk/src/m/plot/plot_mesh.py
===================================================================
--- /issm/trunk/src/m/plot/plot_mesh.py	(revision 17988)
+++ /issm/trunk/src/m/plot/plot_mesh.py	(revision 17989)
@@ -7,5 +7,5 @@
 from applyoptions import applyoptions
 
-def plot_mesh(md,options,nlines,ncols,i):
+def plot_mesh(md,options,ax):
 	'''
 	PLOT_MESH - plot model mesh
@@ -20,6 +20,5 @@
 
 	if is2d:
-		p.subplot(nlines,ncols,i,aspect='equal')
-		p.triplot(x,y,elements)
+		ax.triplot(x,y,elements)
 	else:
 		print 'WARNING: only 2D mesh plot is currently implemented'
@@ -28,3 +27,3 @@
 	options.addfielddefault('title','Mesh')
 	options.addfielddefault('colorbar','off')
-	applyoptions(md,[],options)
+	options.addfielddefault('ticklabels','on')
Index: /issm/trunk/src/m/plot/plot_overlay.py
===================================================================
--- /issm/trunk/src/m/plot/plot_overlay.py	(revision 17988)
+++ /issm/trunk/src/m/plot/plot_overlay.py	(revision 17989)
@@ -2,8 +2,11 @@
 from processmesh import processmesh
 from processdata import processdata
-from osgeo import gdal
 import matplotlib.pyplot as plt
 import matplotlib as mpl
 import os
+try:
+	from osgeo import gdal
+except ImportError:
+	print 'osgeo/gdal for python not installed, plot_overlay is disabled'
 
 def plot_overlay(md,data,options,ax):
@@ -101,3 +104,6 @@
 	norm=mpl.colors.Normalize(vmin=overlaylims[0],vmax=overlaylims[1])
 
-	ax.pcolormesh(xgmap, ygmap, npy.flipud(arr), cmap=mpl.cm.Greys, norm=norm)
+	pc=ax.pcolormesh(xgmap, ygmap, npy.flipud(arr), cmap=mpl.cm.Greys, norm=norm)
+	#rasterization? 
+	if options.getfieldvalue('rasterized',0):
+		pc.set_rasterized(True)
Index: /issm/trunk/src/m/plot/plot_unit.py
===================================================================
--- /issm/trunk/src/m/plot/plot_unit.py	(revision 17988)
+++ /issm/trunk/src/m/plot/plot_unit.py	(revision 17989)
@@ -42,10 +42,13 @@
 	   lims=options.getfieldvalue('caxis',[min(data),max(data)])
 	else:
-	   lims=[min(data),max(data)]
+		if min(data)==max(data):
+			lims=[min(data)-0.5,max(data)+0.5]
+		else:
+			lims=[min(data),max(data)]
 	norm = mpl.colors.Normalize(vmin=lims[0], vmax=lims[1])
 	if datatype==1:
 	   #element plot
 		if is2d:
-			tri=ax.tripcolor(x,y,elements,data,colorlevels,cmap=cmap,edgecolors=edgecolor)
+			tri=ax.tripcolor(x,y,elements,data,colorlevels,cmap=cmap,norm=norm,alpha=alpha,edgecolors=edgecolor)
 		else:
 			raise ValueError('plot_unit error: 3D element plot not supported yet')
@@ -55,5 +58,5 @@
 		#node plot
 		if is2d:
-			tri=ax.tricontourf(x,y,elements,data,colorlevels,cmap=cmap,norm=norm,alpha=alpha)
+			tri=ax.tricontourf(x,y,elements,data,colorlevels,cmap=cmap,norm=norm,alpha=alpha,extend='both')
 			if edgecolor != 'None':
 				ax.triplot(x,y,elements,color=edgecolor)
Index: /issm/trunk/src/m/plot/plotmodel.py
===================================================================
--- /issm/trunk/src/m/plot/plotmodel.py	(revision 17988)
+++ /issm/trunk/src/m/plot/plotmodel.py	(revision 17989)
@@ -42,6 +42,8 @@
 		nc=True
 	else:
-		ncols=subplotwidth
+		ncols=int(subplotwidth)
 		nc=False
+	ncols=int(ncols)
+	nrows=int(nrows)
 	
 	#check that nrows and ncols were given at the same time!
@@ -52,5 +54,5 @@
 	if numberofplots:
 		
-		if not hold: # TODO need to also check whether figurenumber is a new plot so that old plots are not mistakenly cleared
+		if plt.fignum_exists(figurenumber): 
 			plt.cla()
 
@@ -58,27 +60,40 @@
 		if options.list[0].exist('figsize'):
 			figsize=options.list[0].getfieldvalue('figsize')
-			fig=plt.figure(figurenumber,figsize=figsize,tight_layout=True)
+			fig=plt.figure(figurenumber,figsize=(figsize[0],figsize[1]),tight_layout=True)
 		else:
 			fig=plt.figure(figurenumber,tight_layout=True)
 		fig.clf()
-	
-		# options to pass: axes_pad, share_all, label_mode ("1","L","all"), cbar_mode (none,single,each), cbar_location(right,top)
+
+		# options needed to define plot grid
+		direction=options.list[0].getfieldvalue('direction','row') # row,column
+		axes_pad=options.list[0].getfieldvalue('axes_pad',0.25)
+		add_all=options.list[0].getfieldvalue('add_all',True) # True,False
+		share_all=options.list[0].getfieldvalue('share_all',True) # True,False
+		label_mode=options.list[0].getfieldvalue('label_mode','1') # 1,L,all
+		cbar_mode=options.list[0].getfieldvalue('cbar_mode','each') # none,single,each
+		cbar_location=options.list[0].getfieldvalue('cbar_location','right') # right,top
+		cbar_size=options.list[0].getfieldvalue('cbar_size','5%')
+		cbar_pad=options.list[0].getfieldvalue('cbar_pad','2.5%') # None or %
+		
 		axgrid=ImageGrid(fig, 111,
 				nrows_ncols=(nrows,ncols),
-				direction='row',
-				axes_pad=0.05,
-				add_all=True,
-				share_all=True,
-				label_mode='all',
-				cbar_mode='single',
-				cbar_location='right',
-				cbar_size='5%',
-				cbar_pad=0.05
+				direction=direction,
+				axes_pad=axes_pad,
+				add_all=add_all,
+				share_all=share_all,
+				label_mode=label_mode,
+				cbar_mode=cbar_mode,
+				cbar_location=cbar_location,
+				cbar_size=cbar_size,
+				cbar_pad=cbar_pad
 				)
+
+		if cbar_mode=='none':
+			for ax in axgrid.cbar_axes: fig._axstack.remove(ax)
 
 		for i in xrange(numberofplots):
 			plot_manager(options.list[i].getfieldvalue('model',md),options.list[i],fig,axgrid[i])
 
-		plt.show()
+		fig.show()
 	else:
 		raise StandardError('plotmodel error message: no output data found.')
Index: /issm/trunk/src/m/plot/processdata.py
===================================================================
--- /issm/trunk/src/m/plot/processdata.py	(revision 17988)
+++ /issm/trunk/src/m/plot/processdata.py	(revision 17989)
@@ -45,8 +45,14 @@
 	nanfill=options.getfieldvalue('nan',-9999)
 	if npy.any(npy.isnan(procdata)):
+		lb=npy.min(data[~npy.isnan(data)])
+		ub=npy.max(data[~npy.isnan(data)])
+		if lb==ub:
+			lb=lb-0.5
+			ub=ub+0.5
+			nanfill=lb-1
 		procdata[npy.isnan(procdata)]=nanfill
+		options.addfielddefault('clim',[lb,ub])
 		options.addfielddefault('cmap_set_under','1')
-		options.addfielddefault('clim',[min(data),max(data)])
-		print "WARNING: nan's treated as -9999 by default.  Change using pairoption 'nan',nan_fill_value in plotmodel call"
+		print "WARNING: nan's treated as", nanfill, "by default.  Change using pairoption 'nan',nan_fill_value in plotmodel call"
 
 	#non-patch processing 
Index: /issm/trunk/src/m/qmu/setupdesign/IsScaled.m
===================================================================
--- /issm/trunk/src/m/qmu/setupdesign/IsScaled.m	(revision 17988)
+++ /issm/trunk/src/m/qmu/setupdesign/IsScaled.m	(revision 17989)
@@ -3,5 +3,5 @@
 
 switch variablename,
-case {'MaterialsRhoIce','MaterialsRhoWater','MaterialsHeatCapacity','MaterialsThermalConductivity','Gravity','MaxVel'},
+case {'MaterialsRhoIce','MaterialsRhoSeawater','MaterialsHeatCapacity','MaterialsThermalConductivity','Gravity','MaxVel'},
 
 	status=0;
Index: /issm/trunk/src/m/solve/WriteData.m
===================================================================
--- /issm/trunk/src/m/solve/WriteData.m	(revision 17988)
+++ /issm/trunk/src/m/solve/WriteData.m	(revision 17989)
@@ -14,6 +14,9 @@
 	fieldname = getfieldvalue(options,'fieldname');
 	classname = getfieldvalue(options,'class',class(obj));
-
-	enum      = BuildEnum([classname '_' fieldname]);
+	if exist(options,'enum'),
+		enum = getfieldvalue(options,'enum');
+	else
+		enum = BuildEnum([classname '_' fieldname]);
+	end
 	data      = obj.(fieldname);
 else
Index: /issm/trunk/src/m/solve/WriteData.py
===================================================================
--- /issm/trunk/src/m/solve/WriteData.py	(revision 17988)
+++ /issm/trunk/src/m/solve/WriteData.py	(revision 17989)
@@ -24,6 +24,8 @@
 		fieldname = options.getfieldvalue('fieldname')
 		classname = options.getfieldvalue('class',str(type(obj)).rsplit('.')[-1].split("'")[0])
-
-		enum      = BuildEnum(classname+'_'+fieldname)
+		if options.exist('enum'):
+			enum = options.getfieldvalue('enum')
+		else:
+			enum = BuildEnum(classname+'_'+fieldname)
 		data      = getattr(obj,fieldname)
 	else:
Index: /issm/trunk/src/wrappers/IssmConfig/IssmConfig.cpp
===================================================================
--- /issm/trunk/src/wrappers/IssmConfig/IssmConfig.cpp	(revision 17988)
+++ /issm/trunk/src/wrappers/IssmConfig/IssmConfig.cpp	(revision 17989)
@@ -37,6 +37,4 @@
 		#ifdef _HAVE_MPI_
 		value = 1.;
-		#else
-		value = 0.;
 		#endif
 	}
@@ -44,6 +42,4 @@
 		#ifdef _HAVE_DAKOTA_
 		value = 1.;
-		#else
-		value = 0.;
 		#endif
 	}
@@ -51,6 +47,4 @@
 		#ifdef _HAVE_MUMPS_
 		value = 1.;
-		#else
-		value = 0.;
 		#endif
 	}
@@ -58,6 +52,4 @@
 		#ifdef _HAVE_GSL_
 		value = 1.;
-		#else
-		value = 0.;
 		#endif
 	}
@@ -65,6 +57,9 @@
 		#ifdef _HAVE_TAO_
 		value = 1.;
-		#else
-		value = 0.;
+		#endif
+	}
+	else if(strcmp(name,"_HAVE_M1QN3_")==0){
+		#ifdef _HAVE_M1QN3_
+		value = 1.;
 		#endif
 	}
@@ -72,6 +67,4 @@
 		#ifdef _HAVE_PETSC_
 		value = 1.;
-		#else
-		value = 0.;
 		#endif
 	}
Index: /issm/trunk/test/NightlyRun/IdToName.m
===================================================================
--- /issm/trunk/test/NightlyRun/IdToName.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/IdToName.m	(revision 17989)
@@ -132,7 +132,7 @@
 	case 422, name='SquareSheetShelfStressSSAFS3dTiling';
 	case 423, name='RoundSheetShelfGLMigrationSSA2d';
-	case 424, name='SquareSheetShelfGroundingLine2dAgressive';
+	case 424, name='SquareSheetShelfGroundingLine2dAggressive';
 	case 425, name='SquareSheetShelfGroundingLine2dSoft';
-	case 426, name='SquareSheetShelfGroundingLine3dAgressive';
+	case 426, name='SquareSheetShelfGroundingLine3dAggressive';
 	case 427, name='SquareSheetShelfGroundingLine3dSoft';
 	case 428, name='SquareSheetShelfStressSSA2dNewton';
Index: /issm/trunk/test/NightlyRun/IdToName.py
===================================================================
--- /issm/trunk/test/NightlyRun/IdToName.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/IdToName.py	(revision 17989)
@@ -131,7 +131,7 @@
 	422  : 'SquareSheetShelfStressSSAFS3dTiling',
 	423  : 'RoundSheetShelfGLMigrationSSA2d',
-	424  : 'SquareSheetShelfGroundingLine2dAgressive',
+	424  : 'SquareSheetShelfGroundingLine2dAggressive',
 	425  : 'SquareSheetShelfGroundingLine2dSoft',
-	426  : 'SquareSheetShelfGroundingLine3dAgressive',
+	426  : 'SquareSheetShelfGroundingLine3dAggressive',
 	427  : 'SquareSheetShelfGroundingLine3dSoft',
 	428  : 'SquareSheetShelfStressSSA2dNewton',
Index: /issm/trunk/test/NightlyRun/test1101.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1101.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1101.m	(revision 17989)
@@ -3,5 +3,6 @@
 printingflag=false;
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 minvx=[];
@@ -112,21 +113,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',... 
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-09,1e-09,1e-09,...
-	1e-10,1e-10,1e-09,...
-	1e-09,1e-09,1e-09,...
-	1e-09,1e-08,1e-08,...
 	1e-08,1e-08,1e-08,...
-	1e-08,1e-07,1e-08,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1102.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1102.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1102.m	(revision 17989)
@@ -3,5 +3,6 @@
 printingflag=false;
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 minvx=[];
@@ -122,21 +123,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-12,1e-12,1e-12,...
-	1e-12,1e-12,1e-12,...
-	1e-12,1e-11,1e-12,...
-	1e-12,1e-11,1e-12,...
-	1e-12,1e-11,1e-12,...
 	1e-12,1e-11,1e-12,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1103.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1103.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1103.m	(revision 17989)
@@ -3,5 +3,6 @@
 printingflag=false;
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 minvx=[];
@@ -105,21 +106,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-09,1e-09,1e-09,...
-	1e-09,1e-09,1e-09,...
-	1e-09,1e-09,1e-09,...
-	1e-08,1e-08,1e-08,...
 	1e-08,1e-07,1e-07,...
-	1e-07,1e-06,1e-07,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1104.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1104.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1104.m	(revision 17989)
@@ -2,5 +2,6 @@
 %Pattyn and Payne 2006
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 
@@ -56,21 +57,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-08,1e-08,1e-08,...
-	1e-08,1e-08,1e-08,...
-	1e-08,1e-08,1e-08,...
-	1e-08,1e-08,1e-08,...
 	1e-08,1e-07,1e-08,...
-	1e-07,1e-07,1e-07,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1105.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1105.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1105.m	(revision 17989)
@@ -3,5 +3,6 @@
 printingflag=false;
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 minvx=[];
@@ -135,21 +136,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-08,1e-07,1e-07,...
-	1e-09,1e-07,1e-07,...
-	1e-09,1e-09,1e-07,...
-	1e-09,1e-09,1e-08,...
 	1e-09,1e-08,1e-08,...
-	1e-08,1e-08,1e-08,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1106.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1106.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1106.m	(revision 17989)
@@ -2,5 +2,6 @@
 %Pattyn and Payne 2006
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 
@@ -54,21 +55,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-12,1e-12,1e-11,...
-	1e-12,2e-12,2e-12,...
-	1e-12,1e-12,1e-12,...
-	1e-12,2e-12,2e-12,...
 	1e-11,2e-12,3e-12,...
-	1e-11,2e-11,2e-12,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1107.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1107.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1107.m	(revision 17989)
@@ -3,5 +3,6 @@
 printingflag=false;
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 minvx=[];
@@ -124,21 +125,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-07,1e-08,1e-06,...
-	1e-08,1e-08,1e-06,...
 	1e-08,1e-08,1e-07,...
-	1e-08,1e-08,1e-07,...
-	1e-08,1e-08,1e-07,...
-	1e-07,1e-08,1e-06,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test1108.m
===================================================================
--- /issm/trunk/test/NightlyRun/test1108.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test1108.m	(revision 17989)
@@ -2,5 +2,6 @@
 %Pattyn and Payne 2006
 
-L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+%L_list={5000.,10000.,20000.,40000.,80000.,160000.};
+L_list={80000.};
 results={};
 
@@ -63,21 +64,11 @@
 %Fields and tolerances to track changes
 field_names     ={...
-	'Vx5km','Vy5km','Vz5km',...
-	'Vx10km','Vy10km','Vz10km',...
-	'Vx20km','Vy20km','Vz20km',...
-	'Vx40km','Vy40km','Vz40km',...
-	'Vx80km','Vy80km','Vz80km',...
-	'Vx160km','Vy160km','Vz160km'
+	'Vx80km','Vy80km','Vz80km'
 };
 field_tolerances={...
-	1e-07,1e-07,1e-07,...
-	1e-08,2e-08,1e-08,...
 	1e-08,1e-07,1e-07,...
-	1e-08,1e-08,2e-08,...
-	1e-08,1e-07,1e-07,...
-	1e-07,1e-06,1e-07,...
 };
 field_values={};
-for i=1:6,
+for i=1:1,
 	result=results{i};
 	field_values={field_values{:},...
Index: /issm/trunk/test/NightlyRun/test211.m
===================================================================
--- /issm/trunk/test/NightlyRun/test211.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test211.m	(revision 17989)
@@ -15,6 +15,6 @@
 field_tolerances={...
 	2e-08,2e-08,1e-06,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,...
-	5e-08,3e-08,1e-06,3e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06,...
-	1e-07,1e-07,1e-05,5e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06};
+	5e-07,5e-07,5e-05,1e-07,1e-08,1e-08,1e-08,1e-08,5e-08,2e-06,...
+	5e-06,5e-06,5e-05,5e-06,5e-07,5e-07,5e-07,1e-07,1e-06,5e-05};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
Index: /issm/trunk/test/NightlyRun/test211.py
===================================================================
--- /issm/trunk/test/NightlyRun/test211.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test211.py	(revision 17989)
@@ -28,6 +28,6 @@
 field_tolerances=[\
 	2e-08,2e-08,1e-06,2e-08,1e-08,1e-08,1e-08,1e-08,1e-08,1e-08,\
-	5e-08,3e-08,1e-06,3e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06,\
-	1e-07,1e-07,1e-05,5e-08,1e-08,1e-08,1e-08,1e-08,2e-08,2e-06]
+	5e-07,5e-07,5e-05,1e-07,1e-08,1e-08,1e-08,1e-08,5e-08,2e-06,\
+	5e-06,5e-06,5e-05,5e-06,1e-07,5e-07,5e-07,5e-07,1e-06,5e-05]
 field_values=[\
 	md.results.TransientSolution[0].Vx,\
Index: /issm/trunk/test/NightlyRun/test220.m
===================================================================
--- /issm/trunk/test/NightlyRun/test220.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test220.m	(revision 17989)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={1e-09,1e-09,1e-06,1e-09,1e-09};
+field_tolerances={1e-09,1e-09,5e-06,1e-09,1e-09};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test220.py
===================================================================
--- /issm/trunk/test/NightlyRun/test220.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test220.py	(revision 17989)
@@ -21,5 +21,5 @@
 
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[1e-09,1e-09,1e-06,1e-09,1e-09]
+field_tolerances=[1e-09,1e-09,5e-06,1e-09,1e-09]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test271.py
===================================================================
--- /issm/trunk/test/NightlyRun/test271.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test271.py	(revision 17989)
@@ -22,5 +22,5 @@
 md.damage.stabilization=1;
 
-pos=numpy.nonzero(numpy.logical_and(md.mask.ice_levelset[:,0]!=0,md.mesh.vertexonboundary==1))
+pos=numpy.nonzero(numpy.logical_and(md.mask.ice_levelset!=0,md.mesh.vertexonboundary==1))
 md.damage.spcdamage[pos]=0.5;
 
Index: /issm/trunk/test/NightlyRun/test274.m
===================================================================
--- /issm/trunk/test/NightlyRun/test274.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test274.m	(revision 17989)
@@ -14,5 +14,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure'};
-field_tolerances={5.0e-8,2.0e-8,2.0e-8,1e-11};
+field_tolerances={7e-8,3e-8,3e-8,1e-11};
 field_values={...
 	   (md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test274.py
===================================================================
--- /issm/trunk/test/NightlyRun/test274.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test274.py	(revision 17989)
@@ -27,5 +27,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vel','Pressure']
-field_tolerances=[4.5e-8,1.35e-8,1.55e-8,1e-11]
+field_tolerances=[7e-8,3e-8,3e-8,1e-11]
 field_values=[\
 	   md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test285.m
===================================================================
--- /issm/trunk/test/NightlyRun/test285.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test285.m	(revision 17989)
@@ -13,5 +13,5 @@
 	md=solve(md,StressbalanceSolutionEnum());
 	field_names     ={field_names{:},['Vx' i{1}],['Vy' i{1}],['Vz' i{1}],['Vel' i{1}],['Pressure' i{1}]};
-	field_tolerances={field_tolerances{:},6e-08,4e-08,2e-08,4e-08,1e-13};
+	field_tolerances={field_tolerances{:},6e-08,5e-08,2e-08,5e-08,1e-13};
 	field_values={field_values{:},...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test285.py
===================================================================
--- /issm/trunk/test/NightlyRun/test285.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test285.py	(revision 17989)
@@ -23,5 +23,5 @@
 	md=solve(md,StressbalanceSolutionEnum())
 	field_names     =field_names+['Vx'+i,'Vy'+i,'Vz'+i,'Vel'+i,'Pressure'+i]
-	field_tolerances=field_tolerances+[6e-08,4e-08,2e-08,4e-08,1e-13]
+	field_tolerances=field_tolerances+[6e-08,5e-08,2e-08,5e-08,1e-13]
 	field_values=field_values+[\
 		md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test3001.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3001.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test3001.m	(revision 17989)
@@ -4,5 +4,5 @@
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',1);
-md.stressbalance.requested_outputs={'default','StressTensorxx','StressTensoryy','StressTensorxy'};
+md.stressbalance.requested_outputs={'default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy'};
 md.autodiff.isautodiff=true;
 md.toolkits.DefaultAnalysis=issmgslsolver();
@@ -12,5 +12,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure',...
-	'StressTensorxx','StressTensoryy','StressTensorxy'};
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy'};
 field_tolerances={1e-13,1e-13,1e-13,1e-13,...
 	1e-13,1e-13,1e-13};
@@ -20,6 +20,6 @@
 	(md.results.StressbalanceSolution.Vel),...
 	(md.results.StressbalanceSolution.Pressure),...
-	(md.results.StressbalanceSolution.StressTensorxx),...
-	(md.results.StressbalanceSolution.StressTensoryy),...
-	(md.results.StressbalanceSolution.StressTensorxy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxx),...
+	(md.results.StressbalanceSolution.DeviatoricStressyy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxy),...
 	};
Index: /issm/trunk/test/NightlyRun/test3001.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3001.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test3001.py	(revision 17989)
@@ -13,5 +13,5 @@
 md=setflowequation(md,'SSA','all')
 md.cluster=generic('name',oshostname(),'np',1)
-md.stressbalance.requested_outputs=['default','StressTensorxx','StressTensoryy','StressTensorxy']
+md.stressbalance.requested_outputs=['default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy']
 md.toolkits.DefaultAnalysis=issmgslsolver()
 md.autodiff.isautodiff=True
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vel','Pressure',\
-	'StressTensorxx','StressTensoryy','StressTensorxy']
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy']
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,\
 	1e-13,1e-13,1e-13]
@@ -28,6 +28,6 @@
 	md.results.StressbalanceSolution.Vel,\
 	md.results.StressbalanceSolution.Pressure,\
-	md.results.StressbalanceSolution.StressTensorxx,\
-	md.results.StressbalanceSolution.StressTensoryy,\
-	md.results.StressbalanceSolution.StressTensorxy,\
+	md.results.StressbalanceSolution.DeviatoricStressxx,\
+	md.results.StressbalanceSolution.DeviatoricStressyy,\
+	md.results.StressbalanceSolution.DeviatoricStressxy,\
 	]
Index: /issm/trunk/test/NightlyRun/test3101.m
===================================================================
--- /issm/trunk/test/NightlyRun/test3101.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test3101.m	(revision 17989)
@@ -4,5 +4,5 @@
 md=setflowequation(md,'SSA','all');
 md.cluster=generic('name',oshostname(),'np',3);
-md.stressbalance.requested_outputs={'default','StressTensorxx','StressTensoryy','StressTensorxy'};
+md.stressbalance.requested_outputs={'default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy'};
 md.autodiff.isautodiff=true;
 md.toolkits.DefaultAnalysis=issmmumpssolver();
@@ -12,5 +12,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vel','Pressure',...
-	'StressTensorxx','StressTensoryy','StressTensorxy'};
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy'};
 field_tolerances={1e-13,1e-13,1e-13,1e-13,...
 	1e-13,1e-13,1e-13};
@@ -20,6 +20,6 @@
 	(md.results.StressbalanceSolution.Vel),...
 	(md.results.StressbalanceSolution.Pressure),...
-	(md.results.StressbalanceSolution.StressTensorxx),...
-	(md.results.StressbalanceSolution.StressTensoryy),...
-	(md.results.StressbalanceSolution.StressTensorxy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxx),...
+	(md.results.StressbalanceSolution.DeviatoricStressyy),...
+	(md.results.StressbalanceSolution.DeviatoricStressxy),...
 	};
Index: /issm/trunk/test/NightlyRun/test3101.py
===================================================================
--- /issm/trunk/test/NightlyRun/test3101.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test3101.py	(revision 17989)
@@ -13,5 +13,5 @@
 md=setflowequation(md,'SSA','all')
 md.cluster=generic('name',oshostname(),'np',3)
-md.stressbalance.requested_outputs=['StressTensor']
+md.stressbalance.requested_outputs=['default','DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy']
 md.toolkits.DefaultAnalysis=issmmumpssolver()
 md.autodiff.isautodiff=True
@@ -20,5 +20,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vel','Pressure',\
-	'StressTensorxx','StressTensoryy','StressTensorxy']
+	'DeviatoricStressxx','DeviatoricStressyy','DeviatoricStressxy']
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,\
 	1e-13,1e-13,1e-13]
@@ -28,6 +28,6 @@
 	md.results.StressbalanceSolution.Vel,\
 	md.results.StressbalanceSolution.Pressure,\
-	md.results.StressbalanceSolution.StressTensorxx,\
-	md.results.StressbalanceSolution.StressTensoryy,\
-	md.results.StressbalanceSolution.StressTensorxy,\
+	md.results.StressbalanceSolution.DeviatoricStressxx,\
+	md.results.StressbalanceSolution.DeviatoricStressyy,\
+	md.results.StressbalanceSolution.DeviatoricStressxy,\
 	]
Index: /issm/trunk/test/NightlyRun/test315.m
===================================================================
--- /issm/trunk/test/NightlyRun/test315.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test315.m	(revision 17989)
@@ -13,5 +13,5 @@
 field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...,
 	1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
-	1e-10,1.5e-13,1.5e-13,1.5e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
+	1e-10,2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
Index: /issm/trunk/test/NightlyRun/test315.py
===================================================================
--- /issm/trunk/test/NightlyRun/test315.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test315.py	(revision 17989)
@@ -22,5 +22,5 @@
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
 	1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
-	1e-10,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
+	1e-10,2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13]
 field_values=[\
 	md.results.TransientSolution[0].Vx,\
Index: /issm/trunk/test/NightlyRun/test322.m
===================================================================
--- /issm/trunk/test/NightlyRun/test322.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test322.m	(revision 17989)
@@ -23,5 +23,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy'};
-field_tolerances={1e-05,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,2e-09,2e-09,2e-09};
+field_tolerances={5e-05,1e-08,1e-09,1e-09,1e-09,1e-09,1e-09,5e-08,5e-08,5e-08};
 field_values={...
 	(md.results.StressbalanceSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test322.py
===================================================================
--- /issm/trunk/test/NightlyRun/test322.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test322.py	(revision 17989)
@@ -35,5 +35,5 @@
 #Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy']
-field_tolerances=[1e-05,1e-08,1e-09,1e-09,2e-09,2e-09,2e-09]
+field_tolerances=[5e-05,1e-08,1e-09,1e-09,5e-08,5e-08,5e-08]
 field_values=[\
 	md.results.StressbalanceSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test404.m
===================================================================
--- /issm/trunk/test/NightlyRun/test404.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test404.m	(revision 17989)
@@ -9,5 +9,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Vx','Vy','Vz','Vel','Pressure'};
-field_tolerances={2e-07,2e-07,2e-06,1e-06,1e-07};
+field_tolerances={5e-07,5e-07,2e-06,1e-06,1e-07};
 field_values={...
 	(md.results.StressbalanceSolution.Vx),...
Index: /issm/trunk/test/NightlyRun/test404.py
===================================================================
--- /issm/trunk/test/NightlyRun/test404.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test404.py	(revision 17989)
@@ -19,5 +19,5 @@
 #Fields and tolerances to track changes
 field_names     =['Vx','Vy','Vz','Vel','Pressure']
-field_tolerances=[2e-07,2e-07,2e-06,1e-06,1e-07]
+field_tolerances=[5e-07,4e-07,2e-06,1e-06,1e-07]
 field_values=[\
 	md.results.StressbalanceSolution.Vx,\
Index: /issm/trunk/test/NightlyRun/test423.m
===================================================================
--- /issm/trunk/test/NightlyRun/test423.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test423.m	(revision 17989)
@@ -24,5 +24,5 @@
 
 %test different grounding line dynamics.
-md.groundingline.migration='AgressiveMigration';
+md.groundingline.migration='AggressiveMigration';
 md=solve(md,TransientSolutionEnum());
 element_on_iceshelf_agressive=(md.results.TransientSolution.MaskGroundediceLevelset);
@@ -46,5 +46,5 @@
 
 %Fields and tolerances to track changes
-field_names     ={'ElementOnIceShelfAgressive','VelAgressive','ElementOnIceShelfSoft','VelSoft','ElementOnIceShelfSubelement','VelSubelement','ElementOnIceShelfSubelement2','VelSubelement2'};
+field_names     ={'ElementOnIceShelfAggressive','VelAggressive','ElementOnIceShelfSoft','VelSoft','ElementOnIceShelfSubelement','VelSubelement','ElementOnIceShelfSubelement2','VelSubelement2'};
 field_tolerances={1e-13,2e-12,1e-13,2e-12,1e-13,3e-12,1e-13,2e-12};
 field_values={element_on_iceshelf_agressive,vel_agressive,element_on_iceshelf_soft,vel_soft,element_on_iceshelf_subelement,vel_subelement,element_on_iceshelf_subelement2,vel_subelement2};
Index: /issm/trunk/test/NightlyRun/test423.py
===================================================================
--- /issm/trunk/test/NightlyRun/test423.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test423.py	(revision 17989)
@@ -35,5 +35,5 @@
 
 #test different grounding line dynamics.
-md.groundingline.migration='AgressiveMigration'
+md.groundingline.migration='AggressiveMigration'
 md=solve(md,TransientSolutionEnum())
 element_on_iceshelf_agressive=md.results.TransientSolution[0].MaskGroundediceLevelset
@@ -57,5 +57,5 @@
 
 #Fields and tolerances to track changes
-field_names     =['ElementOnIceShelfAgressive','VelAgressive','ElementOnIceShelfSoft','VelSoft','ElementOnIceShelfSubelement','VelSubelement','ElementOnIceShelfSubelement2','VelSubelement2']
+field_names     =['ElementOnIceShelfAggressive','VelAggressive','ElementOnIceShelfSoft','VelSoft','ElementOnIceShelfSubelement','VelSubelement','ElementOnIceShelfSubelement2','VelSubelement2']
 field_tolerances=[1e-13,2e-13,1e-13,2e-13,1e-13,2e-13,1e-13,2e-13]
 field_values=[element_on_iceshelf_agressive,vel_agressive,element_on_iceshelf_soft,vel_soft,element_on_iceshelf_subelement,vel_subelement,element_on_iceshelf_subelement2,vel_subelement2]
Index: /issm/trunk/test/NightlyRun/test424.m
===================================================================
--- /issm/trunk/test/NightlyRun/test424.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test424.m	(revision 17989)
@@ -12,5 +12,5 @@
 md.transient.isstressbalance=0;
 md.transient.isgroundingline=1;
-md.groundingline.migration='AgressiveMigration';
+md.groundingline.migration='AggressiveMigration';
 md.transient.requested_outputs={'IceVolume','IceVolumeAboveFloatation'};
 
Index: /issm/trunk/test/NightlyRun/test424.py
===================================================================
--- /issm/trunk/test/NightlyRun/test424.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test424.py	(revision 17989)
@@ -22,5 +22,5 @@
 md.transient.isstressbalance=False
 md.transient.isgroundingline=True
-md.groundingline.migration='AgressiveMigration'
+md.groundingline.migration='AggressiveMigration'
 md.transient.requested_outputs=['IceVolume','IceVolumeAboveFloatation']
 
Index: /issm/trunk/test/NightlyRun/test426.m
===================================================================
--- /issm/trunk/test/NightlyRun/test426.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test426.m	(revision 17989)
@@ -13,5 +13,5 @@
 md.transient.isstressbalance=0;
 md.transient.isgroundingline=1;
-md.groundingline.migration='AgressiveMigration';
+md.groundingline.migration='AggressiveMigration';
 md.transient.requested_outputs={'IceVolume','IceVolumeAboveFloatation'};
 md.cluster=generic('name',oshostname(),'np',3);
Index: /issm/trunk/test/NightlyRun/test426.py
===================================================================
--- /issm/trunk/test/NightlyRun/test426.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test426.py	(revision 17989)
@@ -23,5 +23,5 @@
 md.transient.isstressbalance=False
 md.transient.isgroundingline=True
-md.groundingline.migration='AgressiveMigration'
+md.groundingline.migration='AggressiveMigration'
 md.transient.requested_outputs=['IceVolume','IceVolumeAboveFloatation']
 md.cluster=generic('name',oshostname(),'np',3)
Index: /issm/trunk/test/NightlyRun/test427.m
===================================================================
--- /issm/trunk/test/NightlyRun/test427.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test427.m	(revision 17989)
@@ -24,5 +24,5 @@
 field_tolerances={1e-13,1e-13,1e-13,1e-13,...
 	5e-12,3e-12,7e-12,2e-11,...
-	1e-10,3e-11,1e-10,7e-11};
+	1e-10,5e-11,1e-10,7e-10};
 field_values={...
 	(md.results.TransientSolution(1).Base),...
Index: /issm/trunk/test/NightlyRun/test427.py
===================================================================
--- /issm/trunk/test/NightlyRun/test427.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test427.py	(revision 17989)
@@ -34,5 +34,5 @@
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,\
 	5e-12,3e-12,7e-12,2e-11,\
-	1e-10,1e-11,1e-10,1e-13]
+	1e-10,5e-11,1e-10,7e-10]
 field_values=[\
 	md.results.TransientSolution[0].Base,\
Index: /issm/trunk/test/NightlyRun/test433.m
===================================================================
--- /issm/trunk/test/NightlyRun/test433.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test433.m	(revision 17989)
@@ -25,5 +25,5 @@
 
 %test different grounding line dynamics.
-md.groundingline.migration='AgressiveMigration';
+md.groundingline.migration='AggressiveMigration';
 md=solve(md,TransientSolutionEnum());
 element_on_iceshelf_agressive=(md.results.TransientSolution.MaskGroundediceLevelset);
@@ -42,5 +42,5 @@
 
 %Fields and tolerances to track changes
-field_names     ={'ElementOnIceShelfAgressive','ElementOnIceShelfSoft','ElementOnIceShelfSubelement','ElementOnIceShelfSubelement'};
+field_names     ={'ElementOnIceShelfAggressive','ElementOnIceShelfSoft','ElementOnIceShelfSubelement','ElementOnIceShelfSubelement'};
 field_tolerances={1e-13,1e-13,1e-13,1e-13};
 field_values={element_on_iceshelf_agressive,element_on_iceshelf_soft,element_on_iceshelf_subelement,element_on_iceshelf_subelement2};
Index: /issm/trunk/test/NightlyRun/test433.py
===================================================================
--- /issm/trunk/test/NightlyRun/test433.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test433.py	(revision 17989)
@@ -36,5 +36,5 @@
 
 #test different grounding line dynamics.
-md.groundingline.migration='AgressiveMigration'
+md.groundingline.migration='AggressiveMigration'
 md=solve(md,TransientSolutionEnum())
 element_on_iceshelf_agressive=md.results.TransientSolution[0].MaskGroundediceLevelset
@@ -49,5 +49,5 @@
 
 #Fields and tolerances to track changes
-field_names     =['ElementOnIceShelfAgressive','ElementOnIceShelfSoft','ElementOnIceShelfSubelement']
+field_names     =['ElementOnIceShelfAggressive','ElementOnIceShelfSoft','ElementOnIceShelfSubelement']
 field_tolerances=[1e-13,1e-13,1e-13]
 field_values=[element_on_iceshelf_agressive,element_on_iceshelf_soft,element_on_iceshelf_subelement]
Index: /issm/trunk/test/NightlyRun/test435.m
===================================================================
--- /issm/trunk/test/NightlyRun/test435.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test435.m	(revision 17989)
@@ -48,6 +48,6 @@
 	'Bed3','Surface3','Thickness3','Floatingice3','Vx3','Vy3','Vz3','Pressure3'};
 field_tolerances={2e-11,5e-12,2e-11,1e-11,4e-10,1e-08,6e-10,1e-13,...
-	3e-11,3e-11,9e-10,7e-11,1e-09,1e-08,1e-09,1e-10,...
-	1e-10,3e-11,1e-10,7e-11,1e-09,1e-08,1e-09,1e-10};
+	3e-11,3e-11,9e-10,7e-11,1e-09,5e-08,1e-09,1e-10,...
+	1e-10,3e-11,1e-10,7e-11,1e-09,5e-08,1e-09,1e-10};
 field_values={...
 	(md.results.TransientSolution(1).Base),...
Index: /issm/trunk/test/NightlyRun/test511.m
===================================================================
--- /issm/trunk/test/NightlyRun/test511.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test511.m	(revision 17989)
@@ -28,5 +28,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','MaterialsRheologyB','Pressure','Vel','Vx','Vy'};
-field_tolerances={1e-11,5e-12,1e-11,1e-09,2e-12,1e-11,1e-11};
+field_tolerances={5e-11,5e-11,5e-11,1e-09,1e-11,5e-11,1e-11};
 field_values={...
 	(md.results.StressbalanceSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test511.py
===================================================================
--- /issm/trunk/test/NightlyRun/test511.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test511.py	(revision 17989)
@@ -39,5 +39,5 @@
 #Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','MaterialsRheologyB','Pressure','Vel','Vx','Vy']
-field_tolerances=[1e-11,5e-12,1e-11,1e-09,2e-12,1e-11,1e-11]
+field_tolerances=[5e-11,5e-11,5e-11,1e-09,1e-11,5e-11,1e-11]
 field_values=[\
 	md.results.StressbalanceSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test513.m
===================================================================
--- /issm/trunk/test/NightlyRun/test513.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test513.m	(revision 17989)
@@ -25,5 +25,5 @@
 %Fields and tolerances to track changes
 field_names     ={'Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy','Vz','Temperature','BasalforcingsMeltingRate'};
-field_tolerances={2e-10,2e-10,1e-10,1e-10,2e-6,1e-6,2e-6,2e-6,2e-6,2e-06};
+field_tolerances={2e-10,2e-10,1e-10,1e-10,3e-6,3e-6,3e-6,3e-6,2e-6,2e-06};
 field_values={...
 	(md.results.SteadystateSolution.Gradient1),...
Index: /issm/trunk/test/NightlyRun/test513.py
===================================================================
--- /issm/trunk/test/NightlyRun/test513.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test513.py	(revision 17989)
@@ -36,5 +36,5 @@
 # Fields and tolerances to track changes
 field_names     =['Gradient','Misfits','FrictionCoefficient','Pressure','Vel','Vx','Vy','Vz','Temperature','BasalforcingsMeltingRate']
-field_tolerances=[2e-10,2e-10,1e-10,1e-10,2e-6,1e-6,2e-6,2e-6,2e-6,2e-06]
+field_tolerances=[2e-10,2e-10,1e-10,1e-10,3e-6,3e-6,3e-6,3e-6,2e-6,2e-06]
 field_values=[\
 	md.results.SteadystateSolution.Gradient1,\
Index: /issm/trunk/test/NightlyRun/test703.m
===================================================================
--- /issm/trunk/test/NightlyRun/test703.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test703.m	(revision 17989)
@@ -72,10 +72,10 @@
 	'Vx3_damp','Vy3_damp','Vel3_damp','Pressure3_damp','Bed3_damp','Surface3_damp','Thickness3_damp'};
 field_tolerances={...
-	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
-	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
-	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
-	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
-	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10,...
-	1e-08,1e-08,1e-08,1e-08,1e-10,1e-10,1e-10};
+	2e-08,2e-08,2e-08,1e-08,1e-10,1e-10,1e-10,...
+	2e-08,2e-08,2e-08,1e-08,1e-10,1e-10,1e-10,...
+	2e-08,2e-08,2e-08,1e-08,1e-10,1e-10,1e-10,...
+	5e-08,5e-08,5e-08,1e-08,1e-10,1e-10,1e-10,...
+	5e-08,5e-08,5e-08,1e-08,1e-10,1e-10,1e-10,...
+	5e-08,5e-08,5e-08,1e-08,1e-10,1e-10,1e-10};
 field_values={...
 	(md.results.TransientSolution(1).Vx),...
Index: /issm/trunk/test/NightlyRun/test804.m
===================================================================
--- /issm/trunk/test/NightlyRun/test804.m	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test804.m	(revision 17989)
@@ -22,5 +22,5 @@
 		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3'};
 field_tolerances={1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
-		1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,...
+		2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13,...
 		2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13};
 field_values={...
Index: /issm/trunk/test/NightlyRun/test804.py
===================================================================
--- /issm/trunk/test/NightlyRun/test804.py	(revision 17988)
+++ /issm/trunk/test/NightlyRun/test804.py	(revision 17989)
@@ -32,5 +32,5 @@
 		'Vx3','Vy3','Vel3','Pressure3','Thickness3','Surface3','MaskIceLevelset3']
 field_tolerances=[1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
-		1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,1e-13,\
+		2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13,\
 		2e-13,2e-13,2e-13,1e-13,1e-13,1e-13,1e-13]
 field_values=[\
Index: /issm/trunk/test/Par/RoundSheetShelf.py
===================================================================
--- /issm/trunk/test/Par/RoundSheetShelf.py	(revision 17988)
+++ /issm/trunk/test/Par/RoundSheetShelf.py	(revision 17989)
@@ -102,5 +102,5 @@
 
 #bathymetry and grounding line migration:
-md.groundingline.migration='AgressiveMigration'
+md.groundingline.migration='AggressiveMigration'
 md.geometry.bed=copy.deepcopy(md.geometry.base)
 pos=numpy.nonzero(md.mask.groundedice_levelset<0.)[0]
