Index: /issm/trunk-jpl/src/c/shared/io/Marshalling/Marshalling.h
===================================================================
--- /issm/trunk-jpl/src/c/shared/io/Marshalling/Marshalling.h	(revision 25508)
+++ /issm/trunk-jpl/src/c/shared/io/Marshalling/Marshalling.h	(revision 25509)
@@ -16,8 +16,13 @@
 	MARSHALLING_LOAD,
 	MARSHALLING_SIZE,
+#ifdef _HAVE_CODIPACK_
+	AD_COUNTDOUBLES,
+	AD_REGISTERINPUT,
+	AD_SETADJOINT,
+#endif
 };
 
 /*Define virtual Marshall Handle*/
-class MarshallHandle{
+class MarshallHandle{ /*{{{*/
 	public:
 		MarshallOpEnum operation_enum;
@@ -28,10 +33,12 @@
 		template<typename T> void call(T  & value);
 		template<typename T> void call(T* & value,int size);
-};
-
-/*Make sure to pass all fields by reference!*/
-class WriteCheckpointFunctor: public MarshallHandle{
-	public:
+}; /*}}}*/
+/* !! Make sure to pass all fields by reference !! */
+class WriteCheckpointFunctor: public MarshallHandle{ /*{{{*/
+
+	private:
 		char** pmarshalled_data;
+
+	public:
 		WriteCheckpointFunctor(char** pmarshalled_data_in) : MarshallHandle(MARSHALLING_WRITE),pmarshalled_data(pmarshalled_data_in){}
 		template<typename T> void call(T & value){
@@ -52,9 +59,11 @@
 			}
 		}
-};
-
-class LoadCheckpointFunctor: public MarshallHandle{
-	public:
+};/*}}}*/
+class LoadCheckpointFunctor:  public MarshallHandle{ /*{{{*/
+
+	private:
 		char** pmarshalled_data;
+
+	public:
 		LoadCheckpointFunctor(char** pmarshalled_data_in) : MarshallHandle(MARSHALLING_LOAD),pmarshalled_data(pmarshalled_data_in){}
 		void Echo(void){
@@ -78,9 +87,11 @@
 			}
 		}
-};
-
-class SizeCheckpointFunctor: public MarshallHandle{
-	public:
+};/*}}}*/
+class SizeCheckpointFunctor:  public MarshallHandle{ /*{{{*/
+
+	private:
 		int marshalled_data_size;
+
+	public:
 		SizeCheckpointFunctor(void) : MarshallHandle(MARSHALLING_SIZE),marshalled_data_size(0){}
 		int MarshalledSize(void){return this->marshalled_data_size;};
@@ -100,5 +111,67 @@
 			}
 		}
-};
+};/*}}}*/
+#ifdef _HAVE_CODIPACK_
+class CountDoublesFunctor:    public MarshallHandle{ /*{{{*/
+
+	private:
+		int double_count;
+
+	public:
+		CountDoublesFunctor(void) : MarshallHandle(AD_COUNTDOUBLES),double_count(0){}
+		int DoubleCount(void){return this->double_count;};
+		void Echo(void){
+			printf("CountDoublesFunctor Echo:\n");
+			printf("   double_count: %i\n",double_count);
+		}
+		template<typename T> void call(T & value){
+			/*General case: do nothing*/
+		}
+		template<typename T> void call(T* & value,int size){
+			/*General case: do nothing*/
+		}
+		void call(IssmDouble value){
+			this->double_count++;
+		}
+		void call(IssmDouble* value,int size){
+			if(value) this->double_count+= size;
+		}
+}; /*}}}*/
+class RegisterInputFunctor:   public MarshallHandle{ /*{{{*/
+
+	private:
+		int   double_count;
+		int*  identifiers;
+		auto* tape_codi;
+
+	public:
+		RegisterInputFunctor(auto* tape_in,int* identifiers_in) : MarshallHandle(AD_REGISTERINPUT),double_count(0),identifiers(identifiers_in),tape_codi(tape_in)){}
+		int DoubleCount(void){return this->double_count;};
+		void Echo(void){
+			printf("RegisterInputFunctor Echo:\n");
+			printf("   double_count: %i\n",double_count);
+		}
+		template<typename T> void call(T & value){
+			/*General case: do nothing*/
+		}
+		template<typename T> void call(T* & value,int size){
+			/*General case: do nothing*/
+		}
+		void call(IssmDouble value){
+			this->tape_codi->registerInput(value);
+			this->identifiers[this->double_count] = value.getGradientData();
+			this->double_count++;
+		}
+		void call(IssmDouble* value,int size){
+			if(value){
+				for(int i=0;i<size;i++){
+					this->tape_codi->registerInput(value[i]);
+					this->identifiers[this->double_count] = value[i].getGradientData();
+					this->double_count++;
+				}
+			}
+		}
+}; /*}}}*/
+#endif
 
 template<typename T> void MarshallHandle::call(T & value){
@@ -107,5 +180,10 @@
 		case MARSHALLING_LOAD: {LoadCheckpointFunctor*  temp = xDynamicCast<LoadCheckpointFunctor*>(this);  temp->call(value); break;}
 		case MARSHALLING_SIZE: {SizeCheckpointFunctor*  temp = xDynamicCast<SizeCheckpointFunctor*>(this);  temp->call(value); break;}
-		default: _error_("not supported yet");
+#ifdef _HAVE_CODIPACK_
+		case AD_COUNTDOUBLES:  {CountDoublesFunctor*    temp = xDynamicCast<CountDoublesFunctor*>(this);    temp->call(value); break;}
+		case AD_REGISTERINPUT: {RegisterInputFunctor*   temp = xDynamicCast<RegisterInputFunctor*>(this);   temp->call(value); break;}
+		//case AD_SETADJOINT:    {SetAdjointFunction*     temp = xDynamicCast<SetAdjointFunction*>(this);     temp->call(value); break;}
+#endif
+		default: _error_("Operation "<<OperationNumber()<<" not supported yet");
 	}
 }
@@ -115,5 +193,10 @@
 		case MARSHALLING_LOAD: {LoadCheckpointFunctor*  temp = xDynamicCast<LoadCheckpointFunctor*>(this);  temp->call(value,size); break;}
 		case MARSHALLING_SIZE: {SizeCheckpointFunctor*  temp = xDynamicCast<SizeCheckpointFunctor*>(this);  temp->call(value,size); break;}
-		default: _error_("not supported yet");
+#ifdef _HAVE_CODIPACK_
+		case AD_COUNTDOUBLES:  {CountDoublesFunctor*    temp = xDynamicCast<CountDoublesFunctor*>(this);    temp->call(value,size); break;}
+		case AD_REGISTERINPUT: {RegisterInputFunctor*   temp = xDynamicCast<RegisterInputFunctor*>(this);   temp->call(value,size); break;}
+		//case AD_SETADJOINT:    {SetAdjointFunction*     temp = xDynamicCast<SetAdjointFunction*>(this);     temp->call(value,size); break;}
+#endif
+		default: _error_("Operation "<<OperationNumber() <<" not supported yet");
 	}
 }
