#include "base/exception.hpp"
#include "base/objectlock.hpp"
#include "base/utility.hpp"
#include "base/convert.hpp"
#include "base/debug.hpp"
#include "base/dependencygraph.hpp"
#include "base/logger.hpp"
#include "base/function.hpp"
#include "base/configobject.hpp"
#include "base/configtype.hpp"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#include "icinga/notificationcommand.hpp"

#include "icinga/service.hpp"

namespace icinga
{

TypeImpl<Notification>::TypeImpl()
{ }

TypeImpl<Notification>::~TypeImpl()
{ }

String TypeImpl<Notification>::GetName() const
{
	return "Notification";
}

int TypeImpl<Notification>::GetAttributes() const
{
	return 0;
}

Type::Ptr TypeImpl<Notification>::GetBaseType() const
{
	return CustomVarObject::TypeInstance;
}

int TypeImpl<Notification>::GetFieldId(const String& name) const
{
	int offset = CustomVarObject::TypeInstance->GetFieldCount();

	switch (static_cast<int>(Utility::SDBM(name, 6))) {
		case -1895201222:
			if (name == "interval")
				return offset + 5;

			break;
		case -1819585739:
			if (name == "suppressed_notifications")
				return offset + 17;

			break;
		case -1785555177:
			if (name == "host_name")
				return offset + 3;

			break;
		case -1758927600:
			if (name == "stashed_notifications")
				return offset + 9;

			break;
		case -1750862898:
			if (name == "state_filter_real")
				return offset + 14;

			break;
		case -1750862878:
			if (name == "states")
				return offset + 10;

			break;
		case -1276411583:
			if (name == "type_filter_real")
				return offset + 15;

			break;
		case -1262592144:
			if (name == "service_name")
				return offset + 0;

			break;
		case -60843911:
			if (name == "types")
				return offset + 8;

			break;
		case 203120729:
			if (name == "command_endpoint")
				return offset + 1;
			if (name == "command")
				return offset + 2;

			break;
		case 309878278:
			if (name == "times")
				return offset + 13;

			break;
		case 600140712:
			if (name == "users")
				return offset + 6;

			break;
		case 928442885:
			if (name == "last_notified_state_per_user")
				return offset + 12;
			if (name == "last_notification")
				return offset + 18;

			break;
		case 928442887:
			if (name == "last_problem_notification")
				return offset + 20;

			break;
		case 959019475:
			if (name == "user_groups")
				return offset + 7;

			break;
		case 1136658041:
			if (name == "notified_problem_users")
				return offset + 11;
			if (name == "notification_number")
				return offset + 16;

			break;
		case 1543715906:
			if (name == "next_notification")
				return offset + 19;

			break;
		case 1809347489:
			if (name == "period")
				return offset + 4;

			break;
		case 1957832466:
			if (name == "no_more_notifications")
				return offset + 21;

			break;
	}

	return CustomVarObject::TypeInstance->GetFieldId(name);
}

Field TypeImpl<Notification>::GetFieldInfo(int id) const
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount();
	if (real_id < 0) { return CustomVarObject::TypeInstance->GetFieldInfo(id); }
	switch (real_id) {
		case 0:
			return {0, "String", "service_name", "service", nullptr, 1586, 0};
		case 1:
			return {1, "String", "command_endpoint", "command_endpoint", "Endpoint", 514, 0};
		case 2:
			return {2, "String", "command", "command", "NotificationCommand", 818, 0};
		case 3:
			return {3, "String", "host_name", "host", "Host", 1842, 0};
		case 4:
			return {4, "String", "period", "period", "TimePeriod", 514, 0};
		case 5:
			return {5, "Number", "interval", "interval", nullptr, 2, 0};
		case 6:
			return {6, "Array", "users", "users", "User", 65538, 1};
		case 7:
			return {7, "Array", "user_groups", "user_groups", "UserGroup", 65538, 1};
		case 8:
			return {8, "Array", "types", "types", nullptr, 66, 1};
		case 9:
			return {9, "Array", "stashed_notifications", "stashed_notifications", nullptr, 3076, 0};
		case 10:
			return {10, "Array", "states", "states", nullptr, 66, 1};
		case 11:
			return {11, "Array", "notified_problem_users", "notified_problem_users", nullptr, 1028, 0};
		case 12:
			return {12, "Dictionary", "last_notified_state_per_user", "last_notified_state_per_user", nullptr, 3076, 0};
		case 13:
			return {13, "Dictionary", "times", "times", nullptr, 2, 0};
		case 14:
			return {14, "Number", "state_filter_real", "state_filter_real", nullptr, 3073, 0};
		case 15:
			return {15, "Number", "type_filter_real", "type_filter_real", nullptr, 3073, 0};
		case 16:
			return {16, "Number", "notification_number", "notification_number", nullptr, 4, 0};
		case 17:
			return {17, "Number", "suppressed_notifications", "suppressed_notifications", nullptr, 3076, 0};
		case 18:
			return {18, "Timestamp", "last_notification", "last_notification", nullptr, 4, 0};
		case 19:
			return {19, "Timestamp", "next_notification", "next_notification", nullptr, 4, 0};
		case 20:
			return {20, "Timestamp", "last_problem_notification", "last_problem_notification", nullptr, 4, 0};
		case 21:
			return {21, "Boolean", "no_more_notifications", "no_more_notifications", nullptr, 1028, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

int TypeImpl<Notification>::GetFieldCount() const
{
	return 22 + CustomVarObject::TypeInstance->GetFieldCount();
}

ObjectFactory TypeImpl<Notification>::GetFactory() const
{
	return TypeHelper<Notification, false>::GetFactory();
}

const std::unordered_set<Type*>& TypeImpl<Notification>::GetLoadDependencies() const
{
	static const auto deps ([] {
		auto typeHost (GetByName("Host").get());
		VERIFY(typeHost);
		VERIFY(ConfigObject::TypeInstance->IsAssignableFrom(typeHost));

		auto typeService (GetByName("Service").get());
		VERIFY(typeService);
		VERIFY(ConfigObject::TypeInstance->IsAssignableFrom(typeService));

		auto typeUser (GetByName("User").get());
		VERIFY(typeUser);
		VERIFY(ConfigObject::TypeInstance->IsAssignableFrom(typeUser));

		auto typeUserGroup (GetByName("UserGroup").get());
		VERIFY(typeUserGroup);
		VERIFY(ConfigObject::TypeInstance->IsAssignableFrom(typeUserGroup));

		return std::unordered_set<Type*>{ typeHost, typeService, typeUser, typeUserGroup, };
	}());

	return deps;
}

int TypeImpl<Notification>::GetActivationPriority() const
{
	return 0;
}

void TypeImpl<Notification>::RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback)
{
	int real_id = fieldId - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::TypeInstance->RegisterAttributeHandler(fieldId, callback); return; }
	switch (real_id) {
		case 0:
			ObjectImpl<Notification>::OnServiceNameChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<Notification>::OnCommandEndpointRawChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<Notification>::OnCommandRawChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<Notification>::OnHostNameChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<Notification>::OnPeriodRawChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<Notification>::OnIntervalChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<Notification>::OnUsersRawChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<Notification>::OnUserGroupsRawChanged.connect(callback);
			break;
		case 8:
			ObjectImpl<Notification>::OnTypesChanged.connect(callback);
			break;
		case 9:
			ObjectImpl<Notification>::OnStashedNotificationsChanged.connect(callback);
			break;
		case 10:
			ObjectImpl<Notification>::OnStatesChanged.connect(callback);
			break;
		case 11:
			ObjectImpl<Notification>::OnNotifiedProblemUsersChanged.connect(callback);
			break;
		case 12:
			ObjectImpl<Notification>::OnLastNotifiedStatePerUserChanged.connect(callback);
			break;
		case 13:
			ObjectImpl<Notification>::OnTimesChanged.connect(callback);
			break;
		case 14:
			ObjectImpl<Notification>::OnStateFilterChanged.connect(callback);
			break;
		case 15:
			ObjectImpl<Notification>::OnTypeFilterChanged.connect(callback);
			break;
		case 16:
			ObjectImpl<Notification>::OnNotificationNumberChanged.connect(callback);
			break;
		case 17:
			ObjectImpl<Notification>::OnSuppressedNotificationsChanged.connect(callback);
			break;
		case 18:
			ObjectImpl<Notification>::OnLastNotificationChanged.connect(callback);
			break;
		case 19:
			ObjectImpl<Notification>::OnNextNotificationChanged.connect(callback);
			break;
		case 20:
			ObjectImpl<Notification>::OnLastProblemNotificationChanged.connect(callback);
			break;
		case 21:
			ObjectImpl<Notification>::OnNoMoreNotificationsChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Notification>::Validate(int types, const ValidationUtils& utils)
{
	CustomVarObject::Validate(types, utils);

	if (2 & types)
		ValidateServiceName(Lazy<String>([this]() { return GetServiceName(); }), utils);
	if (2 & types)
		ValidateCommandEndpointRaw(Lazy<String>([this]() { return GetCommandEndpointRaw(); }), utils);
	if (2 & types)
		ValidateCommandRaw(Lazy<String>([this]() { return GetCommandRaw(); }), utils);
	if (2 & types)
		ValidateHostName(Lazy<String>([this]() { return GetHostName(); }), utils);
	if (2 & types)
		ValidatePeriodRaw(Lazy<String>([this]() { return GetPeriodRaw(); }), utils);
	if (2 & types)
		ValidateInterval(Lazy<double>([this]() { return GetInterval(); }), utils);
	if (2 & types)
		ValidateUsersRaw(Lazy<Array::Ptr>([this]() { return GetUsersRaw(); }), utils);
	if (2 & types)
		ValidateUserGroupsRaw(Lazy<Array::Ptr>([this]() { return GetUserGroupsRaw(); }), utils);
	if (2 & types)
		ValidateTypes(Lazy<Array::Ptr>([this]() { return GetTypes(); }), utils);
	if (4 & types)
		ValidateStashedNotifications(Lazy<Array::Ptr>([this]() { return GetStashedNotifications(); }), utils);
	if (2 & types)
		ValidateStates(Lazy<Array::Ptr>([this]() { return GetStates(); }), utils);
	if (4 & types)
		ValidateNotifiedProblemUsers(Lazy<Array::Ptr>([this]() { return GetNotifiedProblemUsers(); }), utils);
	if (4 & types)
		ValidateLastNotifiedStatePerUser(Lazy<Dictionary::Ptr>([this]() { return GetLastNotifiedStatePerUser(); }), utils);
	if (2 & types)
		ValidateTimes(Lazy<Dictionary::Ptr>([this]() { return GetTimes(); }), utils);
	if (1 & types)
		ValidateStateFilter(Lazy<int>([this]() { return GetStateFilter(); }), utils);
	if (1 & types)
		ValidateTypeFilter(Lazy<int>([this]() { return GetTypeFilter(); }), utils);
	if (4 & types)
		ValidateNotificationNumber(Lazy<int>([this]() { return GetNotificationNumber(); }), utils);
	if (4 & types)
		ValidateSuppressedNotifications(Lazy<int>([this]() { return GetSuppressedNotifications(); }), utils);
	if (4 & types)
		ValidateLastNotification(Lazy<Timestamp>([this]() { return GetLastNotification(); }), utils);
	if (4 & types)
		ValidateNextNotification(Lazy<Timestamp>([this]() { return GetNextNotification(); }), utils);
	if (4 & types)
		ValidateLastProblemNotification(Lazy<Timestamp>([this]() { return GetLastProblemNotification(); }), utils);
	if (4 & types)
		ValidateNoMoreNotifications(Lazy<bool>([this]() { return GetNoMoreNotifications(); }), utils);
}

void ObjectImpl<Notification>::SimpleValidateServiceName(const Lazy<String>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateCommandEndpointRaw(const Lazy<String>& value, const ValidationUtils& utils)
{
			if (!value().IsEmpty() && !utils.ValidateName("Endpoint", value()))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "command_endpoint" }, "Object '" + value() + "' of type 'Endpoint' does not exist."));
}

void ObjectImpl<Notification>::SimpleValidateCommandRaw(const Lazy<String>& value, const ValidationUtils& utils)
{
	if (value().IsEmpty())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "command" }, "Attribute must not be empty."));

			if (!value().IsEmpty() && !utils.ValidateName("NotificationCommand", value()))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "command" }, "Object '" + value() + "' of type 'NotificationCommand' does not exist."));
}

void ObjectImpl<Notification>::SimpleValidateHostName(const Lazy<String>& value, const ValidationUtils& utils)
{
	if (value().IsEmpty())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "host_name" }, "Attribute must not be empty."));

			if (!value().IsEmpty() && !utils.ValidateName("Host", value()))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "host_name" }, "Object '" + value() + "' of type 'Host' does not exist."));
}

void ObjectImpl<Notification>::SimpleValidatePeriodRaw(const Lazy<String>& value, const ValidationUtils& utils)
{
			if (!value().IsEmpty() && !utils.ValidateName("TimePeriod", value()))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "period" }, "Object '" + value() + "' of type 'TimePeriod' does not exist."));
}

void ObjectImpl<Notification>::SimpleValidateInterval(const Lazy<double>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateUsersRaw(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils)
{
	if (avalue()) {
		ObjectLock olock(avalue());
		for (const Value& value : avalue()) {
			if (!value.IsEmpty() && !value.IsString())
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "users" }, "It is not allowed to specify '" + value + "' of type '" + value.GetTypeName() + "' as 'User' name. Expected type of 'User' name: 'String'."));
			if (value.IsEmpty() || !utils.ValidateName("User", value))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "users" }, "Object '" + value + "' of type 'User' does not exist."));
		}
	}
}

void ObjectImpl<Notification>::SimpleValidateUserGroupsRaw(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils)
{
	if (avalue()) {
		ObjectLock olock(avalue());
		for (const Value& value : avalue()) {
			if (!value.IsEmpty() && !value.IsString())
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "user_groups" }, "It is not allowed to specify '" + value + "' of type '" + value.GetTypeName() + "' as 'UserGroup' name. Expected type of 'UserGroup' name: 'String'."));
			if (value.IsEmpty() || !utils.ValidateName("UserGroup", value))
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "user_groups" }, "Object '" + value + "' of type 'UserGroup' does not exist."));
		}
	}
}

void ObjectImpl<Notification>::SimpleValidateTypes(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils)
{
	if (avalue()) {
		ObjectLock olock(avalue());
		for (const Value& value : avalue()) {
	if (value.IsObjectType<Function>()) {
		Function::Ptr func = value;
		if (func->IsDeprecated())
			Log(LogWarning, "Notification") << "Attribute 'types' for object '" << dynamic_cast<ConfigObject *>(this)->GetName() << "' of type '" << dynamic_cast<ConfigObject *>(this)->GetReflectionType()->GetName() << "' is set to a deprecated function: " << func->GetName();
	}

		}
	}
}

void ObjectImpl<Notification>::SimpleValidateStashedNotifications(const Lazy<Array::Ptr>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateStates(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils)
{
	if (avalue()) {
		ObjectLock olock(avalue());
		for (const Value& value : avalue()) {
	if (value.IsObjectType<Function>()) {
		Function::Ptr func = value;
		if (func->IsDeprecated())
			Log(LogWarning, "Notification") << "Attribute 'states' for object '" << dynamic_cast<ConfigObject *>(this)->GetName() << "' of type '" << dynamic_cast<ConfigObject *>(this)->GetReflectionType()->GetName() << "' is set to a deprecated function: " << func->GetName();
	}

		}
	}
}

void ObjectImpl<Notification>::SimpleValidateNotifiedProblemUsers(const Lazy<Array::Ptr>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateLastNotifiedStatePerUser(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateTimes(const Lazy<Dictionary::Ptr>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateStateFilter(const Lazy<int>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateTypeFilter(const Lazy<int>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateNotificationNumber(const Lazy<int>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateSuppressedNotifications(const Lazy<int>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateLastNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateNextNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateLastProblemNotification(const Lazy<Timestamp>& value, const ValidationUtils& utils)
{
}

void ObjectImpl<Notification>::SimpleValidateNoMoreNotifications(const Lazy<bool>& value, const ValidationUtils& utils)
{
}

ObjectImpl<Notification>::ObjectImpl()
{
	SetServiceName(GetDefaultServiceName(), true);
	SetCommandEndpointRaw(GetDefaultCommandEndpointRaw(), true);
	SetCommandRaw(GetDefaultCommandRaw(), true);
	SetHostName(GetDefaultHostName(), true);
	SetPeriodRaw(GetDefaultPeriodRaw(), true);
	SetInterval(GetDefaultInterval(), true);
	SetUsersRaw(GetDefaultUsersRaw(), true);
	SetUserGroupsRaw(GetDefaultUserGroupsRaw(), true);
	SetStashedNotifications(GetDefaultStashedNotifications(), true);
	SetNotifiedProblemUsers(GetDefaultNotifiedProblemUsers(), true);
	SetLastNotifiedStatePerUser(GetDefaultLastNotifiedStatePerUser(), true);
	SetTimes(GetDefaultTimes(), true);
	SetStateFilter(GetDefaultStateFilter(), true);
	SetTypeFilter(GetDefaultTypeFilter(), true);
	SetNotificationNumber(GetDefaultNotificationNumber(), true);
	SetSuppressedNotifications(GetDefaultSuppressedNotifications(), true);
	SetLastNotification(GetDefaultLastNotification(), true);
	SetNextNotification(GetDefaultNextNotification(), true);
	SetLastProblemNotification(GetDefaultLastProblemNotification(), true);
	SetNoMoreNotifications(GetDefaultNoMoreNotifications(), true);
}

ObjectImpl<Notification>::~ObjectImpl()
{ }

void ObjectImpl<Notification>::SetField(int id, const Value& value, bool suppress_events, const Value& cookie)
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::SetField(id, value, suppress_events, cookie); return; }
	switch (real_id) {
		case 0:
			SetServiceName(value, suppress_events, cookie);
			break;
		case 1:
			SetCommandEndpointRaw(value, suppress_events, cookie);
			break;
		case 2:
			SetCommandRaw(value, suppress_events, cookie);
			break;
		case 3:
			SetHostName(value, suppress_events, cookie);
			break;
		case 4:
			SetPeriodRaw(value, suppress_events, cookie);
			break;
		case 5:
			SetInterval(value, suppress_events, cookie);
			break;
		case 6:
			SetUsersRaw(value, suppress_events, cookie);
			break;
		case 7:
			SetUserGroupsRaw(value, suppress_events, cookie);
			break;
		case 8:
			SetTypes(value, suppress_events, cookie);
			break;
		case 9:
			SetStashedNotifications(value, suppress_events, cookie);
			break;
		case 10:
			SetStates(value, suppress_events, cookie);
			break;
		case 11:
			SetNotifiedProblemUsers(value, suppress_events, cookie);
			break;
		case 12:
			SetLastNotifiedStatePerUser(value, suppress_events, cookie);
			break;
		case 13:
			SetTimes(value, suppress_events, cookie);
			break;
		case 14:
			SetStateFilter(value, suppress_events, cookie);
			break;
		case 15:
			SetTypeFilter(value, suppress_events, cookie);
			break;
		case 16:
			SetNotificationNumber(value, suppress_events, cookie);
			break;
		case 17:
			SetSuppressedNotifications(value, suppress_events, cookie);
			break;
		case 18:
			SetLastNotification(value, suppress_events, cookie);
			break;
		case 19:
			SetNextNotification(value, suppress_events, cookie);
			break;
		case 20:
			SetLastProblemNotification(value, suppress_events, cookie);
			break;
		case 21:
			SetNoMoreNotifications(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<Notification>::GetField(int id) const
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return CustomVarObject::GetField(id); }
	switch (real_id) {
		case 0:
			return GetServiceName();
		case 1:
			return GetCommandEndpointRaw();
		case 2:
			return GetCommandRaw();
		case 3:
			return GetHostName();
		case 4:
			return GetPeriodRaw();
		case 5:
			return GetInterval();
		case 6:
			return GetUsersRaw();
		case 7:
			return GetUserGroupsRaw();
		case 8:
			return GetTypes();
		case 9:
			return GetStashedNotifications();
		case 10:
			return GetStates();
		case 11:
			return GetNotifiedProblemUsers();
		case 12:
			return GetLastNotifiedStatePerUser();
		case 13:
			return GetTimes();
		case 14:
			return GetStateFilter();
		case 15:
			return GetTypeFilter();
		case 16:
			return GetNotificationNumber();
		case 17:
			return GetSuppressedNotifications();
		case 18:
			return GetLastNotification();
		case 19:
			return GetNextNotification();
		case 20:
			return GetLastProblemNotification();
		case 21:
			return GetNoMoreNotifications();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Notification>::ValidateField(int id, const Lazy<Value>& lvalue, const ValidationUtils& utils)
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::ValidateField(id, lvalue, utils); return; }
	switch (real_id) {
		case 0:
			ValidateServiceName(lvalue, utils);
			break;
		case 1:
			ValidateCommandEndpointRaw(lvalue, utils);
			break;
		case 2:
			ValidateCommandRaw(lvalue, utils);
			break;
		case 3:
			ValidateHostName(lvalue, utils);
			break;
		case 4:
			ValidatePeriodRaw(lvalue, utils);
			break;
		case 5:
			ValidateInterval(lvalue, utils);
			break;
		case 6:
			ValidateUsersRaw(lvalue, utils);
			break;
		case 7:
			ValidateUserGroupsRaw(lvalue, utils);
			break;
		case 8:
			ValidateTypes(lvalue, utils);
			break;
		case 9:
			ValidateStashedNotifications(lvalue, utils);
			break;
		case 10:
			ValidateStates(lvalue, utils);
			break;
		case 11:
			ValidateNotifiedProblemUsers(lvalue, utils);
			break;
		case 12:
			ValidateLastNotifiedStatePerUser(lvalue, utils);
			break;
		case 13:
			ValidateTimes(lvalue, utils);
			break;
		case 14:
			ValidateStateFilter(lvalue, utils);
			break;
		case 15:
			ValidateTypeFilter(lvalue, utils);
			break;
		case 16:
			ValidateNotificationNumber(lvalue, utils);
			break;
		case 17:
			ValidateSuppressedNotifications(lvalue, utils);
			break;
		case 18:
			ValidateLastNotification(lvalue, utils);
			break;
		case 19:
			ValidateNextNotification(lvalue, utils);
			break;
		case 20:
			ValidateLastProblemNotification(lvalue, utils);
			break;
		case 21:
			ValidateNoMoreNotifications(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<Notification>::NotifyField(int id, const Value& cookie)
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { CustomVarObject::NotifyField(id, cookie); return; }
	switch (real_id) {
		case 0:
			NotifyServiceName(cookie);
			break;
		case 1:
			NotifyCommandEndpointRaw(cookie);
			break;
		case 2:
			NotifyCommandRaw(cookie);
			break;
		case 3:
			NotifyHostName(cookie);
			break;
		case 4:
			NotifyPeriodRaw(cookie);
			break;
		case 5:
			NotifyInterval(cookie);
			break;
		case 6:
			NotifyUsersRaw(cookie);
			break;
		case 7:
			NotifyUserGroupsRaw(cookie);
			break;
		case 8:
			NotifyTypes(cookie);
			break;
		case 9:
			NotifyStashedNotifications(cookie);
			break;
		case 10:
			NotifyStates(cookie);
			break;
		case 11:
			NotifyNotifiedProblemUsers(cookie);
			break;
		case 12:
			NotifyLastNotifiedStatePerUser(cookie);
			break;
		case 13:
			NotifyTimes(cookie);
			break;
		case 14:
			NotifyStateFilter(cookie);
			break;
		case 15:
			NotifyTypeFilter(cookie);
			break;
		case 16:
			NotifyNotificationNumber(cookie);
			break;
		case 17:
			NotifySuppressedNotifications(cookie);
			break;
		case 18:
			NotifyLastNotification(cookie);
			break;
		case 19:
			NotifyNextNotification(cookie);
			break;
		case 20:
			NotifyLastProblemNotification(cookie);
			break;
		case 21:
			NotifyNoMoreNotifications(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Object::Ptr ObjectImpl<Notification>::NavigateField(int id) const
{
	int real_id = id - CustomVarObject::TypeInstance->GetFieldCount(); 
	if (real_id < 0) { return CustomVarObject::NavigateField(id); }
	switch (real_id) {
		case 0:
			return NavigateServiceName();
		case 1:
			return NavigateCommandEndpointRaw();
		case 2:
			return NavigateCommandRaw();
		case 3:
			return NavigateHostName();
		case 4:
			return NavigatePeriodRaw();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

String ObjectImpl<Notification>::GetServiceName() const
{
	return m_ServiceName.load();
}

String ObjectImpl<Notification>::GetCommandEndpointRaw() const
{
	return m_CommandEndpointRaw.load();
}

String ObjectImpl<Notification>::GetCommandRaw() const
{
	return m_CommandRaw.load();
}

String ObjectImpl<Notification>::GetHostName() const
{
	return m_HostName.load();
}

String ObjectImpl<Notification>::GetPeriodRaw() const
{
	return m_PeriodRaw.load();
}

double ObjectImpl<Notification>::GetInterval() const
{
	return m_Interval.load();
}

Array::Ptr ObjectImpl<Notification>::GetUsersRaw() const
{
	return m_UsersRaw.load();
}

Array::Ptr ObjectImpl<Notification>::GetUserGroupsRaw() const
{
	return m_UserGroupsRaw.load();
}

Array::Ptr ObjectImpl<Notification>::GetStashedNotifications() const
{
	return m_StashedNotifications.load();
}

Array::Ptr ObjectImpl<Notification>::GetNotifiedProblemUsers() const
{
	return m_NotifiedProblemUsers.load();
}

Dictionary::Ptr ObjectImpl<Notification>::GetLastNotifiedStatePerUser() const
{
	return m_LastNotifiedStatePerUser.load();
}

Dictionary::Ptr ObjectImpl<Notification>::GetTimes() const
{
	return m_Times.load();
}

int ObjectImpl<Notification>::GetStateFilter() const
{
	return m_StateFilter.load();
}

int ObjectImpl<Notification>::GetTypeFilter() const
{
	return m_TypeFilter.load();
}

int ObjectImpl<Notification>::GetNotificationNumber() const
{
	return m_NotificationNumber.load();
}

int ObjectImpl<Notification>::GetSuppressedNotifications() const
{
	return m_SuppressedNotifications.load();
}

Timestamp ObjectImpl<Notification>::GetLastNotification() const
{
	return m_LastNotification.load();
}

Timestamp ObjectImpl<Notification>::GetNextNotification() const
{
	return m_NextNotification.load();
}

Timestamp ObjectImpl<Notification>::GetLastProblemNotification() const
{
	return m_LastProblemNotification.load();
}

bool ObjectImpl<Notification>::GetNoMoreNotifications() const
{
	return m_NoMoreNotifications.load();
}

void ObjectImpl<Notification>::SetServiceName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetServiceName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_ServiceName.store(value);
	if (!dobj || dobj->IsActive())
		TrackServiceName(oldValue, value);
	if (!suppress_events) {
		NotifyServiceName(cookie);
	}

}

void ObjectImpl<Notification>::SetCommandEndpointRaw(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetCommandEndpointRaw();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_CommandEndpointRaw.store(value);
	if (!dobj || dobj->IsActive())
		TrackCommandEndpointRaw(oldValue, value);
	if (!suppress_events) {
		NotifyCommandEndpointRaw(cookie);
	}

}

void ObjectImpl<Notification>::SetCommandRaw(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetCommandRaw();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_CommandRaw.store(value);
	if (!dobj || dobj->IsActive())
		TrackCommandRaw(oldValue, value);
	if (!suppress_events) {
		NotifyCommandRaw(cookie);
	}

}

void ObjectImpl<Notification>::SetHostName(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetHostName();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_HostName.store(value);
	if (!dobj || dobj->IsActive())
		TrackHostName(oldValue, value);
	if (!suppress_events) {
		NotifyHostName(cookie);
	}

}

void ObjectImpl<Notification>::SetPeriodRaw(const String& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetPeriodRaw();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_PeriodRaw.store(value);
	if (!dobj || dobj->IsActive())
		TrackPeriodRaw(oldValue, value);
	if (!suppress_events) {
		NotifyPeriodRaw(cookie);
	}

}

void ObjectImpl<Notification>::SetInterval(double value, bool suppress_events, const Value& cookie)
{
	m_Interval.store(value);
	if (!suppress_events) {
		NotifyInterval(cookie);
	}

}

void ObjectImpl<Notification>::SetUsersRaw(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetUsersRaw();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_UsersRaw.store(value);
	if (!dobj || dobj->IsActive())
		TrackUsersRaw(oldValue, value);
	if (!suppress_events) {
		NotifyUsersRaw(cookie);
		if (!dobj || dobj->IsActive())
			OnUsersRawChangedWithOldValue(static_cast<Notification *>(this), oldValue, value);
	}

}

void ObjectImpl<Notification>::SetUserGroupsRaw(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetUserGroupsRaw();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_UserGroupsRaw.store(value);
	if (!dobj || dobj->IsActive())
		TrackUserGroupsRaw(oldValue, value);
	if (!suppress_events) {
		NotifyUserGroupsRaw(cookie);
		if (!dobj || dobj->IsActive())
			OnUserGroupsRawChangedWithOldValue(static_cast<Notification *>(this), oldValue, value);
	}

}

void ObjectImpl<Notification>::SetStashedNotifications(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_StashedNotifications.store(value);
	if (!suppress_events) {
		NotifyStashedNotifications(cookie);
	}

}

void ObjectImpl<Notification>::SetNotifiedProblemUsers(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_NotifiedProblemUsers.store(value);
	if (!suppress_events) {
		NotifyNotifiedProblemUsers(cookie);
	}

}

void ObjectImpl<Notification>::SetLastNotifiedStatePerUser(const Dictionary::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_LastNotifiedStatePerUser.store(value);
	if (!suppress_events) {
		NotifyLastNotifiedStatePerUser(cookie);
	}

}

void ObjectImpl<Notification>::SetTimes(const Dictionary::Ptr& value, bool suppress_events, const Value& cookie)
{
	m_Times.store(value);
	if (!suppress_events) {
		NotifyTimes(cookie);
	}

}

void ObjectImpl<Notification>::SetStateFilter(int value, bool suppress_events, const Value& cookie)
{
	m_StateFilter.store(value);
	if (!suppress_events) {
		NotifyStateFilter(cookie);
	}

}

void ObjectImpl<Notification>::SetTypeFilter(int value, bool suppress_events, const Value& cookie)
{
	m_TypeFilter.store(value);
	if (!suppress_events) {
		NotifyTypeFilter(cookie);
	}

}

void ObjectImpl<Notification>::SetNotificationNumber(int value, bool suppress_events, const Value& cookie)
{
	m_NotificationNumber.store(value);
	if (!suppress_events) {
		NotifyNotificationNumber(cookie);
	}

}

void ObjectImpl<Notification>::SetSuppressedNotifications(int value, bool suppress_events, const Value& cookie)
{
	m_SuppressedNotifications.store(value);
	if (!suppress_events) {
		NotifySuppressedNotifications(cookie);
	}

}

void ObjectImpl<Notification>::SetLastNotification(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_LastNotification.store(value);
	if (!suppress_events) {
		NotifyLastNotification(cookie);
	}

}

void ObjectImpl<Notification>::SetNextNotification(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_NextNotification.store(value);
	if (!suppress_events) {
		NotifyNextNotification(cookie);
	}

}

void ObjectImpl<Notification>::SetLastProblemNotification(const Timestamp& value, bool suppress_events, const Value& cookie)
{
	m_LastProblemNotification.store(value);
	if (!suppress_events) {
		NotifyLastProblemNotification(cookie);
	}

}

void ObjectImpl<Notification>::SetNoMoreNotifications(bool value, bool suppress_events, const Value& cookie)
{
	m_NoMoreNotifications.store(value);
	if (!suppress_events) {
		NotifyNoMoreNotifications(cookie);
	}

}

void ObjectImpl<Notification>::TrackServiceName(const String& oldValue, const String& newValue)
{
	
			if (!oldValue.IsEmpty()) {
				Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
				DependencyGraph::RemoveDependency(this, service.get());
			}

			if (!newValue.IsEmpty()) {
				Service::Ptr service = Service::GetByNamePair(GetHostName(), newValue);
				DependencyGraph::AddDependency(this, service.get());
			}
		
}

void ObjectImpl<Notification>::TrackCommandEndpointRaw(const String& oldValue, const String& newValue)
{
	if (!oldValue.IsEmpty())
		DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<Endpoint>(oldValue).get());
	if (!newValue.IsEmpty())
		DependencyGraph::AddDependency(this, ConfigObject::GetObject<Endpoint>(newValue).get());
}

void ObjectImpl<Notification>::TrackCommandRaw(const String& oldValue, const String& newValue)
{
	if (!oldValue.IsEmpty())
		DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<NotificationCommand>(oldValue).get());
	if (!newValue.IsEmpty())
		DependencyGraph::AddDependency(this, ConfigObject::GetObject<NotificationCommand>(newValue).get());
}

void ObjectImpl<Notification>::TrackHostName(const String& oldValue, const String& newValue)
{
	if (!oldValue.IsEmpty())
		DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<Host>(oldValue).get());
	if (!newValue.IsEmpty())
		DependencyGraph::AddDependency(this, ConfigObject::GetObject<Host>(newValue).get());
}

void ObjectImpl<Notification>::TrackPeriodRaw(const String& oldValue, const String& newValue)
{
	if (!oldValue.IsEmpty())
		DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<TimePeriod>(oldValue).get());
	if (!newValue.IsEmpty())
		DependencyGraph::AddDependency(this, ConfigObject::GetObject<TimePeriod>(newValue).get());
}

void ObjectImpl<Notification>::TrackUsersRaw(const Array::Ptr& oldValue, const Array::Ptr& newValue)
{
	if (oldValue) {
		ObjectLock olock(oldValue);
		for (auto& ref : oldValue) {
			DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<User>(ref).get());
		}
	}
	if (newValue) {
		ObjectLock olock(newValue);
		for (auto& ref : newValue) {
			DependencyGraph::AddDependency(this, ConfigObject::GetObject<User>(ref).get());
		}
	}
}

void ObjectImpl<Notification>::TrackUserGroupsRaw(const Array::Ptr& oldValue, const Array::Ptr& newValue)
{
	if (oldValue) {
		ObjectLock olock(oldValue);
		for (auto& ref : oldValue) {
			DependencyGraph::RemoveDependency(this, ConfigObject::GetObject<UserGroup>(ref).get());
		}
	}
	if (newValue) {
		ObjectLock olock(newValue);
		for (auto& ref : newValue) {
			DependencyGraph::AddDependency(this, ConfigObject::GetObject<UserGroup>(ref).get());
		}
	}
}

Object::Ptr ObjectImpl<Notification>::NavigateServiceName() const
{
	
			if (!GetServiceName().IsEmpty()) {
				Host::Ptr host = Host::GetByName(GetHostName());
				if (host)
					return host->GetServiceByShortName(GetServiceName());
			}

			return nullptr;
		
}

Object::Ptr ObjectImpl<Notification>::NavigateCommandEndpointRaw() const
{
	
			return Endpoint::GetByName(GetCommandEndpointRaw());
		
}

Object::Ptr ObjectImpl<Notification>::NavigateCommandRaw() const
{
	
			return NotificationCommand::GetByName(GetCommandRaw());
		
}

Object::Ptr ObjectImpl<Notification>::NavigateHostName() const
{
	
			return Host::GetByName(GetHostName());
		
}

Object::Ptr ObjectImpl<Notification>::NavigatePeriodRaw() const
{
	
			return TimePeriod::GetByName(GetPeriodRaw());
		
}

void ObjectImpl<Notification>::Start(bool runtimeCreated)
{
	CustomVarObject::Start(runtimeCreated);

	TrackServiceName(Empty, GetServiceName());
	TrackCommandEndpointRaw(Empty, GetCommandEndpointRaw());
	TrackCommandRaw(Empty, GetCommandRaw());
	TrackHostName(Empty, GetHostName());
	TrackPeriodRaw(Empty, GetPeriodRaw());
	TrackUsersRaw(Empty, GetUsersRaw());
	TrackUserGroupsRaw(Empty, GetUserGroupsRaw());
}

void ObjectImpl<Notification>::Stop(bool runtimeRemoved)
{
	CustomVarObject::Stop(runtimeRemoved);

	TrackServiceName(GetServiceName(), Empty);
	TrackCommandEndpointRaw(GetCommandEndpointRaw(), Empty);
	TrackCommandRaw(GetCommandRaw(), Empty);
	TrackHostName(GetHostName(), Empty);
	TrackPeriodRaw(GetPeriodRaw(), Empty);
	TrackUsersRaw(GetUsersRaw(), Empty);
	TrackUserGroupsRaw(GetUserGroupsRaw(), Empty);
}

void ObjectImpl<Notification>::NotifyServiceName(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnServiceNameChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyCommandEndpointRaw(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnCommandEndpointRawChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyCommandRaw(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnCommandRawChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyHostName(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnHostNameChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyPeriodRaw(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnPeriodRawChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyInterval(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnIntervalChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyUsersRaw(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnUsersRawChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyUserGroupsRaw(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnUserGroupsRawChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyTypes(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnTypesChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyStashedNotifications(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnStashedNotificationsChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyStates(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnStatesChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyNotifiedProblemUsers(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnNotifiedProblemUsersChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyLastNotifiedStatePerUser(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnLastNotifiedStatePerUserChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyTimes(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnTimesChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyStateFilter(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnStateFilterChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyTypeFilter(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnTypeFilterChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyNotificationNumber(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnNotificationNumberChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifySuppressedNotifications(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnSuppressedNotificationsChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyLastNotification(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnLastNotificationChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyNextNotification(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnNextNotificationChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyLastProblemNotification(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnLastProblemNotificationChanged(static_cast<Notification *>(this), cookie);
}

void ObjectImpl<Notification>::NotifyNoMoreNotifications(const Value& cookie)
{
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	if (!dobj || dobj->IsActive())
		OnNoMoreNotificationsChanged(static_cast<Notification *>(this), cookie);
}

String ObjectImpl<Notification>::GetDefaultServiceName() const
{
	return String();
}

String ObjectImpl<Notification>::GetDefaultCommandEndpointRaw() const
{
	return String();
}

String ObjectImpl<Notification>::GetDefaultCommandRaw() const
{
	return String();
}

String ObjectImpl<Notification>::GetDefaultHostName() const
{
	return String();
}

String ObjectImpl<Notification>::GetDefaultPeriodRaw() const
{
	return String();
}

double ObjectImpl<Notification>::GetDefaultInterval() const
{
	 return 1800; 
}

Array::Ptr ObjectImpl<Notification>::GetDefaultUsersRaw() const
{
	return Array::Ptr();
}

Array::Ptr ObjectImpl<Notification>::GetDefaultUserGroupsRaw() const
{
	return Array::Ptr();
}

Array::Ptr ObjectImpl<Notification>::GetDefaultTypes() const
{
	return Array::Ptr();
}

Array::Ptr ObjectImpl<Notification>::GetDefaultStashedNotifications() const
{
	 return new Array(); 
}

Array::Ptr ObjectImpl<Notification>::GetDefaultStates() const
{
	return Array::Ptr();
}

Array::Ptr ObjectImpl<Notification>::GetDefaultNotifiedProblemUsers() const
{
	 return new Array(); 
}

Dictionary::Ptr ObjectImpl<Notification>::GetDefaultLastNotifiedStatePerUser() const
{
	 return new Dictionary(); 
}

Dictionary::Ptr ObjectImpl<Notification>::GetDefaultTimes() const
{
	return Dictionary::Ptr();
}

int ObjectImpl<Notification>::GetDefaultStateFilter() const
{
	return int();
}

int ObjectImpl<Notification>::GetDefaultTypeFilter() const
{
	return int();
}

int ObjectImpl<Notification>::GetDefaultNotificationNumber() const
{
	return int();
}

int ObjectImpl<Notification>::GetDefaultSuppressedNotifications() const
{
	 return 0; 
}

Timestamp ObjectImpl<Notification>::GetDefaultLastNotification() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Notification>::GetDefaultNextNotification() const
{
	return Timestamp();
}

Timestamp ObjectImpl<Notification>::GetDefaultLastProblemNotification() const
{
	return Timestamp();
}

bool ObjectImpl<Notification>::GetDefaultNoMoreNotifications() const
{
	 return false; 
}


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnServiceNameChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnCommandEndpointRawChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnCommandRawChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnHostNameChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnPeriodRawChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnIntervalChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnUsersRawChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&, const Value&)> ObjectImpl<Notification>::OnUsersRawChangedWithOldValue;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnUserGroupsRawChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&, const Value&)> ObjectImpl<Notification>::OnUserGroupsRawChangedWithOldValue;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnTypesChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnStashedNotificationsChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnStatesChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnNotifiedProblemUsersChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnLastNotifiedStatePerUserChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnTimesChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnStateFilterChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnTypeFilterChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnNotificationNumberChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnSuppressedNotificationsChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnLastNotificationChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnNextNotificationChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnLastProblemNotificationChanged;


boost::signals2::signal<void (const intrusive_ptr<Notification>&, const Value&)> ObjectImpl<Notification>::OnNoMoreNotificationsChanged;

static void TIValidateNotification_1(const intrusive_ptr<ObjectImpl<Notification> >& object, const String& key, const Value& value, std::vector<String>& location, const ValidationUtils& utils)
{
	bool known_attribute = false;
	do {
		if (key != "begin")
			break;
		known_attribute = true;
		try {
			Convert::ToDouble(value);
			return;
		} catch (...) { }
	} while (0);

	do {
		if (key != "end")
			break;
		known_attribute = true;
		try {
			Convert::ToDouble(value);
			return;
		} catch (...) { }
	} while (0);

	if (!known_attribute)
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, "Invalid attribute: " + key));
	else
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, "Invalid type."));
}

static void TIValidateNotificationCommandEndpointRaw(const intrusive_ptr<ObjectImpl<Notification> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateNotificationCommandRaw(const intrusive_ptr<ObjectImpl<Notification> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateNotificationHostName(const intrusive_ptr<ObjectImpl<Notification> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateNotificationInterval(const intrusive_ptr<ObjectImpl<Notification> >& object, double value, std::vector<String>& location, const ValidationUtils& utils)
{
}

static void TIValidateNotificationLastNotification(const intrusive_ptr<ObjectImpl<Notification> >& object, const Timestamp& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationLastNotifiedStatePerUser(const intrusive_ptr<ObjectImpl<Notification> >& object, const Dictionary::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationLastProblemNotification(const intrusive_ptr<ObjectImpl<Notification> >& object, const Timestamp& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationNextNotification(const intrusive_ptr<ObjectImpl<Notification> >& object, const Timestamp& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationNoMoreNotifications(const intrusive_ptr<ObjectImpl<Notification> >& object, bool value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationNotificationNumber(const intrusive_ptr<ObjectImpl<Notification> >& object, int value, std::vector<String>& location, const ValidationUtils& utils)
{
}

static void TIValidateNotificationNotifiedProblemUsers(const intrusive_ptr<ObjectImpl<Notification> >& object, const Array::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationPeriodRaw(const intrusive_ptr<ObjectImpl<Notification> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateNotificationServiceName(const intrusive_ptr<ObjectImpl<Notification> >& object, const String& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (value.IsEmpty())
		return;

}

static void TIValidateNotificationStashedNotifications(const intrusive_ptr<ObjectImpl<Notification> >& object, const Array::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationStateFilter(const intrusive_ptr<ObjectImpl<Notification> >& object, int value, std::vector<String>& location, const ValidationUtils& utils)
{
}

static void TIValidateNotificationStates(const intrusive_ptr<ObjectImpl<Notification> >& object, const Array::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationSuppressedNotifications(const intrusive_ptr<ObjectImpl<Notification> >& object, int value, std::vector<String>& location, const ValidationUtils& utils)
{
}

static void TIValidateNotificationTimes(const intrusive_ptr<ObjectImpl<Notification> >& object, const Dictionary::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

	do {
		const Dictionary::Ptr& dict = value;
		{
			ObjectLock olock(dict);
			for (const Dictionary::Pair& kv : dict) {
				const String& akey = kv.first;
				const Value& avalue = kv.second;
				location.emplace_back(akey);
				TIValidateNotification_1(object, akey, avalue, location, utils);
				location.pop_back();
			}
		}
		return;
	} while (0);

}

static void TIValidateNotificationTypeFilter(const intrusive_ptr<ObjectImpl<Notification> >& object, int value, std::vector<String>& location, const ValidationUtils& utils)
{
}

static void TIValidateNotificationTypes(const intrusive_ptr<ObjectImpl<Notification> >& object, const Array::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationUserGroupsRaw(const intrusive_ptr<ObjectImpl<Notification> >& object, const Array::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

static void TIValidateNotificationUsersRaw(const intrusive_ptr<ObjectImpl<Notification> >& object, const Array::Ptr& value, std::vector<String>& location, const ValidationUtils& utils)
{
	if (!value)
		return;

}

void ObjectImpl<Notification>::ValidateCommandEndpointRaw(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateCommandEndpointRaw(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("command_endpoint");
	TIValidateNotificationCommandEndpointRaw(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateCommandRaw(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateCommandRaw(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("command");
	TIValidateNotificationCommandRaw(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateHostName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateHostName(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("host_name");
	TIValidateNotificationHostName(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateInterval(const Lazy<double>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateInterval(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("interval");
	TIValidateNotificationInterval(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateLastNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateLastNotification(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("last_notification");
	TIValidateNotificationLastNotification(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateLastNotifiedStatePerUser(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateLastNotifiedStatePerUser(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("last_notified_state_per_user");
	TIValidateNotificationLastNotifiedStatePerUser(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateLastProblemNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateLastProblemNotification(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("last_problem_notification");
	TIValidateNotificationLastProblemNotification(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateNextNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateNextNotification(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("next_notification");
	TIValidateNotificationNextNotification(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateNoMoreNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateNoMoreNotifications(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("no_more_notifications");
	TIValidateNotificationNoMoreNotifications(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateNotificationNumber(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateNotificationNumber(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("notification_number");
	TIValidateNotificationNotificationNumber(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateNotifiedProblemUsers(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateNotifiedProblemUsers(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("notified_problem_users");
	TIValidateNotificationNotifiedProblemUsers(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidatePeriodRaw(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidatePeriodRaw(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("period");
	TIValidateNotificationPeriodRaw(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateServiceName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateServiceName(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("service_name");
	TIValidateNotificationServiceName(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateStashedNotifications(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStashedNotifications(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("stashed_notifications");
	TIValidateNotificationStashedNotifications(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateStateFilter(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStateFilter(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("state_filter_real");
	TIValidateNotificationStateFilter(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStates(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("states");
	TIValidateNotificationStates(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateSuppressedNotifications(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateSuppressedNotifications(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("suppressed_notifications");
	TIValidateNotificationSuppressedNotifications(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateTimes(const Lazy<Dictionary::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTimes(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("times");
	TIValidateNotificationTimes(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateTypeFilter(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTypeFilter(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("type_filter_real");
	TIValidateNotificationTypeFilter(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTypes(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("types");
	TIValidateNotificationTypes(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateUserGroupsRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateUserGroupsRaw(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("user_groups");
	TIValidateNotificationUserGroupsRaw(this, lvalue(), location, utils);
	location.pop_back();
}

void ObjectImpl<Notification>::ValidateUsersRaw(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateUsersRaw(lvalue, utils);
	std::vector<String> location;
	location.emplace_back("users");
	TIValidateNotificationUsersRaw(this, lvalue(), location, utils);
	location.pop_back();
}

}
#pragma GCC diagnostic pop
