Index: /issm/trunk-jpl/src/c/analyses/EnthalpyAnalysis.cpp
===================================================================
--- /issm/trunk-jpl/src/c/analyses/EnthalpyAnalysis.cpp	(revision 21720)
+++ /issm/trunk-jpl/src/c/analyses/EnthalpyAnalysis.cpp	(revision 21721)
@@ -5,4 +5,5 @@
 #include "../modules/modules.h"
 #include "../solutionsequences/solutionsequences.h"
+#include "../cores/cores.h"
 
 /*Model processing*/
@@ -980,112 +981,124 @@
 void           EnthalpyAnalysis::DrainWaterfraction(FemModel* femmodel){/*{{{*/
 	/*Drain excess water fraction in ice column: */
-	for(int i=0;i<femmodel->elements->Size();i++){
-		Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
-		DrainWaterfractionIcecolumn(element);
-	}
-}/*}}}*/
-void           EnthalpyAnalysis::DrainWaterfraction(Element* element, IssmDouble* pdrainrate_element){/*{{{*/
-
-	/* Check if ice in element */
-	if(!element->IsIceInElement()) return;
-
-	/*Intermediaries*/
-	int iv,is,vertexdown,vertexup,numsegments;	
-	IssmDouble dt, height_element;
-	IssmDouble rho_water, rho_ice;
-	int numvertices = element->GetNumberOfVertices();
-
-	IssmDouble* xyz_list = NULL;
-	IssmDouble* enthalpies = xNew<IssmDouble>(numvertices);
-	IssmDouble* pressures = xNew<IssmDouble>(numvertices);
-	IssmDouble* temperatures = xNew<IssmDouble>(numvertices);
-	IssmDouble* waterfractions = xNew<IssmDouble>(numvertices);
-	IssmDouble* deltawaterfractions = xNew<IssmDouble>(numvertices);
-	int        *pairindices   = NULL;
+	ComputeWaterfractionDrainage(femmodel);
+	DrainageUpdateWatercolumn(femmodel);
+	DrainageUpdateEnthalpy(femmodel);
+}/*}}}*/
+void				EnthalpyAnalysis::ComputeWaterfractionDrainage(FemModel* femmodel){/*{{{*/
+
+	int i,k,numnodes;
+	IssmDouble dt;
+	Element* element= NULL;
+
+	femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
+
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		numnodes=element->GetNumberOfNodes();
+		IssmDouble* waterfractions= xNew<IssmDouble>(numnodes);
+		IssmDouble* drainage= xNew<IssmDouble>(numnodes);
+
+		element->GetInputListOnNodes(waterfractions,WaterfractionEnum);
+		for(k=0; k<numnodes;k++){
+			drainage[k]=DrainageFunctionWaterfraction(waterfractions[k], dt);
+		}
+		element->AddInput(WaterfractionDrainageEnum,drainage,element->GetElementType());
+
+		xDelete<IssmDouble>(waterfractions);
+		xDelete<IssmDouble>(drainage);
+	}
+}/*}}}*/
+void				EnthalpyAnalysis::DrainageUpdateWatercolumn(FemModel* femmodel){/*{{{*/
+
+	int i,k,numnodes, numbasalnodes;
+	IssmDouble dt;
+	int* basalnodeindices=NULL;
+	Element* element= NULL;
 	
-	rho_ice=element->GetMaterialParameter(MaterialsRhoIceEnum);
-	rho_water=element->GetMaterialParameter(MaterialsRhoSeawaterEnum);
-
-	element->GetVerticesCoordinates(&xyz_list);
-	element->GetInputListOnVertices(enthalpies,EnthalpyEnum);
-	element->GetInputListOnVertices(pressures,PressureEnum);
-
-	element->FindParam(&dt,TimesteppingTimeStepEnum);
-	for(iv=0;iv<numvertices;iv++){ 
-		element->EnthalpyToThermal(&temperatures[iv],&waterfractions[iv], enthalpies[iv],pressures[iv]); 
-		deltawaterfractions[iv]=DrainageFunctionWaterfraction(waterfractions[iv], dt);
-	}
-	
-	/*drain waterfraction, feed updated variables back into model*/
-	for(iv=0;iv<numvertices;iv++){
-		if(reCast<bool,IssmDouble>(dt))
-			waterfractions[iv]-=deltawaterfractions[iv]*dt;
-		else
-			waterfractions[iv]-=deltawaterfractions[iv];
-		element->ThermalToEnthalpy(&enthalpies[iv], temperatures[iv], waterfractions[iv], pressures[iv]);
-	}
-	element->AddInput(EnthalpyEnum,enthalpies,P1Enum);
-  	element->AddInput(WaterfractionEnum,waterfractions,P1Enum);
-
-	/*return meltwater column equivalent to drained water*/
-	element->VerticalSegmentIndices(&pairindices,&numsegments);
-	for(is=0;is<numsegments;is++){
-		vertexdown = pairindices[is*2+0];
-		vertexup   = pairindices[is*2+1];
-		height_element=fabs(xyz_list[vertexup*3+2]-xyz_list[vertexdown*3+2]);
-		pdrainrate_element[is]=(deltawaterfractions[vertexdown]+deltawaterfractions[vertexup])/2.*height_element; // return water equivalent of drainage
-		_assert_(pdrainrate_element[is]>=0.);
-	}
-
-	/*Clean up and return*/
-	xDelete<int>(pairindices);
-	xDelete<IssmDouble>(xyz_list);
-	xDelete<IssmDouble>(enthalpies);
-	xDelete<IssmDouble>(pressures);
-	xDelete<IssmDouble>(temperatures);
-	xDelete<IssmDouble>(waterfractions);
-	xDelete<IssmDouble>(deltawaterfractions);
-}/*}}}*/
-void           EnthalpyAnalysis::DrainWaterfractionIcecolumn(Element* element){/*{{{*/
-
-	/* Check if ice in element */
-	if(!element->IsIceInElement()) return;
-
-	/* Only drain waterfraction of ice column from element at base*/
-	if(!element->IsOnBase()) return; //FIXME: allow freeze on for floating elements
-
-	/* Intermediaries*/
-	int is,numsegments;
-	int *pairindices   = NULL;
-
-	int numnodes=element->GetNumberOfNodes();
-	element->VerticalSegmentIndices(&pairindices,&numsegments);
-
-	IssmDouble* drainrate_column  = xNew<IssmDouble>(numsegments);
-	IssmDouble* drainrate_element = xNew<IssmDouble>(numsegments);
-
-	for(is=0;is<numsegments;is++)	drainrate_column[is]=0.;
-	Element* elementi = element;
-	for(;;){
-		for(is=0;is<numsegments;is++)	drainrate_element[is]=0.;
-		DrainWaterfraction(elementi,drainrate_element); // TODO: make sure every vertex is only drained once
-		for(is=0;is<numsegments;is++)	drainrate_column[is]+=drainrate_element[is];
-
-		if(elementi->IsOnSurface()) break;
-		elementi=elementi->GetUpperElement();			
-	}
-
-	/* add drained water to water column*/
-	IssmDouble* watercolumn = xNew<IssmDouble>(numnodes);
-	element->GetInputListOnNodes(watercolumn,WatercolumnEnum);
-	for(is=0;is<numsegments;is++) watercolumn[is]+=drainrate_column[is];
-
-	/* Feed updated water column back into model */
-	element->AddInput(WatercolumnEnum,watercolumn,element->GetElementType());
-
-	xDelete<int>(pairindices);
-	xDelete<IssmDouble>(drainrate_column);
-	xDelete<IssmDouble>(drainrate_element);
-	xDelete<IssmDouble>(watercolumn);
+	femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
+
+	/*depth-integrate the drained water fraction */
+	femmodel->parameters->SetParam(WaterfractionDrainageEnum,InputToDepthaverageInEnum);
+	femmodel->parameters->SetParam(WaterfractionDrainageIntegratedEnum,InputToDepthaverageOutEnum);
+	depthaverage_core(femmodel);
+	femmodel->parameters->SetParam(WaterfractionDrainageIntegratedEnum,InputToExtrudeEnum);
+	extrudefrombase_core(femmodel);
+	/*multiply depth-average by ice thickness*/
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		numnodes=element->GetNumberOfNodes();
+		IssmDouble* drainage_int= xNew<IssmDouble>(numnodes);
+		IssmDouble* thicknesses= xNew<IssmDouble>(numnodes);
+
+		element->GetInputListOnNodes(drainage_int,WaterfractionDrainageIntegratedEnum);
+		element->GetInputListOnNodes(thicknesses,ThicknessEnum);
+		for(k=0;k<numnodes;k++){
+			drainage_int[k]*=thicknesses[k];
+		}
+		element->AddInput(WaterfractionDrainageIntegratedEnum, drainage_int, element->GetElementType());
+
+		xDelete<IssmDouble>(drainage_int);
+		xDelete<IssmDouble>(thicknesses);
+	}
+
+	/*update water column*/
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		/* Check if ice in element */
+		if(!element->IsIceInElement()) continue;
+		if(!element->IsOnBase()) continue; 
+
+		numnodes=element->GetNumberOfNodes();
+		IssmDouble* watercolumn= xNew<IssmDouble>(numnodes);
+		IssmDouble* drainage_int= xNew<IssmDouble>(numnodes);
+		element->GetInputListOnNodes(watercolumn,WatercolumnEnum);
+		element->GetInputListOnNodes(drainage_int,WaterfractionDrainageIntegratedEnum);
+
+		element->BasalNodeIndices(&numbasalnodes,&basalnodeindices,element->GetElementType());
+		for(k=0;k<numbasalnodes;k++){
+			watercolumn[basalnodeindices[k]]+=dt*drainage_int[basalnodeindices[k]];
+		}
+		element->AddInput(WatercolumnEnum, watercolumn, element->GetElementType());
+
+		xDelete<IssmDouble>(watercolumn);
+		xDelete<IssmDouble>(drainage_int);
+	}
+	xDelete<int>(basalnodeindices);
+}/*}}}*/
+void				EnthalpyAnalysis::DrainageUpdateEnthalpy(FemModel* femmodel){/*{{{*/
+
+	int i,k,numnodes;
+	IssmDouble dt;
+	Element* element= NULL;
+	femmodel->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
+
+	for(i=0;i<femmodel->elements->Size();i++){
+		element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));
+		numnodes=element->GetNumberOfNodes();
+		IssmDouble* enthalpies= xNew<IssmDouble>(numnodes);
+		IssmDouble* pressures= xNew<IssmDouble>(numnodes);
+		IssmDouble* temperatures= xNew<IssmDouble>(numnodes);
+		IssmDouble* waterfractions= xNew<IssmDouble>(numnodes);
+		IssmDouble* drainage= xNew<IssmDouble>(numnodes);
+
+		element->GetInputListOnNodes(enthalpies,EnthalpyEnum);
+		element->GetInputListOnNodes(pressures,PressureEnum);
+		element->GetInputListOnNodes(temperatures,TemperatureEnum);
+		element->GetInputListOnNodes(waterfractions,WaterfractionEnum);
+		element->GetInputListOnNodes(drainage,WaterfractionDrainageEnum);
+
+		for(k=0;k<numnodes;k++){
+			waterfractions[k]-=dt*drainage[k];
+			element->ThermalToEnthalpy(&enthalpies[k], temperatures[k], waterfractions[k], pressures[k]);
+		}
+		element->AddInput(WaterfractionEnum,waterfractions,element->GetElementType());
+		element->AddInput(EnthalpyEnum,enthalpies,element->GetElementType());
+
+		xDelete<IssmDouble>(enthalpies);
+		xDelete<IssmDouble>(pressures);
+		xDelete<IssmDouble>(temperatures);
+		xDelete<IssmDouble>(waterfractions);
+		xDelete<IssmDouble>(drainage);
+	}
 }/*}}}*/
 IssmDouble     EnthalpyAnalysis::EnthalpyDiffusionParameter(Element* element,IssmDouble enthalpy,IssmDouble pressure){/*{{{*/
Index: /issm/trunk-jpl/src/c/analyses/EnthalpyAnalysis.h
===================================================================
--- /issm/trunk-jpl/src/c/analyses/EnthalpyAnalysis.h	(revision 21720)
+++ /issm/trunk-jpl/src/c/analyses/EnthalpyAnalysis.h	(revision 21721)
@@ -36,6 +36,7 @@
 		ElementVector*    CreatePVectorShelf(Element* element);
 		static void       DrainWaterfraction(FemModel* femmodel);
-		static void       DrainWaterfraction(Element* element, IssmDouble* pdrainrate_element);
-		static void       DrainWaterfractionIcecolumn(Element* element);
+ 		static void       ComputeWaterfractionDrainage(FemModel* femmodel);
+ 		static void       DrainageUpdateWatercolumn(FemModel* femmodel);
+ 		static void       DrainageUpdateEnthalpy(FemModel* femmodel);
 		static IssmDouble EnthalpyDiffusionParameter(Element* element,IssmDouble enthalpy,IssmDouble pressure);
 		static IssmDouble EnthalpyDiffusionParameterVolume(Element* element,int enthalpy_enum);
Index: /issm/trunk-jpl/src/c/classes/Elements/Element.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/Elements/Element.h	(revision 21720)
+++ /issm/trunk-jpl/src/c/classes/Elements/Element.h	(revision 21721)
@@ -59,5 +59,4 @@
 		/*bool               AllActive(void);*/
 		/*bool               AnyActive(void);*/
-		void               BasalNodeIndices(int* pnumindices,int** pindices,int finiteelement){_error_("not implemented yet");};
 		void               ComputeLambdaS(void);
 		void               ComputeNewDamage();
@@ -177,4 +176,5 @@
 		virtual void       AddInput(int input_enum, IssmDouble* values, int interpolation_enum)=0;
 		virtual void       AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part)=0;
+		virtual void		 BasalNodeIndices(int* pnumindices,int** pindices,int finiteelement){_error_("not implemented yet");};
 		virtual void       CalvingRateDev(void){_error_("not implemented yet");};
 		virtual void	    CalvingRateLevermann(void)=0;
Index: /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h
===================================================================
--- /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 21720)
+++ /issm/trunk-jpl/src/c/shared/Enum/EnumDefinitions.h	(revision 21721)
@@ -265,4 +265,5 @@
 	StrainRateperpendicularEnum,
 	StrainRateeffectiveEnum,
+	EffectiveViscosityEnum,
 	MaterialsRhoIceEnum,
 	MaterialsRhoSeawaterEnum,
@@ -539,4 +540,6 @@
 	TransientInputEnum,
 	WaterfractionEnum,
+	WaterfractionDrainageEnum,
+	WaterfractionDrainageIntegratedEnum,
 	WatercolumnEnum,
 	ViscousHeatingEnum,
Index: /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 21720)
+++ /issm/trunk-jpl/src/c/shared/Enum/EnumToStringx.cpp	(revision 21721)
@@ -271,4 +271,5 @@
 		case StrainRateperpendicularEnum : return "StrainRateperpendicular";
 		case StrainRateeffectiveEnum : return "StrainRateeffective";
+		case EffectiveViscosityEnum : return "EffectiveViscosity";
 		case MaterialsRhoIceEnum : return "MaterialsRhoIce";
 		case MaterialsRhoSeawaterEnum : return "MaterialsRhoSeawater";
@@ -537,4 +538,6 @@
 		case TransientInputEnum : return "TransientInput";
 		case WaterfractionEnum : return "Waterfraction";
+		case WaterfractionDrainageEnum : return "WaterfractionDrainage";
+		case WaterfractionDrainageIntegratedEnum : return "WaterfractionDrainageIntegrated";
 		case WatercolumnEnum : return "Watercolumn";
 		case ViscousHeatingEnum : return "ViscousHeating";
Index: /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp
===================================================================
--- /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 21720)
+++ /issm/trunk-jpl/src/c/shared/Enum/StringToEnumx.cpp	(revision 21721)
@@ -277,4 +277,5 @@
 	      else if (strcmp(name,"StrainRateperpendicular")==0) return StrainRateperpendicularEnum;
 	      else if (strcmp(name,"StrainRateeffective")==0) return StrainRateeffectiveEnum;
+	      else if (strcmp(name,"EffectiveViscosity")==0) return EffectiveViscosityEnum;
 	      else if (strcmp(name,"MaterialsRhoIce")==0) return MaterialsRhoIceEnum;
 	      else if (strcmp(name,"MaterialsRhoSeawater")==0) return MaterialsRhoSeawaterEnum;
@@ -382,9 +383,9 @@
 	      else if (strcmp(name,"SmbNumRequestedOutputs")==0) return SmbNumRequestedOutputsEnum;
 	      else if (strcmp(name,"SmbRequestedOutputs")==0) return SmbRequestedOutputsEnum;
-	      else if (strcmp(name,"SmbIsInitialized")==0) return SmbIsInitializedEnum;
          else stage=4;
    }
    if(stage==4){
-	      if (strcmp(name,"SmbDzini")==0) return SmbDziniEnum;
+	      if (strcmp(name,"SmbIsInitialized")==0) return SmbIsInitializedEnum;
+	      else if (strcmp(name,"SmbDzini")==0) return SmbDziniEnum;
 	      else if (strcmp(name,"SmbDini")==0) return SmbDiniEnum;
 	      else if (strcmp(name,"SmbReini")==0) return SmbReiniEnum;
@@ -505,9 +506,9 @@
 	      else if (strcmp(name,"AndroidFrictionCoefficient")==0) return AndroidFrictionCoefficientEnum;
 	      else if (strcmp(name,"ResetPenalties")==0) return ResetPenaltiesEnum;
-	      else if (strcmp(name,"SurfaceAbsVelMisfit")==0) return SurfaceAbsVelMisfitEnum;
          else stage=5;
    }
    if(stage==5){
-	      if (strcmp(name,"SurfaceArea")==0) return SurfaceAreaEnum;
+	      if (strcmp(name,"SurfaceAbsVelMisfit")==0) return SurfaceAbsVelMisfitEnum;
+	      else if (strcmp(name,"SurfaceArea")==0) return SurfaceAreaEnum;
 	      else if (strcmp(name,"SurfaceAverageVelMisfit")==0) return SurfaceAverageVelMisfitEnum;
 	      else if (strcmp(name,"SurfaceLogVelMisfit")==0) return SurfaceLogVelMisfitEnum;
@@ -549,4 +550,6 @@
 	      else if (strcmp(name,"TransientInput")==0) return TransientInputEnum;
 	      else if (strcmp(name,"Waterfraction")==0) return WaterfractionEnum;
+	      else if (strcmp(name,"WaterfractionDrainage")==0) return WaterfractionDrainageEnum;
+	      else if (strcmp(name,"WaterfractionDrainageIntegrated")==0) return WaterfractionDrainageIntegratedEnum;
 	      else if (strcmp(name,"Watercolumn")==0) return WatercolumnEnum;
 	      else if (strcmp(name,"ViscousHeating")==0) return ViscousHeatingEnum;
@@ -626,11 +629,11 @@
 	      else if (strcmp(name,"Outputdefinition26")==0) return Outputdefinition26Enum;
 	      else if (strcmp(name,"Outputdefinition27")==0) return Outputdefinition27Enum;
-	      else if (strcmp(name,"Outputdefinition28")==0) return Outputdefinition28Enum;
-	      else if (strcmp(name,"Outputdefinition29")==0) return Outputdefinition29Enum;
-	      else if (strcmp(name,"Outputdefinition30")==0) return Outputdefinition30Enum;
          else stage=6;
    }
    if(stage==6){
-	      if (strcmp(name,"Outputdefinition31")==0) return Outputdefinition31Enum;
+	      if (strcmp(name,"Outputdefinition28")==0) return Outputdefinition28Enum;
+	      else if (strcmp(name,"Outputdefinition29")==0) return Outputdefinition29Enum;
+	      else if (strcmp(name,"Outputdefinition30")==0) return Outputdefinition30Enum;
+	      else if (strcmp(name,"Outputdefinition31")==0) return Outputdefinition31Enum;
 	      else if (strcmp(name,"Outputdefinition32")==0) return Outputdefinition32Enum;
 	      else if (strcmp(name,"Outputdefinition33")==0) return Outputdefinition33Enum;
@@ -749,11 +752,11 @@
 	      else if (strcmp(name,"ToolkitsOptionsStrings")==0) return ToolkitsOptionsStringsEnum;
 	      else if (strcmp(name,"QmuErrName")==0) return QmuErrNameEnum;
-	      else if (strcmp(name,"QmuInName")==0) return QmuInNameEnum;
-	      else if (strcmp(name,"QmuOutName")==0) return QmuOutNameEnum;
-	      else if (strcmp(name,"Regular")==0) return RegularEnum;
          else stage=7;
    }
    if(stage==7){
-	      if (strcmp(name,"Scaled")==0) return ScaledEnum;
+	      if (strcmp(name,"QmuInName")==0) return QmuInNameEnum;
+	      else if (strcmp(name,"QmuOutName")==0) return QmuOutNameEnum;
+	      else if (strcmp(name,"Regular")==0) return RegularEnum;
+	      else if (strcmp(name,"Scaled")==0) return ScaledEnum;
 	      else if (strcmp(name,"Separate")==0) return SeparateEnum;
 	      else if (strcmp(name,"Sset")==0) return SsetEnum;
@@ -872,11 +875,11 @@
 	      else if (strcmp(name,"SpcTransient")==0) return SpcTransientEnum;
 	      else if (strcmp(name,"StringArrayParam")==0) return StringArrayParamEnum;
-	      else if (strcmp(name,"StringParam")==0) return StringParamEnum;
-	      else if (strcmp(name,"Seg")==0) return SegEnum;
-	      else if (strcmp(name,"SegInput")==0) return SegInputEnum;
          else stage=8;
    }
    if(stage==8){
-	      if (strcmp(name,"Tria")==0) return TriaEnum;
+	      if (strcmp(name,"StringParam")==0) return StringParamEnum;
+	      else if (strcmp(name,"Seg")==0) return SegEnum;
+	      else if (strcmp(name,"SegInput")==0) return SegInputEnum;
+	      else if (strcmp(name,"Tria")==0) return TriaEnum;
 	      else if (strcmp(name,"TriaInput")==0) return TriaInputEnum;
 	      else if (strcmp(name,"Tetra")==0) return TetraEnum;
@@ -995,11 +998,11 @@
 	      else if (strcmp(name,"P1P1")==0) return P1P1Enum;
 	      else if (strcmp(name,"P1P1GLS")==0) return P1P1GLSEnum;
-	      else if (strcmp(name,"MINI")==0) return MINIEnum;
-	      else if (strcmp(name,"MINIcondensed")==0) return MINIcondensedEnum;
-	      else if (strcmp(name,"TaylorHood")==0) return TaylorHoodEnum;
          else stage=9;
    }
    if(stage==9){
-	      if (strcmp(name,"LATaylorHood")==0) return LATaylorHoodEnum;
+	      if (strcmp(name,"MINI")==0) return MINIEnum;
+	      else if (strcmp(name,"MINIcondensed")==0) return MINIcondensedEnum;
+	      else if (strcmp(name,"TaylorHood")==0) return TaylorHoodEnum;
+	      else if (strcmp(name,"LATaylorHood")==0) return LATaylorHoodEnum;
 	      else if (strcmp(name,"XTaylorHood")==0) return XTaylorHoodEnum;
 	      else if (strcmp(name,"OneLayerP4z")==0) return OneLayerP4zEnum;
