diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0d90274bf9e0327fe706ffcfa337b49322e0bb3e..9a23f059268899791574cc8ae43f573e7d129fbe 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -65,14 +65,6 @@ cppcheck-misra:
   script:
     - ci/cppcheck-misra.sh
 
-vera:
-  stage: build
-  before_script:
-    - vera++ --version
-    - cp ci/vera.profile /usr/lib/vera++/profiles/custom
-  script:
-    - ci/vera.sh
-
 clang-tidy:
   stage: build
   variables:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d56b1c4e859d1de9b54dd2558ff170eb8584363b..50c416bbd0ee88fef12adb1af819d0675a4e5d51 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ add_library(common OBJECT
         src/Helpers/CRCHelper.cpp
         src/Helpers/TimeAndDate.cpp
         src/Helpers/TimeHelper.cpp
+        src/Platform/x86/Parameters/SystemParameters.cpp
         src/Services/EventReportService.cpp
         src/Services/MemoryManagementService.cpp
         src/Services/ParameterService.cpp
diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index eb2f737d61cdc9908902200278d251f14b740910..a8523462496cad6652af9cb1c8eeb05d02fee2f4 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -141,4 +141,8 @@
  */
 #define LOGGER_MAX_MESSAGE_SIZE 512
 
+/**
+ * @brief Size of the array holding the Parameter objects for the ST[20] parameter service
+ */
+#define ECSS_PARAMETER_COUNT 3
 #endif // ECSS_SERVICES_ECSS_DEFINITIONS_H
diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp
index caeae9c80520866bd895f9e1e3db2bd4e4080204..0c07fe079c4f98002cbcc7d17c56a17e93e521d2 100644
--- a/inc/ErrorHandler.hpp
+++ b/inc/ErrorHandler.hpp
@@ -70,13 +70,13 @@ public:
 		 */
 		OtherMessageType = 9,
 		/**
-		 * Attempt to insert new function in a full function map (ST[08])
+		 * Attempt to insert new element in a full map ST[08]
 		 */
-		FunctionMapFull = 10,
+		MapFull = 10,
 		/**
 		 * A Message that is included within another message is too large
 		 */
-		NestedMessageTooLarge = 11,
+		NestedMessageTooLarge = 11
 	};
 
 	/**
@@ -102,7 +102,7 @@ public:
 		/**
 		 * Cannot parse a Message, because there is an error in its secondary header
 		 */
-		UnacceptableMessage = 5,
+		UnacceptableMessage = 5
 	};
 
 	/**
@@ -135,7 +135,14 @@ public:
 		EventActionUnknownEventActionDefinitionIDError = 4,
 		SubServiceExecutionStartError = 5,
 		InstructionExecutionStartError = 6,
-
+		/**
+		 * Attempt to change the value of a non existing parameter (ST[20])
+		 */
+		SetNonExistingParameter = 7,
+		/**
+		 * Attempt to access a non existing parameter (ST[20])
+		 */
+		GetNonExistingParameter = 8
 	};
 
 	/**
diff --git a/inc/Helpers/TimeHelper.hpp b/inc/Helpers/TimeHelper.hpp
index 027e078e817bf6748ac693821d7527a9e5c7c811..ecbad93d35d5893842e080e585c210f549bbce1d 100644
--- a/inc/Helpers/TimeHelper.hpp
+++ b/inc/Helpers/TimeHelper.hpp
@@ -66,7 +66,7 @@ public:
 	 * @todo check if we need to change the epoch to the recommended one from the standard, 1
 	 * January 1958
 	 */
-	static uint32_t utcToSeconds(TimeAndDate& TimeInfo);
+	static uint32_t utcToSeconds(const TimeAndDate& TimeInfo);
 
 	/**
 	 * Convert elapsed seconds since Unix epoch to UTC date.
@@ -94,7 +94,7 @@ public:
 	 * @todo time security for critical time operations
 	 * @todo declare the implicit P-field
 	 */
-	static uint64_t generateCDSTimeFormat(struct TimeAndDate& TimeInfo);
+	static uint64_t generateCDSTimeFormat(const struct TimeAndDate& TimeInfo);
 
 	/**
 	 * Parse the CDS time format (3.3 in CCSDS 301.0-B-4 standard)
@@ -124,7 +124,7 @@ public:
 	 * @todo time security for critical time operations
 	 * @todo declare the implicit P-field
 	 */
-	static uint32_t generateCUCTimeFormat(struct TimeAndDate& TimeInfo);
+	static uint32_t generateCUCTimeFormat(const struct TimeAndDate& TimeInfo);
 
 	/**
 	 * Parse the CUC time format (3.3 in CCSDS 301.0-B-4 standard)
diff --git a/inc/Platform/x86/Parameters/SystemParameters.hpp b/inc/Platform/x86/Parameters/SystemParameters.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e58687e46c5d39b4d374fcc68cb4d2aa8b8f564
--- /dev/null
+++ b/inc/Platform/x86/Parameters/SystemParameters.hpp
@@ -0,0 +1,32 @@
+#include "Services/Parameter.hpp"
+#include "etl/vector.h"
+/**
+ * @author Athanasios Theocharis <athatheoc@gmail.com>
+ */
+
+/**
+ * This class was created for the purpose of initializing and storing explicitly
+ * parameters (that are instances of the \ref Parameter class). It stores all the parameters
+ * of the specific application. Different subsystems should have their own implementations of this class.
+ * The position of the parameter in the vector is also called the parameter ID.
+ *
+ * It is initialised statically.
+ *
+ * The parameters here are under the responsibility of \ref ParameterService.
+ */
+class SystemParameters {
+public:
+	Parameter<uint8_t> parameter1 = Parameter<uint8_t>(3);
+	Parameter<uint16_t> parameter2 = Parameter<uint16_t>(7);
+	Parameter<uint32_t> parameter3 = Parameter<uint32_t>(10);
+	/**
+	 * The key of the array is the ID of the parameter as specified in PUS
+	 */
+	etl::array<std::reference_wrapper<ParameterBase>, ECSS_PARAMETER_COUNT> parametersArray = {
+		parameter1, parameter2, parameter3
+	};
+
+	SystemParameters() = default;
+};
+
+extern SystemParameters systemParameters;
diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..932d450f5389fb6cb67c9979f52106aef00d9b4c
--- /dev/null
+++ b/inc/Services/Parameter.hpp
@@ -0,0 +1,89 @@
+#ifndef ECSS_SERVICES_PARAMETER_HPP
+#define ECSS_SERVICES_PARAMETER_HPP
+
+#include "etl/String.hpp"
+#include "Message.hpp"
+#include "ECSS_Definitions.hpp"
+
+/**
+ * Implementation of a Parameter field, as specified in ECSS-E-ST-70-41C.
+ *
+ * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
+ * @author Athanasios Theocharis <athatheoc@gmail.com>
+ *
+ * @section Introduction
+ * The Parameter class implements a way of storing and updating system parameters
+ * of arbitrary size and type, while avoiding std::any and dynamic memory allocation.
+ * It is split in two distinct parts:
+ * 1) an abstract \ref ParameterBase class which provides a
+ * common data type used to create any pointers to \ref Parameter objects, as well as
+ * virtual functions for accessing the parameter's data part, and
+ * 2) a templated \ref Parameter used to store any type-specific parameter information,
+ * such as the actual data field where the parameter's value will be stored.
+ *
+ * @section Architecture Rationale
+ * The ST[20] Parameter service is implemented with the need of arbitrary type storage
+ * in mind, while avoiding any use of dynamic memory allocation, a requirement for use
+ * in embedded systems. Since lack of Dynamic Memory Access precludes usage of stl::any
+ * and the need for truly arbitrary (even for template-based objects like etl::string) type storage
+ * would exclude from consideration constructs like etl::variant due to limitations on
+ * the number of supported distinct types, a custom solution was needed.
+ * Furthermore, the \ref ParameterService should provide ID-based access to parameters.
+ */
+class ParameterBase {
+public:
+	virtual void appendValueToMessage(Message& message) = 0;
+	virtual void setValueFromMessage(Message& message) = 0;
+};
+
+/**
+ * Implementation of a parameter containing its value. See \ref ParameterBase for more information.
+ * @tparam DataType The type of the Parameter value. This is the type used for transmission and reception
+ * as per the PUS.
+ */
+template <typename DataType>
+class Parameter : public ParameterBase {
+private:
+	DataType currentValue;
+
+public:
+	Parameter(DataType initialValue) {
+		currentValue = initialValue;
+	}
+
+	inline void setValue(DataType value) {
+		currentValue = value;
+	}
+
+	DataType getValue() {
+		return currentValue;
+	}
+
+	inline void setValueFromMessage(Message& message) override;
+
+	inline void appendValueToMessage(Message& message) override;
+};
+
+template<> inline void Parameter<uint8_t>::setValueFromMessage(Message& message) {
+	currentValue = message.readUint8();
+}
+template<> inline void Parameter<uint16_t>::setValueFromMessage(Message& message) {
+	currentValue = message.readUint16();
+}
+
+template<> inline void Parameter<uint32_t>::setValueFromMessage(Message& message) {
+	currentValue = message.readUint32();
+}
+
+template<> inline void Parameter<uint8_t>::appendValueToMessage(Message& message) {
+	message.appendUint8(this->currentValue);
+}
+
+template<> inline void Parameter<uint16_t>::appendValueToMessage(Message& message) {
+	message.appendUint16(this->currentValue);
+}
+
+template<> inline void Parameter<uint32_t>::appendValueToMessage(Message& message) {
+	message.appendUint32(this->currentValue);
+}
+#endif //ECSS_SERVICES_PARAMETER_HPP
diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp
index 6b2a7af751c4904540f037929bcbd78f56588b8e..f347f651b1dda1e1a8e7073f5d19528ffeba7f2e 100644
--- a/inc/Services/ParameterService.hpp
+++ b/inc/Services/ParameterService.hpp
@@ -1,77 +1,40 @@
 #ifndef ECSS_SERVICES_PARAMETERSERVICE_HPP
 #define ECSS_SERVICES_PARAMETERSERVICE_HPP
 
+#include "ECSS_Definitions.hpp"
 #include "Service.hpp"
 #include "ErrorHandler.hpp"
-#include "etl/map.h"
+#include "Parameter.hpp"
+#include "Parameters/SystemParameters.hpp"
 
 /**
  * Implementation of the ST[20] parameter management service,
  * as defined in ECSS-E-ST-70-41C
  *
  * @author Grigoris Pavlakis <grigpavl@ece.auth.gr>
+ * @author Athanasios Theocharis <athatheoc@gmail.com>
  */
 
-/**
- * Generic parameter structure
- * PTC and PFC for each parameter shall be specified as in
- * ECSS-E-ST-70-41C, chapter 7.3
- */
-
-typedef uint16_t ParamId; // parameter IDs are given sequentially
-struct Parameter {
-	uint8_t ptc; // Packet field type code (PTC)
-	uint8_t pfc; // Packet field format code (PFC)
-
-	uint32_t settingData;
-	// Actual data defining the operation of a peripheral or subsystem.
-	// Peripheral-dependent normally (void* maybe?) (it's a memory address according to spec).
-	// Dummy int for now.
-};
-
 /**
  * Parameter manager - ST[20]
- * Holds the list with the parameters and provides functions
- * for parameter reporting and modification.
  *
- * The parameter list is stored in a map with the parameter IDs as keys and values
- * corresponding Parameter structs containing the PTC, PFC and the parameter's value.
- *
- * @ingroup Services
+ * The purpose of this class is to handle functions regarding the access and modification
+ * of the various parameters of the CubeSat.
+ * The parameters to be managed are initialized and kept in \ref SystemParameters.
  */
-
 class ParameterService : public Service {
-private:
-	etl::map<ParamId, Parameter, ECSS_MAX_PARAMETERS> paramsList;
-	uint16_t numOfValidIds(Message idMsg); // count the valid ids in a given TC[20, 1]
-
 public:
-	/**
-	 * Initializes the parameter list with some dummy values for now.
-	 */
-	ParameterService();
+	ParameterService() = default;
 
 	/**
 	 * This function receives a TC[20, 1] packet and returns a TM[20, 2] packet
 	 * containing the current configuration
 	 * **for the parameters specified in the carried valid IDs**.
 	 *
-	 * No sophisticated error checking for now, just whether the packet is of the correct type
-	 * and whether the requested IDs are valid, ignoring the invalid ones.
-	 * If the packet has an incorrect header, an InternalError::UnacceptablePacket is raised.
-	 * If no IDs are correct, the returned message shall be empty.
-	 *
-	 * @param paramId: a valid TC[20, 1] packet carrying the requested parameter IDs
+	 * @param paramId: a TC[20, 1] packet carrying the requested parameter IDs
 	 * @return None (messages are stored using storeMessage())
-	 *
-	 *
-	 * NOTES:
-	 * Method for valid ID counting is a hack (clones the message and figures out the number
-	 * separately, due to message access being non-random). Should be enough for now.
-	 *
-	 * Everything apart from the setting data is uint16 (setting data are uint32 for now)
 	 */
-	void reportParameterIds(Message& paramIds);
+	void reportParameters(Message& paramIds);
 
 	/**
 	 * This function receives a TC[20, 3] message and after checking whether its type is correct,
@@ -79,11 +42,8 @@ public:
 	 * while ignoring all invalid IDs.
 	 *
 	 * @param newParamValues: a valid TC[20, 3] message carrying parameter ID and replacement value
-	 * @return None
-	 *
-	 * @todo Use pointers for changing and storing addresses to comply with the standard
 	 */
-	void setParameterIds(Message& newParamValues);
+	void setParameters(Message& newParamValues);
 
 	/**
 	 * It is responsible to call the suitable function that executes a telecommand packet. The source of that packet
diff --git a/src/Helpers/TimeHelper.cpp b/src/Helpers/TimeHelper.cpp
index 04792af7c90b0be0153d8212aa3af4262673870b..b0e02d9b4debc90164b0b041ca16ee11bc3b0e28 100644
--- a/src/Helpers/TimeHelper.cpp
+++ b/src/Helpers/TimeHelper.cpp
@@ -10,7 +10,7 @@ bool TimeHelper::IsLeapYear(uint16_t year) {
 	return (year % 400) == 0;
 }
 
-uint32_t TimeHelper::utcToSeconds(TimeAndDate& TimeInfo) {
+uint32_t TimeHelper::utcToSeconds(const TimeAndDate& TimeInfo) {
 	// the date, that \p TimeInfo represents, should be greater than or equal to 1/1/2019 and the
 	// date should be valid according to Gregorian calendar
 	ASSERT_INTERNAL(TimeInfo.year >= 2019, ErrorHandler::InternalErrorType::InvalidDate);
@@ -91,7 +91,7 @@ struct TimeAndDate TimeHelper::secondsToUTC(uint32_t seconds) {
 	return TimeInfo;
 }
 
-uint64_t TimeHelper::generateCDSTimeFormat(TimeAndDate& TimeInfo) {
+uint64_t TimeHelper::generateCDSTimeFormat(const TimeAndDate& TimeInfo) {
 	/**
 	 * Define the T-field. The total number of octets for the implementation of T-field is 6(2 for
 	 * the `DAY` and 4 for the `ms of day`
@@ -126,7 +126,7 @@ TimeAndDate TimeHelper::parseCDStimeFormat(const uint8_t* data) {
 	return secondsToUTC(seconds);
 }
 
-uint32_t TimeHelper::generateCUCTimeFormat(struct TimeAndDate& TimeInfo) {
+uint32_t TimeHelper::generateCUCTimeFormat(const struct TimeAndDate& TimeInfo) {
 	return (utcToSeconds(TimeInfo) + LEAP_SECONDS);
 }
 
diff --git a/src/Platform/x86/Parameters/SystemParameters.cpp b/src/Platform/x86/Parameters/SystemParameters.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b5f68de3991e7aea68d3a6de2578aa48a4783b85
--- /dev/null
+++ b/src/Platform/x86/Parameters/SystemParameters.cpp
@@ -0,0 +1,3 @@
+#include "Parameters/SystemParameters.hpp"
+
+SystemParameters systemParameters;
diff --git a/src/Platform/x86/main.cpp b/src/Platform/x86/main.cpp
index 391780a790d452b7d5e0fd46a3aec0c280882818..07e1f968d556647caa0db2e5b0e7b0c7ea41457c 100644
--- a/src/Platform/x86/main.cpp
+++ b/src/Platform/x86/main.cpp
@@ -55,7 +55,7 @@ int main() {
 	sentPacket.appendUint16(2); // number of contained IDs
 	sentPacket.appendUint16(0); // first ID
 	sentPacket.appendUint16(1); // second ID
-	paramService.reportParameterIds(sentPacket);
+	paramService.reportParameters(sentPacket);
 
 	// Test code for setParameter
 	Message sentPacket2 = Message(20, 3, Message::TC, 1); // application id is a dummy number (1)
@@ -65,8 +65,8 @@ int main() {
 	sentPacket2.appendUint16(1); // 2nd parameter ID
 	sentPacket2.appendUint32(45823); // settings for 2nd parameter
 
-	paramService.setParameterIds(sentPacket2);
-	paramService.reportParameterIds(sentPacket);
+	paramService.setParameters(sentPacket2);
+	paramService.reportParameters(sentPacket);
 
 	// ST[06] testing
 	char anotherStr[8] = "Fgthred";
diff --git a/src/Services/EventActionService.cpp b/src/Services/EventActionService.cpp
index f42079794019ef1d4fca34b4ed176e7d40e5c18c..b0f2f7e22f4157d7d9b239309b8095f108663d53 100644
--- a/src/Services/EventActionService.cpp
+++ b/src/Services/EventActionService.cpp
@@ -221,4 +221,4 @@ void EventActionService::execute(Message& message) {
 	}
 }
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Services/FunctionManagementService.cpp b/src/Services/FunctionManagementService.cpp
index 4cee2c0c7f77749b1ff34f1bd4aa87c0809d8fb5..5400f038bb6efb3193712b8a800881478c89a338 100644
--- a/src/Services/FunctionManagementService.cpp
+++ b/src/Services/FunctionManagementService.cpp
@@ -46,7 +46,7 @@ void FunctionManagementService::include(String<ECSS_FUNCTION_NAME_LENGTH> funcNa
 		funcName.append(ECSS_FUNCTION_NAME_LENGTH - funcName.length(), 0);
 		funcPtrIndex.insert(std::make_pair(funcName, ptr));
 	} else {
-		ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::FunctionMapFull);
+		ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MapFull);
 	}
 }
 
diff --git a/src/Services/ParameterService.cpp b/src/Services/ParameterService.cpp
index aee2de5da27401a6a523f041cda172e112504281..3557f0ed7c66133dd50d075d6760649d97a4c7ef 100644
--- a/src/Services/ParameterService.cpp
+++ b/src/Services/ParameterService.cpp
@@ -2,50 +2,12 @@
 #ifdef SERVICE_PARAMETER
 
 #include "Services/ParameterService.hpp"
+#include "Services/Parameter.hpp"
 
-#define DEMOMODE
+void ParameterService::reportParameters(Message& paramIds) {
+	// TM[20,2]
+	Message parameterReport(20, 2, Message::TM, 1);
 
-#include <ctime>
-#include <cstdlib>
-
-ParameterService::ParameterService() {
-#ifdef DEMOMODE
-	// Test code, setting up some of the parameter fields
-
-	time_t currTime = time(nullptr);
-	struct tm* today = localtime(&currTime);
-
-	Parameter test1;
-	test1.settingData = today->tm_hour; // the current hour
-	test1.ptc = 3; // unsigned int
-	test1.pfc = 14; // 32 bits
-
-	Parameter test2;
-	test2.settingData = today->tm_min; // the current minute
-	test2.ptc = 3; // unsigned int
-	test2.pfc = 14; // 32 bits
-
-	// MAKE SURE THE IDS ARE UNIQUE WHEN INSERTING!
-	/**
-	 * @todo: Make a separate insert() function for parameter insertion to protect from blunders
-	 * if needed to
-	 */
-
-	paramsList.insert(std::make_pair(0, test1));
-	paramsList.insert(std::make_pair(1, test2));
-
-#endif
-}
-
-void ParameterService::reportParameterIds(Message& paramIds) {
-	paramIds.assertTC(20, 1);
-	Message reqParam(20, 2, Message::TM, 1); // empty TM[20, 2] parameter report message
-
-	paramIds.resetRead(); // since we're passing a reference, the reading position shall be reset
-	// to its default before any read operations (to ensure the correct data is being read)
-
-	// assertion: correct message, packet and service type (at failure throws an
-	// InternalError::UnacceptablePacket)
 	ErrorHandler::assertRequest(paramIds.packetType == Message::TC, paramIds,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
 	ErrorHandler::assertRequest(paramIds.messageType == 1, paramIds,
@@ -53,29 +15,31 @@ void ParameterService::reportParameterIds(Message& paramIds) {
 	ErrorHandler::assertRequest(paramIds.serviceType == 20, paramIds,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
 
-	uint16_t ids = paramIds.readUint16();
-	reqParam.appendUint16(numOfValidIds(paramIds)); // include the number of valid IDs
-
-	for (uint16_t i = 0; i < ids; i++) {
-		uint16_t currId = paramIds.readUint16(); // current ID to be appended
-
-		if (paramsList.find(currId) != paramsList.end()) {
-			reqParam.appendUint16(currId);
-			reqParam.appendUint32(paramsList[currId].settingData);
+	uint16_t numOfIds = paramIds.readUint16();
+	uint16_t numberOfValidIds = 0;
+	for (uint16_t i = 0; i < numOfIds; i++) {
+		if (paramIds.readUint16() < systemParameters.parametersArray.size()) {
+			numberOfValidIds++;
+		}
+	}
+	parameterReport.appendUint16(numberOfValidIds);
+	paramIds.resetRead();
+
+	numOfIds = paramIds.readUint16();
+	for (uint16_t i = 0; i < numOfIds; i++) {
+		uint16_t currId = paramIds.readUint16();
+		if (currId < systemParameters.parametersArray.size()) {
+			parameterReport.appendUint16(currId);
+			systemParameters.parametersArray[currId].get().appendValueToMessage(parameterReport);
 		} else {
-			ErrorHandler::reportError(paramIds, ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError);
-			continue; // generate failed start of execution notification & ignore
+			ErrorHandler::reportError(paramIds, ErrorHandler::GetNonExistingParameter);
 		}
 	}
 
-	storeMessage(reqParam);
+	storeMessage(parameterReport);
 }
 
-void ParameterService::setParameterIds(Message& newParamValues) {
-	newParamValues.assertTC(20, 3);
-
-	// assertion: correct message, packet and service type (at failure throws an
-	// InternalError::UnacceptablePacket which gets logged)
+void ParameterService::setParameters(Message& newParamValues) {
 
 	ErrorHandler::assertRequest(newParamValues.packetType == Message::TC, newParamValues,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
@@ -84,51 +48,26 @@ void ParameterService::setParameterIds(Message& newParamValues) {
 	ErrorHandler::assertRequest(newParamValues.serviceType == 20, newParamValues,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
 
-	uint16_t ids = newParamValues.readUint16(); // get number of ID's
+	uint16_t numOfIds = newParamValues.readUint16();
 
-	for (uint16_t i = 0; i < ids; i++) {
+	for (uint16_t i = 0; i < numOfIds; i++) {
 		uint16_t currId = newParamValues.readUint16();
-
-		if (paramsList.find(currId) != paramsList.end()) {
-			paramsList[currId].settingData = newParamValues.readUint32();
+		if (currId < systemParameters.parametersArray.size()) {
+			systemParameters.parametersArray[currId].get().setValueFromMessage(newParamValues);
 		} else {
-			ErrorHandler::reportError(newParamValues,
-			                          ErrorHandler::ExecutionStartErrorType::UnknownExecutionStartError);
-			continue; // generate failed start of execution notification & ignore
-		}
-	}
-}
-
-uint16_t ParameterService::numOfValidIds(Message idMsg) {
-	idMsg.resetRead();
-	// start reading from the beginning of the idMsg object
-	// (original obj. will not be influenced if this is called by value)
-
-	uint16_t ids = idMsg.readUint16(); // first 16bits of the packet are # of IDs
-	uint16_t validIds = 0;
-
-	for (uint16_t i = 0; i < ids; i++) {
-		uint16_t currId = idMsg.readUint16();
-
-		if (idMsg.messageType == 3) {
-			idMsg.readUint32(); // skip the 32bit settings blocks, we need only the IDs
-		}
-
-		if (paramsList.find(currId) != paramsList.end()) {
-			validIds++;
+			ErrorHandler::reportError(newParamValues, ErrorHandler::SetNonExistingParameter);
+			break; // Setting next parameters is impossible, since the size of value to be read is unknown
 		}
 	}
-
-	return validIds;
 }
 
 void ParameterService::execute(Message& message) {
 	switch (message.messageType) {
 		case 1:
-			reportParameterIds(message); // TC[20,1]
+			reportParameters(message); // TC[20,1]
 			break;
 		case 3:
-			setParameterIds(message); // TC[20,3]
+			setParameters(message); // TC[20,3]
 			break;
 		default:
 			ErrorHandler::reportInternalError(ErrorHandler::OtherMessageType);
diff --git a/test/Services/EventActionService.cpp b/test/Services/EventActionService.cpp
index d87262dce4bf2fad920224dd25c306f40ae6eb60..1931fc56dcee2120c7b0db8f5c3ad23716490195 100644
--- a/test/Services/EventActionService.cpp
+++ b/test/Services/EventActionService.cpp
@@ -3,9 +3,7 @@
 #include <Message.hpp>
 #include "ServiceTests.hpp"
 #include <etl/String.hpp>
-#include <etl/map.h>
 #include <cstring>
-#include <iostream>
 #include <ServicePool.hpp>
 
 EventActionService& eventActionService = Services.eventAction;
diff --git a/test/Services/FunctionManagementService.cpp b/test/Services/FunctionManagementService.cpp
index a4893a1a7561c2deb783ba8a12e46779c4a2d127..a793c3e9035ed37eb4aa9351d235fe1774f866a6 100644
--- a/test/Services/FunctionManagementService.cpp
+++ b/test/Services/FunctionManagementService.cpp
@@ -71,6 +71,6 @@ TEST_CASE("ST[08] - Insert Tests") {
 			name += std::to_string(i); // different names to fill up the map
 			fms.include(String<ECSS_FUNCTION_NAME_LENGTH>(name.c_str()), &test);
 		}
-		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::FunctionMapFull));
+		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::MapFull));
 	}
 }
diff --git a/test/Services/Parameter.cpp b/test/Services/Parameter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6cf629ee627eb1ced39be89518618663425e0240
--- /dev/null
+++ b/test/Services/Parameter.cpp
@@ -0,0 +1,41 @@
+#include "catch2/catch.hpp"
+#include "Services/Parameter.hpp"
+#include "Message.hpp"
+
+TEST_CASE("Parameter Append") {
+	SECTION("Check correct appending") {
+		Message request = Message(20, 1, Message::TC, 1);
+		Parameter<uint8_t> parameter1 = Parameter<uint8_t>(1);
+		Parameter<uint16_t> parameter2 = Parameter<uint16_t>(500);
+		Parameter<uint32_t> parameter3 = Parameter<uint32_t>(70000);
+
+		parameter1.appendValueToMessage(request);
+		parameter2.appendValueToMessage(request);
+		parameter3.appendValueToMessage(request);
+
+		CHECK(request.readUint8() == 1);
+		CHECK(request.readUint16() == 500);
+		CHECK(request.readUint32() == 70000);
+	}
+}
+
+TEST_CASE("Parameter Set") {
+	SECTION("Check correct setting") {
+		Message request = Message(20, 1, Message::TC, 1);
+		Parameter<uint8_t> parameter1 = Parameter<uint8_t>(1);
+		Parameter<uint16_t> parameter2 = Parameter<uint16_t>(500);
+		Parameter<uint32_t> parameter3 = Parameter<uint32_t>(70000);
+
+		request.appendUint8(10);
+		request.appendUint16(1000);
+		request.appendUint32(70001);
+
+		parameter1.setValueFromMessage(request);
+		parameter2.setValueFromMessage(request);
+		parameter3.setValueFromMessage(request);
+
+		CHECK(parameter1.getValue() == 10);
+		CHECK(parameter2.getValue() == 1000);
+		CHECK(parameter3.getValue() == 70001);
+	}
+}
diff --git a/test/Services/ParameterService.cpp b/test/Services/ParameterService.cpp
index 6153f6c5d57f69b32bbfdc1bb1410c040d0f8a7d..f29143633e2b692fb55226330627831f094044bc 100644
--- a/test/Services/ParameterService.cpp
+++ b/test/Services/ParameterService.cpp
@@ -1,103 +1,206 @@
 #include "catch2/catch.hpp"
-#include "Services/ParameterService.hpp"
 #include "Message.hpp"
 #include "ServiceTests.hpp"
 
-ParameterService& pserv = Services.parameterManagement;
+static void resetParameterValues() {
+	systemParameters.parameter1.setValue(3);
+	systemParameters.parameter2.setValue(7);
+	systemParameters.parameter3.setValue(10);
+};
 
 TEST_CASE("Parameter Report Subservice") {
-	SECTION("Faulty Instruction Handling Test") {
-		Message request(20, 1, Message::TC, 1);
-		Message report(20, 2, Message::TM, 1);
-
-		request.appendUint16(2); // number of requested IDs
-		request.appendUint16(34672); // faulty ID in this context
-		request.appendUint16(1); // valid
+	SECTION("All requested parameters invalid") {
+		Message request = Message(20, 1, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(54432);
+		request.appendUint16(60000);
+		request.appendUint16(65535);
 
 		MessageParser::execute(request);
-		report = ServiceTests::get(0);
-		request.resetRead();
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetNonExistingParameter) == 3);
+		CHECK(ServiceTests::count() == 4);
+
+		Message report = ServiceTests::get(3);
+		CHECK(report.serviceType == 20);
+		CHECK(report.messageType == 2);
+		CHECK(report.readUint16() == 0);  // the message shall be empty
 
-		report.readUint16();
-		request.readUint16();
+		ServiceTests::reset();
+		Services.reset();
+	}
 
-		while (report.readPosition <= report.dataSize) {
-			CHECK_FALSE(report.readUint16() == 34672); // fail if faulty ID is present in report
-			report.readUint32(); // ignore the carried settings
-		}
+	SECTION("Some requested parameters invalid") {
+		Message request = Message(20, 1, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(1);
+		request.appendUint16(10000);
+		request.appendUint16(2);
 
-		CHECK(ServiceTests::countErrors() == 1);
-		CHECK(ServiceTests::thrownError(ErrorHandler::UnknownExecutionStartError));
+		MessageParser::execute(request);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::GetNonExistingParameter) == 1);
+		CHECK(ServiceTests::count() == 2);
+
+		Message report = ServiceTests::get(1);
+		CHECK(report.serviceType == 20);
+		CHECK(report.messageType == 2);
+		CHECK(report.readUint16() == 2);
+		CHECK(report.readUint16() == 1);
+		CHECK(report.readUint16() == 7);
+		CHECK(report.readUint16() == 2);
+		CHECK(report.readUint32() == 10);
+
+		ServiceTests::reset();
+		Services.reset();
 	}
 
-	// **WARNING**
-	// TODO: Update this test (and all tests in general) to use the error handler's output when
-	//  checking for assertions.
-	SECTION("Wrong Message Type Handling Test") {
-		Message falseRequest(15, 3, Message::TM, 1); // a totally wrong message
+	SECTION("Parameters are of different types") {
+		Message request = Message(20, 1, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(0);
+		request.appendUint16(1);
+		request.appendUint16(2);
 
-		MessageParser::execute(falseRequest);
-		Message errorNotif = ServiceTests::get(0);
-		CHECK(errorNotif.messageType == 4); // check for proper failed start of
-		// execution notification
-		CHECK(errorNotif.serviceType == 1);
-
-		Message response = ServiceTests::get(1);
-		CHECK(response.messageType == 2);
-		CHECK(response.serviceType == 20);
-		CHECK(response.packetType == Message::TM);
-		CHECK(response.readPosition == 0); // if empty, this should't change from 0
+		MessageParser::execute(request);
+
+		Message report = ServiceTests::get(0);
+		CHECK(report.serviceType == 20);
+		CHECK(report.messageType == 2);
+		CHECK(report.readUint16() == 3);
+		CHECK(report.readUint16() == 0);
+		CHECK(report.readUint8() == 3);
+		CHECK(report.readUint16() == 1);
+		CHECK(report.readUint16() == 7);
+		CHECK(report.readUint16() == 2);
+		CHECK(report.readUint32() == 10);
+
+		ServiceTests::reset();
+		Services.reset();
 	}
 }
 
 TEST_CASE("Parameter Setting Subservice") {
-	SECTION("Faulty Instruction Handling Test") {
-		Message setRequest(20, 3, Message::TC, 1);
-		Message reportRequest(20, 1, Message::TC, 1);
-
-		setRequest.appendUint16(2); // total number of IDs
-		setRequest.appendUint16(1); // correct ID in this context
-		setRequest.appendUint32(3735928559); // 0xDEADBEEF in hex (new setting)
-		setRequest.appendUint16(16742); // faulty ID in this context
-		setRequest.appendUint32(3131746989); // 0xBAAAAAAD (this shouldn't be found in the report)
-
-		reportRequest.appendUint16(2);
-		reportRequest.appendUint16(16742);
-		reportRequest.appendUint16(1); // used to be 3, which pointed the bug with
-		// numOfValidIds out, now is 1 in order to be a valid ID (a separate test for
-		// numOfValidIds shall be introduced)
-
-		// Since every reporting and setting is called with the same (sometimes faulty) parameters,
-		// and there are errors generated (as should be) it is important to catch and check for
-		// them in order to preserve the integrity of the test.
-		MessageParser::execute(reportRequest);
-		Message errorNotif1 = ServiceTests::get(0);
-		CHECK(errorNotif1.messageType == 4);
-		CHECK(errorNotif1.serviceType == 1);
-
-		Message before = ServiceTests::get(1);
-
-		MessageParser::execute(setRequest);
-		Message errorNotif2 = ServiceTests::get(2);
-		CHECK(errorNotif2.messageType == 4);
-		CHECK(errorNotif2.serviceType == 1);
-
-		MessageParser::execute(reportRequest);
-		Message errorNotif3 = ServiceTests::get(3);
-		CHECK(errorNotif3.messageType == 4);
-		CHECK(errorNotif3.serviceType == 1);
-
-		Message after = ServiceTests::get(4);
-
-		before.readUint16();
-		after.readUint16(); // skip the number of IDs
-
-		while (after.readPosition <= after.dataSize) {
-			CHECK(before.readUint16() == after.readUint16()); // check if all IDs are present
-			CHECK_FALSE(after.readUint32() == 0xBAAAAAAD); // fail if any settings are BAAAAAAD :P
-		}
-
-		CHECK(ServiceTests::countErrors() == 3);
-		CHECK(ServiceTests::thrownError(ErrorHandler::UnknownExecutionStartError));
+	SECTION("All parameter IDs are invalid") {
+		Message request = Message(20, 3, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(54432);
+		request.appendUint16(1);
+		request.appendUint16(60000);
+		request.appendUint16(1);
+		request.appendUint16(65534);
+		request.appendUint16(1);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetNonExistingParameter) == 1);
+		CHECK(ServiceTests::count() == 1);
+
+		CHECK(systemParameters.parameter1.getValue() == 3);
+		CHECK(systemParameters.parameter2.getValue() == 7);
+		CHECK(systemParameters.parameter3.getValue() == 10);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("The last parameter ID is invalid") {
+		Message request = Message(20, 3, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(0);
+		request.appendUint8(1);
+		request.appendUint16(1);
+		request.appendUint16(2);
+		request.appendUint16(65534);
+		request.appendUint16(1);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetNonExistingParameter) == 1);
+		CHECK(ServiceTests::count() == 1);
+
+		CHECK(systemParameters.parameter1.getValue() == 1);
+		CHECK(systemParameters.parameter2.getValue() == 2);
+		CHECK(systemParameters.parameter3.getValue() == 10);
+
+		resetParameterValues();
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("The middle parameter ID is invalid") {
+		Message request = Message(20, 3, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(0);
+		request.appendUint8(1);
+		request.appendUint16(65534);
+		request.appendUint16(1);
+		request.appendUint16(2);
+		request.appendUint16(3);
+
+		MessageParser::execute(request);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::SetNonExistingParameter) == 1);
+		CHECK(ServiceTests::count() == 1);
+
+		CHECK(systemParameters.parameter1.getValue() == 1);
+		CHECK(systemParameters.parameter2.getValue() == 7);
+		CHECK(systemParameters.parameter3.getValue() == 10);
+
+		resetParameterValues();
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("All IDs are valid") {
+		Message request = Message(20, 3, Message::TC, 1);
+		request.appendUint16(3);
+		request.appendUint16(0);
+		request.appendUint8(1);
+		request.appendUint16(1);
+		request.appendUint16(2);
+		request.appendUint16(2);
+		request.appendUint32(3);
+
+		MessageParser::execute(request);
+
+		CHECK(systemParameters.parameter1.getValue() == 1);
+		CHECK(systemParameters.parameter2.getValue() == 2);
+		CHECK(systemParameters.parameter3.getValue() == 3);
+
+		resetParameterValues();
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Wrong Messages") {
+
+	SECTION("Wrong Service Type Handling Test for Report") {
+		Message falseRequest(62, 1, Message::TM, 1);
+
+		MessageParser::execute(falseRequest);
+		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::OtherMessageType));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Wrong Service Type Handling Test for Set") {
+		Message falseRequest(62, 3, Message::TM, 1);
+
+		MessageParser::execute(falseRequest);
+		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::OtherMessageType));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Wrong Message Type") {
+		Message falseRequest(20, 127, Message::TM, 1);
+
+		MessageParser::execute(falseRequest);
+		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::OtherMessageType));
+
+		ServiceTests::reset();
+		Services.reset();
 	}
 }
diff --git a/test/Services/ServiceTests.hpp b/test/Services/ServiceTests.hpp
index df769167d28843854d9d6919a7730c5015d5b2f7..d5b76b882b1f788b7da4267f5ab4d3f4841f5168 100644
--- a/test/Services/ServiceTests.hpp
+++ b/test/Services/ServiceTests.hpp
@@ -123,7 +123,7 @@ public:
 	}
 
 	/**
-	 * Find if an error
+	 * Find if an error exists
 	 * @tparam ErrorType An enumeration of ErrorHandler
 	 * @param errorType The error code of the Error, corresponding to the correct type as
 	 * specified in ErrorHandler
@@ -136,6 +136,20 @@ public:
 
 		return thrownErrors.find(std::make_pair(errorSource, errorType)) != thrownErrors.end();
 	}
+	/**
+ 	 * Find the number of times that an error exists
+ 	 * @tparam ErrorType An enumeration of ErrorHandler
+ 	 * @param errorType The error code of the Error, corresponding to the correct type as
+ 	 * specified in ErrorHandler
+ 	 */
+	template <typename ErrorType>
+	static int countThrownErrors(ErrorType errorType) {
+		ErrorHandler::ErrorSource errorSource = ErrorHandler::findErrorSource(errorType);
+
+		expectingErrors = true;
+
+		return thrownErrors.count(std::make_pair(errorSource, errorType));
+	}
 };
 
 #endif // ECSS_SERVICES_TESTS_SERVICES_SERVICETESTS_HPP