#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/usergroup.hpp"

namespace icinga
{

TypeImpl<User>::TypeImpl()
{ }

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

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

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

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

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

	switch (static_cast<int>(Utility::SDBM(name, 1))) {
		case 100:
			if (name == "display_name")
				return offset + 0;

			break;
		case 101:
			if (name == "email")
				return offset + 2;
			if (name == "enable_notifications")
				return offset + 10;

			break;
		case 103:
			if (name == "groups")
				return offset + 4;

			break;
		case 108:
			if (name == "last_notification")
				return offset + 9;

			break;
		case 112:
			if (name == "period")
				return offset + 1;
			if (name == "pager")
				return offset + 3;

			break;
		case 115:
			if (name == "states")
				return offset + 6;
			if (name == "state_filter_real")
				return offset + 8;

			break;
		case 116:
			if (name == "types")
				return offset + 5;
			if (name == "type_filter_real")
				return offset + 7;

			break;
	}

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

Field TypeImpl<User>::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", "display_name", "display_name", nullptr, 2, 0};
		case 1:
			return {1, "String", "period", "period", "TimePeriod", 514, 0};
		case 2:
			return {2, "String", "email", "email", nullptr, 2, 0};
		case 3:
			return {3, "String", "pager", "pager", nullptr, 2, 0};
		case 4:
			return {4, "Array", "groups", "groups", "UserGroup", 66818, 1};
		case 5:
			return {5, "Array", "types", "types", nullptr, 66, 1};
		case 6:
			return {6, "Array", "states", "states", nullptr, 66, 1};
		case 7:
			return {7, "Number", "type_filter_real", "type_filter_real", nullptr, 3073, 0};
		case 8:
			return {8, "Number", "state_filter_real", "state_filter_real", nullptr, 3073, 0};
		case 9:
			return {9, "Timestamp", "last_notification", "last_notification", nullptr, 4, 0};
		case 10:
			return {10, "Boolean", "enable_notifications", "enable_notifications", nullptr, 2, 0};
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

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

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

void TypeImpl<User>::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<User>::OnDisplayNameChanged.connect(callback);
			break;
		case 1:
			ObjectImpl<User>::OnPeriodRawChanged.connect(callback);
			break;
		case 2:
			ObjectImpl<User>::OnEmailChanged.connect(callback);
			break;
		case 3:
			ObjectImpl<User>::OnPagerChanged.connect(callback);
			break;
		case 4:
			ObjectImpl<User>::OnGroupsChanged.connect(callback);
			break;
		case 5:
			ObjectImpl<User>::OnTypesChanged.connect(callback);
			break;
		case 6:
			ObjectImpl<User>::OnStatesChanged.connect(callback);
			break;
		case 7:
			ObjectImpl<User>::OnTypeFilterChanged.connect(callback);
			break;
		case 8:
			ObjectImpl<User>::OnStateFilterChanged.connect(callback);
			break;
		case 9:
			ObjectImpl<User>::OnLastNotificationChanged.connect(callback);
			break;
		case 10:
			ObjectImpl<User>::OnEnableNotificationsChanged.connect(callback);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

	if (2 & types)
		ValidateDisplayName(Lazy<String>([this]() { return GetDisplayName(); }), utils);
	if (2 & types)
		ValidatePeriodRaw(Lazy<String>([this]() { return GetPeriodRaw(); }), utils);
	if (2 & types)
		ValidateEmail(Lazy<String>([this]() { return GetEmail(); }), utils);
	if (2 & types)
		ValidatePager(Lazy<String>([this]() { return GetPager(); }), utils);
	if (2 & types)
		ValidateGroups(Lazy<Array::Ptr>([this]() { return GetGroups(); }), utils);
	if (2 & types)
		ValidateTypes(Lazy<Array::Ptr>([this]() { return GetTypes(); }), utils);
	if (2 & types)
		ValidateStates(Lazy<Array::Ptr>([this]() { return GetStates(); }), utils);
	if (1 & types)
		ValidateTypeFilter(Lazy<int>([this]() { return GetTypeFilter(); }), utils);
	if (1 & types)
		ValidateStateFilter(Lazy<int>([this]() { return GetStateFilter(); }), utils);
	if (4 & types)
		ValidateLastNotification(Lazy<Timestamp>([this]() { return GetLastNotification(); }), utils);
	if (2 & types)
		ValidateEnableNotifications(Lazy<bool>([this]() { return GetEnableNotifications(); }), utils);
}

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

void ObjectImpl<User>::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<User>::SimpleValidateEmail(const Lazy<String>& value, const ValidationUtils& utils)
{
}

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

void ObjectImpl<User>::SimpleValidateGroups(const Lazy<Array::Ptr>& avalue, const ValidationUtils& utils)
{
	if (!avalue())
		BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "groups" }, "Attribute must not be empty."));

	if (avalue()) {
		ObjectLock olock(avalue());
		for (const Value& value : avalue()) {
			if (!value.IsEmpty() && !value.IsString())
				BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), { "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), { "groups" }, "Object '" + value + "' of type 'UserGroup' does not exist."));
		}
	}
}

void ObjectImpl<User>::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, "User") << "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<User>::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, "User") << "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<User>::SimpleValidateTypeFilter(const Lazy<int>& value, const ValidationUtils& utils)
{
}

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

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

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

ObjectImpl<User>::ObjectImpl()
{
	SetDisplayName(GetDefaultDisplayName(), true);
	SetPeriodRaw(GetDefaultPeriodRaw(), true);
	SetEmail(GetDefaultEmail(), true);
	SetPager(GetDefaultPager(), true);
	SetGroups(GetDefaultGroups(), true);
	SetTypeFilter(GetDefaultTypeFilter(), true);
	SetStateFilter(GetDefaultStateFilter(), true);
	SetLastNotification(GetDefaultLastNotification(), true);
	SetEnableNotifications(GetDefaultEnableNotifications(), true);
}

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

void ObjectImpl<User>::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:
			SetDisplayName(value, suppress_events, cookie);
			break;
		case 1:
			SetPeriodRaw(value, suppress_events, cookie);
			break;
		case 2:
			SetEmail(value, suppress_events, cookie);
			break;
		case 3:
			SetPager(value, suppress_events, cookie);
			break;
		case 4:
			SetGroups(value, suppress_events, cookie);
			break;
		case 5:
			SetTypes(value, suppress_events, cookie);
			break;
		case 6:
			SetStates(value, suppress_events, cookie);
			break;
		case 7:
			SetTypeFilter(value, suppress_events, cookie);
			break;
		case 8:
			SetStateFilter(value, suppress_events, cookie);
			break;
		case 9:
			SetLastNotification(value, suppress_events, cookie);
			break;
		case 10:
			SetEnableNotifications(value, suppress_events, cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

Value ObjectImpl<User>::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 GetDisplayName();
		case 1:
			return GetPeriodRaw();
		case 2:
			return GetEmail();
		case 3:
			return GetPager();
		case 4:
			return GetGroups();
		case 5:
			return GetTypes();
		case 6:
			return GetStates();
		case 7:
			return GetTypeFilter();
		case 8:
			return GetStateFilter();
		case 9:
			return GetLastNotification();
		case 10:
			return GetEnableNotifications();
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<User>::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:
			ValidateDisplayName(lvalue, utils);
			break;
		case 1:
			ValidatePeriodRaw(lvalue, utils);
			break;
		case 2:
			ValidateEmail(lvalue, utils);
			break;
		case 3:
			ValidatePager(lvalue, utils);
			break;
		case 4:
			ValidateGroups(lvalue, utils);
			break;
		case 5:
			ValidateTypes(lvalue, utils);
			break;
		case 6:
			ValidateStates(lvalue, utils);
			break;
		case 7:
			ValidateTypeFilter(lvalue, utils);
			break;
		case 8:
			ValidateStateFilter(lvalue, utils);
			break;
		case 9:
			ValidateLastNotification(lvalue, utils);
			break;
		case 10:
			ValidateEnableNotifications(lvalue, utils);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

void ObjectImpl<User>::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:
			NotifyDisplayName(cookie);
			break;
		case 1:
			NotifyPeriodRaw(cookie);
			break;
		case 2:
			NotifyEmail(cookie);
			break;
		case 3:
			NotifyPager(cookie);
			break;
		case 4:
			NotifyGroups(cookie);
			break;
		case 5:
			NotifyTypes(cookie);
			break;
		case 6:
			NotifyStates(cookie);
			break;
		case 7:
			NotifyTypeFilter(cookie);
			break;
		case 8:
			NotifyStateFilter(cookie);
			break;
		case 9:
			NotifyLastNotification(cookie);
			break;
		case 10:
			NotifyEnableNotifications(cookie);
			break;
		default:
			throw std::runtime_error("Invalid field ID.");
	}
}

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

String ObjectImpl<User>::GetDisplayName() const
{

			String displayName = m_DisplayName.load();
			if (displayName.IsEmpty())
				return GetName();
			else
				return displayName;
		
}

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

String ObjectImpl<User>::GetEmail() const
{
	return m_Email.load();
}

String ObjectImpl<User>::GetPager() const
{
	return m_Pager.load();
}

Array::Ptr ObjectImpl<User>::GetGroups() const
{
	return m_Groups.load();
}

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

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

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

bool ObjectImpl<User>::GetEnableNotifications() const
{
	return m_EnableNotifications.load();
}

void ObjectImpl<User>::SetDisplayName(const String& value, bool suppress_events, const Value& cookie)
{
	m_DisplayName.store(value);
	if (!suppress_events) {
		NotifyDisplayName(cookie);
	}

}

void ObjectImpl<User>::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<User>::SetEmail(const String& value, bool suppress_events, const Value& cookie)
{
	m_Email.store(value);
	if (!suppress_events) {
		NotifyEmail(cookie);
	}

}

void ObjectImpl<User>::SetPager(const String& value, bool suppress_events, const Value& cookie)
{
	m_Pager.store(value);
	if (!suppress_events) {
		NotifyPager(cookie);
	}

}

void ObjectImpl<User>::SetGroups(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
	Value oldValue = GetGroups();
	auto *dobj = dynamic_cast<ConfigObject *>(this);
	m_Groups.store(value);
	if (!dobj || dobj->IsActive())
		TrackGroups(oldValue, value);
	if (!suppress_events) {
		NotifyGroups(cookie);
		if (!dobj || dobj->IsActive())
			OnGroupsChangedWithOldValue(static_cast<User *>(this), oldValue, value);
	}

}

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

}

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

}

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

}

void ObjectImpl<User>::SetEnableNotifications(bool value, bool suppress_events, const Value& cookie)
{
	m_EnableNotifications.store(value);
	if (!suppress_events) {
		NotifyEnableNotifications(cookie);
	}

}

void ObjectImpl<User>::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<User>::TrackGroups(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<User>::NavigatePeriodRaw() const
{
	
			return TimePeriod::GetByName(GetPeriodRaw());
		
}

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

	TrackPeriodRaw(Empty, GetPeriodRaw());
	TrackGroups(Empty, GetGroups());
}

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

	TrackPeriodRaw(GetPeriodRaw(), Empty);
	TrackGroups(GetGroups(), Empty);
}

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

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

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

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

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

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

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

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

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

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

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

String ObjectImpl<User>::GetDefaultDisplayName() const
{
	return String();
}

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

String ObjectImpl<User>::GetDefaultEmail() const
{
	return String();
}

String ObjectImpl<User>::GetDefaultPager() const
{
	return String();
}

Array::Ptr ObjectImpl<User>::GetDefaultGroups() const
{
	 return new Array(); 
}

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

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

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

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

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

bool ObjectImpl<User>::GetDefaultEnableNotifications() const
{
	 return true; 
}


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


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


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


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


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


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


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


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


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


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


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


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

void ObjectImpl<User>::ValidateDisplayName(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateDisplayName(lvalue, utils);
}

void ObjectImpl<User>::ValidateEmail(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEmail(lvalue, utils);
}

void ObjectImpl<User>::ValidateEnableNotifications(const Lazy<bool>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateEnableNotifications(lvalue, utils);
}

void ObjectImpl<User>::ValidateGroups(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateGroups(lvalue, utils);
}

void ObjectImpl<User>::ValidateLastNotification(const Lazy<Timestamp>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateLastNotification(lvalue, utils);
}

void ObjectImpl<User>::ValidatePager(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidatePager(lvalue, utils);
}

void ObjectImpl<User>::ValidatePeriodRaw(const Lazy<String>& lvalue, const ValidationUtils& utils)
{
	SimpleValidatePeriodRaw(lvalue, utils);
}

void ObjectImpl<User>::ValidateStateFilter(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStateFilter(lvalue, utils);
}

void ObjectImpl<User>::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateStates(lvalue, utils);
}

void ObjectImpl<User>::ValidateTypeFilter(const Lazy<int>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTypeFilter(lvalue, utils);
}

void ObjectImpl<User>::ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
	SimpleValidateTypes(lvalue, utils);
}

}
#pragma GCC diagnostic pop
