diff --git a/CMakeLists.txt b/CMakeLists.txt
index 377e35fc5cf84d4188f1014bf37f71a396823c68..676ae31eec43f262e0017c68111671daced1fb21 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,7 @@ else()
         message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
 endif()
 
+
 find_package(CURL REQUIRED)
 
 if(CURL_FOUND)
@@ -64,7 +65,7 @@ set(HEADERS ${header_path}/CrestApi.h
 		    ${header_path}/CrestException.h
 		    ${header_path}/picosha2.h)
 
-set(SOURCES src/CrestApi.cxx src/CrestRequest.cxx src/CrestApiFs.cxx)
+set(SOURCES src/CrestApi.cxx src/CrestRequest.cxx src/CrestApiFs.cxx src/CrestModel.cxx)
 
 include_directories(CrestApi ./ nlohmann ${Boost_INCLUDE_DIRS})
 set (SOURCES_EXAMPLE_FS doc/crest_example_fs.cxx)
@@ -115,4 +116,4 @@ configure_file(CrestApiLibConfig.cmake.in CrestApiLibConfig.cmake @ONLY)
 
 install(FILES ${HEADERS} DESTINATION "${include_dest}")
 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CrestApiLibConfig.cmake"
-        DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/CrestApiLib")
\ No newline at end of file
+        DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/CrestApiLib")
diff --git a/CrestApi/CrestModel.h b/CrestApi/CrestModel.h
index bc40bac8e4b4b25b15cc9f12d8206835ac922797..7c5bb51ce3b7d21d5f0e7a7b46271b9895e712c9 100644
--- a/CrestApi/CrestModel.h
+++ b/CrestApi/CrestModel.h
@@ -22,23 +22,8 @@ public:
     int totalPages;
     int number;
 
-    json to_json() const
-    {
-        return {
-            {"size", size},
-            {"totalElements", totalElements},
-            {"totalPages", totalPages},
-            {"number", number}};
-    }
-    static RespPage from_json(const json &j)
-    {
-        RespPage respPage;
-        respPage.size = j.value("size", 0);
-        respPage.totalElements = j.value("totalElements", 0);
-        respPage.totalPages = j.value("totalPages", 0);
-        respPage.number = j.value("number", 0);
-        return respPage;
-    }
+    json to_json() const;
+    static RespPage from_json(const json &j);
 };
 
 class GenericMap
@@ -46,31 +31,9 @@ class GenericMap
 public:
     std::map<std::string, std::string> additionalProperties;
 
-    json to_json() const
-    {
-        json additionalPropertiesJson;
-        for (const auto &entry : additionalProperties)
-        {
-            additionalPropertiesJson[entry.first] = entry.second;
-        }
-
-        return {
-            additionalPropertiesJson
-        };
-    }
-
-    static GenericMap from_json(const json &j)
-    {
-        GenericMap genericMap;
+    json to_json() const;
 
-        json additionalPropertiesJson = j.value("additionalProperties", json::object());
-        for (auto it = additionalPropertiesJson.begin(); it != additionalPropertiesJson.end(); ++it)
-        {
-            genericMap.additionalProperties[it.key()] = it.value();
-        }
-
-        return genericMap;
-    }
+    static GenericMap from_json(const json &j);
 };
 
 class CrestBaseResponse
@@ -82,47 +45,9 @@ public:
     std::optional<RespPage> page;
     std::optional<GenericMap> filter;
 
-    json to_json() const
-    {
-        json result = {
-            {"size", size},
-            {"datatype", datatype},
-            {"format", format}
-        };
-
-        // Check if the 'page' optional contains a value
-        if (page.has_value()) {
-            // Check if the value of 'page' is not null
-            if (!page.value().to_json().is_null()) {
-                result["page"] = page.value().to_json();
-            }
-        }
-
-        // Check if the 'filter' optional contains a value
-        if (filter.has_value()) {
-            // Check if the value of 'filter' is not null
-            if (!filter.value().to_json().is_null()) {
-                result["filter"] = filter.value().to_json();
-            }
-        }
-
-        return result;
-    }
+    json to_json() const;
 
-    static CrestBaseResponse from_json(const json &j)
-    {
-        CrestBaseResponse crestResponse;
-        crestResponse.size = j.value("size", 0);
-        crestResponse.datatype = j.value("datatype", "");
-        crestResponse.format = j.value("format", "");
-
-        // Check for the presence of "page" key and create an optional
-        crestResponse.page = j.contains("page") ? std::make_optional(RespPage::from_json(j["page"])) : std::nullopt;
-        // Check for the presence of "filter" key and create an optional
-        crestResponse.filter = j.contains("filter") ? std::make_optional(GenericMap::from_json(j["filter"])) : std::nullopt;
-
-        return crestResponse;
-    }
+    static CrestBaseResponse from_json(const json &j);
 };
 
 class GlobalTagDto
@@ -141,51 +66,14 @@ public:
     int64_t insertionTimeMilli;
 
     // Ctor
-    GlobalTagDto(std::string name, std::string description, std::string release, std::string workflow): 
-        name(name), validity(0), description(description), release(release), 
-        insertionTime(""), snapshotTime(""), scenario(""), workflow(workflow), type("T"), 
-        snapshotTimeMilli(0), insertionTimeMilli(0){
-        
-    }
+    GlobalTagDto(const char* _name, const char* _description, const char* _release, const char* _workflow);
+
     // Default Ctor
-    GlobalTagDto(): name(""), validity(0), description(""), release(""), 
-        insertionTime(""), snapshotTime(""), scenario(""), workflow(""), type("T"), 
-        snapshotTimeMilli(0), insertionTimeMilli(0){
-        
-    }
+    GlobalTagDto();
 
-    json to_json() const
-    {
-        return {
-            {"name", name},
-            {"validity", validity},
-            {"description", description},
-            {"release", release},
-            {"insertionTime", insertionTime},
-            {"snapshotTime", snapshotTime},
-            {"scenario", scenario},
-            {"workflow", workflow},
-            {"type", type},
-            {"snapshotTimeMilli", snapshotTimeMilli},
-            {"insertionTimeMilli", insertionTimeMilli}};
-    }
+    json to_json() const ;
 
-    static GlobalTagDto from_json(const json &j)
-    {
-        GlobalTagDto globalTag;
-        globalTag.name = j.value("name", "");
-        globalTag.validity = j.value<long_t>("validity", 0);
-        globalTag.description = j.value("description", "");
-        globalTag.release = j.value("release", "");
-        globalTag.insertionTime = j.value("insertionTime", "");
-        globalTag.snapshotTime = j.value("snapshotTime", "");
-        globalTag.scenario = j.value("scenario", "");
-        globalTag.workflow = j.value("workflow", "");
-        globalTag.type = j.value("type", "");
-        globalTag.snapshotTimeMilli = j.value("snapshotTimeMilli", 0);
-        globalTag.insertionTimeMilli = j.value("insertionTimeMilli", 0);
-        return globalTag;
-    }
+    static GlobalTagDto from_json(const json &j);
 };
 
 class GlobalTagSetDto : public CrestBaseResponse
@@ -193,40 +81,9 @@ class GlobalTagSetDto : public CrestBaseResponse
 public:
     std::vector<GlobalTagDto> resources;
 
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((GlobalTagDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
+    json to_json() const;
 
-    static GlobalTagSetDto from_json(const json &j)
-    {
-        GlobalTagSetDto globalTagSet;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            globalTagSet.resources.push_back(GlobalTagDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        globalTagSet.size = j.value("size", 0);
-        globalTagSet.datatype = j.value("datatype", "");
-        globalTagSet.format = j.value("format", "GlobalTagSetDto");
-        // Parse other properties as needed
-        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
-        if (cbr.page.has_value()) {
-            globalTagSet.page = cbr.page.value();
-        }
-        if (cbr.filter.has_value()) {
-            globalTagSet.filter = cbr.filter.value();
-        }
-        return globalTagSet;
-    }
+    static GlobalTagSetDto from_json(const json &j);
 };
 
 /**
@@ -258,42 +115,8 @@ public:
     TagDto(): name(""), timeType(""), objectType(""), synchronization(""), description(""), lastValidatedTime(0), endOfValidity(0), insertionTime(""), modificationTime("") {
    
     }
-    json to_json() const
-    {
-        return {
-            {"name", name},
-            {"timeType", timeType},
-            {"payloadSpec", objectType},
-            {"synchronization", synchronization},
-            {"description", description},
-            {"lastValidatedTime", lastValidatedTime},
-            {"endOfValidity", endOfValidity},
-            {"insertionTime", insertionTime},
-            {"modificationTime", modificationTime}};
-    }
-    static TagDto from_json(const json &j)
-    {
-        TagDto tag;
-        auto it = j.find("name");
-        if (it != j.end())
-        {
-            tag.name = j["name"];
-        }
-        else
-        {
-	  throw Crest::CrestException("ERROR in TagDto.from_json: JSON contains no tag name.");
-        }
-
-        tag.timeType = j.value("timeType", "");
-        tag.objectType = j.value("payloadSpec", "");
-        tag.synchronization = j.value("synchronization", "");
-        tag.description = j.value("description", "");
-        tag.lastValidatedTime = j.value<long_t>("lastValidatedTime", 0);
-        tag.endOfValidity = j.value<long_t>("endOfValidity", 0);
-        tag.insertionTime = j.value("insertionTime", "");
-        tag.modificationTime = j.value("modificationTime", "");
-        return tag;
-    }
+    json to_json() const;
+    static TagDto from_json(const json &j);
 };
 
 class TagSetDto : public CrestBaseResponse
@@ -301,39 +124,9 @@ class TagSetDto : public CrestBaseResponse
 public:
     std::vector<TagDto> resources;
 
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((TagDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
-    static TagSetDto from_json(const json &j)
-    {
-        TagSetDto tagSet;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            tagSet.resources.push_back(TagDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        tagSet.size = j.value("size", 0);
-        tagSet.datatype = j.value("datatype", "");
-        tagSet.format = j.value("format", "TagSetDto");
-        // Parse other properties as needed
-        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
-        if (cbr.page.has_value()) {
-	    tagSet.page = cbr.page.value();	    
-        }
-        if (cbr.filter.has_value()) {
-            tagSet.filter = cbr.filter.value();
-        }
-        return tagSet;
-    }
+    json to_json() const;
+
+    static TagSetDto from_json(const json &j);
 };
 
 
@@ -354,23 +147,8 @@ public:
         
     }
 
-    json to_json() const
-    {
-        return {
-            {"tagName", tagName},
-            {"globalTagName", globalTagName},
-            {"record", record},
-            {"label", label}};
-    }
-    static GlobalTagMapDto from_json(const json &j)
-    {
-        GlobalTagMapDto tagmap;
-        tagmap.tagName = j.value("tagName", "");
-        tagmap.globalTagName = j.value("globalTagName", "");
-        tagmap.record = j.value("record", "none");
-        tagmap.label = j.value("label", "none");
-        return tagmap;
-    }
+    json to_json() const;
+    static GlobalTagMapDto from_json(const json &j);
 };
 
 class GlobalTagMapSetDto : public CrestBaseResponse
@@ -378,56 +156,10 @@ class GlobalTagMapSetDto : public CrestBaseResponse
 public:
     std::vector<GlobalTagMapDto> resources;
 
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((GlobalTagMapDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
-    static GlobalTagMapSetDto from_json(const json &j)
-    {
-        GlobalTagMapSetDto tagMapSet;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            tagMapSet.resources.push_back(GlobalTagMapDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        tagMapSet.size = j.value("size", 0);
-        tagMapSet.datatype = j.value("datatype", "");
-        tagMapSet.format = j.value("format", "GlobalTagMapSetDto");
-        // Parse other properties as needed
-        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
-        if (cbr.page.has_value()) {
-            tagMapSet.page = cbr.page.value();
-        }
-        if (cbr.filter.has_value()) {
-            tagMapSet.filter = cbr.filter.value();
-        }
-        return tagMapSet;
-    }
+    json to_json() const;
+    static GlobalTagMapSetDto from_json(const json &j);
 
-    static GlobalTagMapSetDto from_fs_json(const json &j)
-    {
-        GlobalTagMapSetDto tagMapSet;
-        int n = j.size();
-
-        for (auto it = j.begin(); it != j.end(); ++it)
-        {
-            tagMapSet.resources.push_back(GlobalTagMapDto::from_json(*it));
-        }
-
-        tagMapSet.size = n;
-        tagMapSet.datatype = "maps";
-        tagMapSet.format = "GlobalTagMapSetDto";
-	
-        return tagMapSet;
-    }
+    static GlobalTagMapSetDto from_fs_json(const json &j);
 };
 
 
@@ -448,27 +180,8 @@ public:
     TagMetaDto(): tagName(""), description(""), chansize(0), colsize(0), tagInfo(""), insertionTime(""){
     }
 
-    json to_json() const
-    {
-        return {
-            {"tagName", tagName},
-            {"description", description},
-            {"chansize", chansize},
-            {"colsize", colsize},
-            {"tagInfo", tagInfo},
-            {"insertionTime", insertionTime}};
-    }
-    static TagMetaDto from_json(const json &j)
-    {
-        TagMetaDto tag;
-        tag.tagName = j.value("tagName", "");
-        tag.chansize = j.value("chansize", 0);
-        tag.colsize = j.value("colsize", 0);
-        tag.tagInfo = j.value("tagInfo", "");
-        tag.description = j.value("description", "");
-        tag.insertionTime = j.value("insertionTime", "");
-        return tag;
-    }
+    json to_json() const;
+    static TagMetaDto from_json(const json &j);
 };
 
 class TagMetaSetDto : public CrestBaseResponse
@@ -476,39 +189,8 @@ class TagMetaSetDto : public CrestBaseResponse
 public:
     std::vector<TagMetaDto> resources;
 
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((TagMetaDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
-    static TagMetaSetDto from_json(const json &j)
-    {
-        TagMetaSetDto tagSet;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            tagSet.resources.push_back(TagMetaDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        tagSet.size = j.value("size", 0);
-        tagSet.datatype = j.value("datatype", "");
-        tagSet.format = j.value("format", "");
-        // Parse other properties as needed
-        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
-        if (cbr.page.has_value()) {
-            tagSet.page = cbr.page.value();
-        }
-        if (cbr.filter.has_value()) {
-            tagSet.filter = cbr.filter.value();
-        }
-        return tagSet;
-    }
+    json to_json() const;
+    static TagMetaSetDto from_json(const json &j);
 };
 
 class IovDto
@@ -526,23 +208,8 @@ public:
     IovDto(): tagName(""), since(0), insertionTime(""), payloadHash("") {
     }
 
-    json to_json() const
-    {
-        return {
-            {"tagName", tagName},
-            {"since", since},
-            {"insertionTime", insertionTime},
-            {"payloadHash", payloadHash}};
-    }
-    static IovDto from_json(const json &j)
-    {
-        IovDto iov;
-        iov.tagName = j.value("tagName", "");
-	    iov.since = j.value<long_t>("since", 0);
-        iov.insertionTime = j.value("insertionTime", "");
-        iov.payloadHash = j.value("payloadHash", "");
-        return iov;
-    }
+    json to_json() const;
+    static IovDto from_json(const json &j);
 };
 
 class IovSetDto : public CrestBaseResponse
@@ -550,59 +217,11 @@ class IovSetDto : public CrestBaseResponse
 public:
     std::vector<IovDto> resources;
 
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((IovDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
+    json to_json() const;
   
-    static IovSetDto from_json(const json &j)
-    {
-        IovSetDto iovSet;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            iovSet.resources.push_back(IovDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        iovSet.size = j.value("size", iovSet.resources.size());
-        iovSet.datatype = j.value("datatype", "");
-        iovSet.format = j.value("format", "");
-        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
-        if (cbr.page.has_value()) {
-            iovSet.page = cbr.page.value();
-        }
-        if (cbr.filter.has_value()) {
-            iovSet.filter = cbr.filter.value();
-        }
-        // Parse other properties as needed
-        return iovSet;
-    }
+    static IovSetDto from_json(const json &j);
   
-    static IovSetDto from_fs_json(const json &j)
-    {
-        IovSetDto iovSet;
-	int n = j.size();
-
-        for (auto it = j.begin(); it != j.end(); ++it)
-        {
-            iovSet.resources.push_back(IovDto::from_json(*it));
-        }	
-
-        // Deserialize CrestBaseResponse part
-        iovSet.size = n;
-        iovSet.datatype = "iovs";
-        iovSet.format = "IovSetDto";
-	
-        // Parse other properties as needed
-        return iovSet;
-    }
+    static IovSetDto from_fs_json(const json &j);
 };
 
 class StoreDto
@@ -622,26 +241,9 @@ public:
     StoreDto(): since(0), hash(""), data(""), streamerInfo("{}"){
     }
 
-    // Function to serialize the object to JSON
-    json to_json() const
-    {
-        return {
-            {"hash", hash},
-            {"since", since},
-            {"data", data},
-            {"streamerInfo", streamerInfo}};
-    }
+    json to_json() const;
 
-    // Function to deserialize the object from JSON
-    static StoreDto from_json(const json &j)
-    {
-        StoreDto storeDto;	
-        storeDto.hash = j.value("hash", "");
-        storeDto.since = j.value("since", 0.0);
-        storeDto.data = j.value("data", "");
-        storeDto.streamerInfo = j.value("streamerInfo", "");
-        return storeDto;
-    }
+    static StoreDto from_json(const json &j);
 };
 
 class StoreSetDto : public CrestBaseResponse
@@ -649,36 +251,9 @@ class StoreSetDto : public CrestBaseResponse
 public:
     std::vector<StoreDto> resources;
 
-    // Function to serialize the object to JSON
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((StoreDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
+    json to_json() const;
 
-    // Function to deserialize the object from JSON
-    static StoreSetDto from_json(const json &j)
-    {
-        StoreSetDto storeSetDto;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            storeSetDto.resources.push_back(StoreDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        storeSetDto.size = j.value("size", storeSetDto.resources.size());
-        storeSetDto.datatype = j.value("datatype", "data");
-        storeSetDto.format = j.value("format", "StoreSetDto");
-        // we are skipping the parse of RespPage for page, and GenericMap for filters
-
-        return storeSetDto;
-    }
+    static StoreSetDto from_json(const json &j);
 };
 
 class PayloadDto 
@@ -694,33 +269,12 @@ public:
     std::string insertionTime;
 
     // Function to serialize the object to JSON
-    json to_json() const
-    {
-        return {
-            {"hash", hash},
-            {"version", version},
-            {"objectType", objectType},
-            {"objectName", objectName},
-            {"compressionType", compressionType},
-            {"checkSum", checkSum},
-            {"size", size},
-            {"insertionTime", insertionTime}};
-    }
+
+    json to_json() const;
 
     // Function to deserialize the object from JSON
-    static PayloadDto from_json(const json &j)
-    {
-        PayloadDto payloadDto;
-        payloadDto.hash = j.value("hash", "");
-        payloadDto.version = j.value("version", "");
-        payloadDto.objectType = j.value("objectType", "");
-        payloadDto.objectName = j.value("objectName", "");
-        payloadDto.compressionType = j.value("compressionType", "");
-        payloadDto.checkSum = j.value("checkSum", "");
-        payloadDto.size = j.value("size", 0);
-        payloadDto.insertionTime = j.value("insertionTime", "");
-        return payloadDto;
-    }
+
+    static PayloadDto from_json(const json &j);
 };
 
 class PayloadSetDto : public CrestBaseResponse
@@ -729,35 +283,12 @@ public:
     std::vector<PayloadDto> resources;
 
     // Function to serialize the object to JSON
-    json to_json() const
-    {
-        json baseJson = CrestBaseResponse::to_json();
-        json jsonResources = json::array();
-        for (const auto &resource : resources)
-        {
-            jsonResources.push_back(((PayloadDto)resource).to_json());
-        }
-        baseJson["resources"] = jsonResources;
-        return baseJson;
-    }
+    
+    json to_json() const;
 
     // Function to deserialize the object from JSON
-    static PayloadSetDto from_json(const json &j)
-    {
-        PayloadSetDto payloadSetDto;
-        json jsonResources = j.value("resources", json::array());
-        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
-        {
-            payloadSetDto.resources.push_back(PayloadDto::from_json(*it));
-        }
-        // Deserialize CrestBaseResponse part
-        payloadSetDto.size = j.value("size", payloadSetDto.resources.size());
-        payloadSetDto.datatype = j.value("datatype", "data");
-        payloadSetDto.format = j.value("format", "PayloadSetDto");
-        // we are skipping the parse of RespPage for page, and GenericMap for filters
-
-        return payloadSetDto;
-    }
+    
+    static PayloadSetDto from_json(const json &j);
 };
 
 #endif // CREST_DTOS_HPP
diff --git a/src/CrestModel.cxx b/src/CrestModel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a92b8933881ef2f0ae8f7fb1e4a0d8ed41c1f1e7
--- /dev/null
+++ b/src/CrestModel.cxx
@@ -0,0 +1,538 @@
+#include <CrestApi/CrestModel.h>
+#include <iostream>
+
+  json RespPage::to_json() const
+    {
+        return {
+            {"size", size},
+            {"totalElements", totalElements},
+            {"totalPages", totalPages},
+            {"number", number}};
+    }
+  RespPage RespPage::from_json(const json &j)
+    {
+        RespPage respPage;
+        respPage.size = j.value("size", 0);
+        respPage.totalElements = j.value("totalElements", 0);
+        respPage.totalPages = j.value("totalPages", 0);
+        respPage.number = j.value("number", 0);
+        return respPage;
+    }
+  json GenericMap::to_json() const
+    {
+        json additionalPropertiesJson;
+        for (const auto &entry : additionalProperties)
+        {
+            additionalPropertiesJson[entry.first] = entry.second;
+        }
+
+        return {
+            additionalPropertiesJson
+        };
+    }
+
+  GenericMap GenericMap::from_json(const json &j)
+    {
+        GenericMap genericMap;
+
+        json additionalPropertiesJson = j.value("additionalProperties", json::object());
+        for (auto it = additionalPropertiesJson.begin(); it != additionalPropertiesJson.end(); ++it)
+        {
+            genericMap.additionalProperties[it.key()] = it.value();
+        }
+
+        return genericMap;
+    }
+
+    json CrestBaseResponse::to_json() const
+    {
+        json result = {
+            {"size", size},
+            {"datatype", datatype},
+            {"format", format}
+        };
+
+        // Check if the 'page' optional contains a value
+        if (page.has_value()) {
+            // Check if the value of 'page' is not null
+	    if (!page.value().to_json().is_null()) {
+                result["page"] = page.value().to_json();
+            }
+        }
+
+        // Check if the 'filter' optional contains a value
+        if (filter.has_value()) {
+            // Check if the value of 'filter' is not null
+            if (!filter.value().to_json().is_null()) {
+                result["filter"] = filter.value().to_json();
+            }
+        }
+
+        return result;
+    }
+
+    CrestBaseResponse CrestBaseResponse::from_json(const json &j)
+    {
+        CrestBaseResponse crestResponse;
+        crestResponse.size = j.value("size", 0);
+        crestResponse.datatype = j.value("datatype", "");
+        crestResponse.format = j.value("format", "");
+
+        // Check for the presence of "page" key and create an optional
+        crestResponse.page = j.contains("page") ? std::make_optional(RespPage::from_json(j["page"])) : std::nullopt;
+        // Check for the presence of "filter" key and create an optional
+        crestResponse.filter = j.contains("filter") ? std::make_optional(GenericMap::from_json(j["filter"])) : std::nullopt;
+
+        return crestResponse;
+    }
+    json GlobalTagSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((GlobalTagDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+
+    GlobalTagSetDto GlobalTagSetDto::from_json(const json &j)
+    {
+        GlobalTagSetDto globalTagSet;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            globalTagSet.resources.push_back(GlobalTagDto::from_json(*it));
+        }
+        globalTagSet.size = j.value("size", 0);
+        globalTagSet.datatype = j.value("datatype", "");
+        globalTagSet.format = j.value("format", "GlobalTagSetDto");
+
+        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
+        if (cbr.page.has_value()) {
+            globalTagSet.page = cbr.page.value();
+        }
+        if (cbr.filter.has_value()) {
+            globalTagSet.filter = cbr.filter.value();
+        }
+        return globalTagSet;
+    }
+
+  GlobalTagDto::GlobalTagDto(): name(""), validity(0), description(""), release(""),
+        insertionTime(""), snapshotTime(""), scenario(""), workflow(""), type("T"),
+        snapshotTimeMilli(0), insertionTimeMilli(0){
+  }
+
+  GlobalTagDto::GlobalTagDto(const char* _name, const char* _description, const char* _release, const char* _workflow):
+        name(_name), validity(0), description(_description), release(_release),
+        insertionTime(""), snapshotTime(""), scenario(""), workflow(_workflow), type("T"),
+        snapshotTimeMilli(0), insertionTimeMilli(0){
+  }
+
+  json GlobalTagDto::to_json() const {
+	json js={};
+	js["name"]=name;
+	js["validity"]=validity;
+        js["description"]=description;
+        js["release"]=release;
+        js["insertionTime"]=insertionTime;
+        js["snapshotTime"]=snapshotTime;
+        js["scenario"]=scenario;
+        js["workflow"]=workflow;
+        js["type"]=type;
+        js["snapshotTimeMilli"]=snapshotTimeMilli;
+        js["insertionTimeMilli"]=insertionTimeMilli;	
+	return js;
+  }
+  GlobalTagDto GlobalTagDto::from_json(const json &j)
+    {
+        GlobalTagDto globalTag;
+        globalTag.name = j.value("name", "");
+        globalTag.validity = j.value<long_t>("validity", 0);
+        globalTag.description = j.value("description", "");
+        globalTag.release = j.value("release", "");
+        globalTag.insertionTime = j.value("insertionTime", "");
+        globalTag.snapshotTime = j.value("snapshotTime", "");
+        globalTag.scenario = j.value("scenario", "");
+        globalTag.workflow = j.value("workflow", "");
+        globalTag.type = j.value("type", "");
+        globalTag.snapshotTimeMilli = j.value("snapshotTimeMilli", 0);
+        globalTag.insertionTimeMilli = j.value("insertionTimeMilli", 0);
+        return globalTag;
+    }
+    json TagDto::to_json() const
+    {
+        return {
+            {"name", name},
+            {"timeType", timeType},
+            {"payloadSpec", objectType},
+            {"synchronization", synchronization},
+            {"description", description},
+            {"lastValidatedTime", lastValidatedTime},
+            {"endOfValidity", endOfValidity},
+            {"insertionTime", insertionTime},
+            {"modificationTime", modificationTime}};
+    }
+    TagDto TagDto::from_json(const json &j)
+    {
+        TagDto tag;
+        auto it = j.find("name");
+        if (it != j.end())
+        {
+            tag.name = j["name"];
+        }
+        else
+        {
+          throw Crest::CrestException("ERROR in TagDto.from_json: JSON contains no tag name.");
+        }
+
+        tag.timeType = j.value("timeType", "");
+        tag.objectType = j.value("payloadSpec", "");
+        tag.synchronization = j.value("synchronization", "");
+        tag.description = j.value("description", "");
+        tag.lastValidatedTime = j.value<long_t>("lastValidatedTime", 0);
+        tag.endOfValidity = j.value<long_t>("endOfValidity", 0);
+        tag.insertionTime = j.value("insertionTime", "");
+        tag.modificationTime = j.value("modificationTime", "");
+        return tag;
+    }
+    json TagSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((TagDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+    TagSetDto TagSetDto::from_json(const json &j)
+    {
+        TagSetDto tagSet;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            tagSet.resources.push_back(TagDto::from_json(*it));
+        }
+
+        tagSet.size = j.value("size", 0);
+        tagSet.datatype = j.value("datatype", "");
+        tagSet.format = j.value("format", "TagSetDto");
+
+        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
+        if (cbr.page.has_value()) {
+            tagSet.page = cbr.page.value();
+        }
+        if (cbr.filter.has_value()) {
+            tagSet.filter = cbr.filter.value();
+        }
+        return tagSet;
+    }
+    json GlobalTagMapDto::to_json() const
+    {
+        return {
+            {"tagName", tagName},
+            {"globalTagName", globalTagName},
+            {"record", record},
+            {"label", label}};
+    }
+    GlobalTagMapDto GlobalTagMapDto::from_json(const json &j)
+    {
+        GlobalTagMapDto tagmap;
+        tagmap.tagName = j.value("tagName", "");
+        tagmap.globalTagName = j.value("globalTagName", "");
+        tagmap.record = j.value("record", "none");
+        tagmap.label = j.value("label", "none");
+        return tagmap;
+    }
+
+    json GlobalTagMapSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((GlobalTagMapDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+    GlobalTagMapSetDto GlobalTagMapSetDto::from_json(const json &j)
+    {
+        GlobalTagMapSetDto tagMapSet;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            tagMapSet.resources.push_back(GlobalTagMapDto::from_json(*it));
+        }
+
+        tagMapSet.size = j.value("size", 0);
+        tagMapSet.datatype = j.value("datatype", "");
+        tagMapSet.format = j.value("format", "GlobalTagMapSetDto");
+
+        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
+        if (cbr.page.has_value()) {
+            tagMapSet.page = cbr.page.value();
+        }
+        if (cbr.filter.has_value()) {
+            tagMapSet.filter = cbr.filter.value();
+        }
+        return tagMapSet;
+    }
+
+    GlobalTagMapSetDto GlobalTagMapSetDto::from_fs_json(const json &j)
+    {
+        GlobalTagMapSetDto tagMapSet;
+        int n = j.size();
+
+        for (auto it = j.begin(); it != j.end(); ++it)
+        {
+            tagMapSet.resources.push_back(GlobalTagMapDto::from_json(*it));
+        }
+
+        tagMapSet.size = n;
+        tagMapSet.datatype = "maps";
+        tagMapSet.format = "GlobalTagMapSetDto";
+
+        return tagMapSet;
+    }
+
+    json TagMetaDto::to_json() const
+    {
+        return {
+            {"tagName", tagName},
+            {"description", description},
+            {"chansize", chansize},
+            {"colsize", colsize},
+            {"tagInfo", tagInfo},
+            {"insertionTime", insertionTime}};
+    }
+    TagMetaDto TagMetaDto::from_json(const json &j)
+    {
+        TagMetaDto tag;
+        tag.tagName = j.value("tagName", "");
+        tag.chansize = j.value("chansize", 0);
+        tag.colsize = j.value("colsize", 0);
+        tag.tagInfo = j.value("tagInfo", "");
+        tag.description = j.value("description", "");
+        tag.insertionTime = j.value("insertionTime", "");
+        return tag;
+    }
+
+    json TagMetaSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((TagMetaDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+    TagMetaSetDto TagMetaSetDto::from_json(const json &j)
+    {
+        TagMetaSetDto tagSet;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            tagSet.resources.push_back(TagMetaDto::from_json(*it));
+        }
+
+        tagSet.size = j.value("size", 0);
+        tagSet.datatype = j.value("datatype", "");
+        tagSet.format = j.value("format", "");
+
+        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
+        if (cbr.page.has_value()) {
+            tagSet.page = cbr.page.value();
+        }
+        if (cbr.filter.has_value()) {
+            tagSet.filter = cbr.filter.value();
+        }
+        return tagSet;
+    }
+    json IovDto::to_json() const
+    {
+        return {
+            {"tagName", tagName},
+            {"since", since},
+            {"insertionTime", insertionTime},
+            {"payloadHash", payloadHash}};
+    }
+    IovDto IovDto::from_json(const json &j)
+    {
+        IovDto iov;
+        iov.tagName = j.value("tagName", "");
+            iov.since = j.value<long_t>("since", 0);
+        iov.insertionTime = j.value("insertionTime", "");
+        iov.payloadHash = j.value("payloadHash", "");
+        return iov;
+    }
+
+    json IovSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((IovDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+
+    IovSetDto IovSetDto::from_json(const json &j)
+    {
+        IovSetDto iovSet;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            iovSet.resources.push_back(IovDto::from_json(*it));
+        }
+
+        iovSet.size = j.value("size", iovSet.resources.size());
+        iovSet.datatype = j.value("datatype", "");
+        iovSet.format = j.value("format", "");
+        CrestBaseResponse cbr = CrestBaseResponse::from_json(j);
+        if (cbr.page.has_value()) {
+            iovSet.page = cbr.page.value();
+        }
+        if (cbr.filter.has_value()) {
+            iovSet.filter = cbr.filter.value();
+        }
+        return iovSet;
+    }
+
+    IovSetDto IovSetDto::from_fs_json(const json &j)
+    {
+        IovSetDto iovSet;
+        int n = j.size();
+
+        for (auto it = j.begin(); it != j.end(); ++it)
+        {
+            iovSet.resources.push_back(IovDto::from_json(*it));
+        }
+
+        iovSet.size = n;
+        iovSet.datatype = "iovs";
+        iovSet.format = "IovSetDto";
+
+        return iovSet;
+    }
+
+    json StoreDto::to_json() const
+    {
+        return {
+            {"hash", hash},
+            {"since", since},
+            {"data", data},
+            {"streamerInfo", streamerInfo}};
+    }
+
+    StoreDto StoreDto::from_json(const json &j)
+    {
+        StoreDto storeDto;
+        storeDto.hash = j.value("hash", "");
+        storeDto.since = j.value("since", 0.0);
+        storeDto.data = j.value("data", "");
+        storeDto.streamerInfo = j.value("streamerInfo", "");
+        return storeDto;
+    }
+
+    json StoreSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((StoreDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+
+    StoreSetDto StoreSetDto::from_json(const json &j)
+    {
+        StoreSetDto storeSetDto;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            storeSetDto.resources.push_back(StoreDto::from_json(*it));
+        }
+
+        storeSetDto.size = j.value("size", storeSetDto.resources.size());
+        storeSetDto.datatype = j.value("datatype", "data");
+        storeSetDto.format = j.value("format", "StoreSetDto");
+        // we are skipping the parse of RespPage for page, and GenericMap for filters
+
+        return storeSetDto;
+    }
+
+    // Function to serialize the object to JSON
+
+    json PayloadDto::to_json() const
+    {
+        return {
+            {"hash", hash},
+            {"version", version},
+            {"objectType", objectType},
+            {"objectName", objectName},
+            {"compressionType", compressionType},
+            {"checkSum", checkSum},
+            {"size", size},
+            {"insertionTime", insertionTime}};
+    }
+
+    // Function to deserialize the object from JSON
+
+    PayloadDto PayloadDto::from_json(const json &j)
+    {
+        PayloadDto payloadDto;
+        payloadDto.hash = j.value("hash", "");
+        payloadDto.version = j.value("version", "");
+        payloadDto.objectType = j.value("objectType", "");
+        payloadDto.objectName = j.value("objectName", "");
+        payloadDto.compressionType = j.value("compressionType", "");
+        payloadDto.checkSum = j.value("checkSum", "");
+        payloadDto.size = j.value("size", 0);
+        payloadDto.insertionTime = j.value("insertionTime", "");
+        return payloadDto;
+    }
+
+    // Function to serialize the object to JSON
+
+    json PayloadSetDto::to_json() const
+    {
+        json baseJson = CrestBaseResponse::to_json();
+        json jsonResources = json::array();
+        for (const auto &resource : resources)
+        {
+            jsonResources.push_back(((PayloadDto)resource).to_json());
+        }
+        baseJson["resources"] = jsonResources;
+        return baseJson;
+    }
+
+    // Function to deserialize the object from JSON
+
+    PayloadSetDto PayloadSetDto::from_json(const json &j)
+    {
+        PayloadSetDto payloadSetDto;
+        json jsonResources = j.value("resources", json::array());
+        for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+        {
+            payloadSetDto.resources.push_back(PayloadDto::from_json(*it));
+        }
+        // Deserialize CrestBaseResponse part
+
+        payloadSetDto.size = j.value("size", payloadSetDto.resources.size());
+        payloadSetDto.datatype = j.value("datatype", "data");
+        payloadSetDto.format = j.value("format", "PayloadSetDto");
+        // we are skipping the parse of RespPage for page, and GenericMap for filters
+
+        return payloadSetDto;
+    }
+