+Extensible::Extensible()
+ : culled(false)
+{
+}
+
+CullResult Extensible::cull()
+{
+ FreeAllExtItems();
+ culled = true;
+ return classbase::cull();
+}
+
+void Extensible::FreeAllExtItems()
+{
+ for(ExtensibleStore::iterator i = extensions.begin(); i != extensions.end(); ++i)
+ {
+ i->first->free(this, i->second);
+ }
+ extensions.clear();
+}
+
+Extensible::~Extensible()
+{
+ if ((!extensions.empty() || !culled) && ServerInstance)
+ ServerInstance->Logs->Log("CULLLIST", LOG_DEBUG, "Extensible destructor called without cull @%p", (void*)this);
+}
+
+void ExtensionItem::FromInternal(Extensible* container, const std::string& value)
+{
+ FromNetwork(container, value);
+}
+
+void ExtensionItem::FromNetwork(Extensible* container, const std::string& value)
+{
+}
+
+std::string ExtensionItem::ToHuman(const Extensible* container, void* item) const
+{
+ // Try to use the network form by default.
+ std::string ret = ToNetwork(container, item);
+
+ // If there's no network form then fall back to the internal form.
+ if (ret.empty())
+ ret = ToInternal(container, item);
+
+ return ret;
+}
+
+std::string ExtensionItem::ToInternal(const Extensible* container, void* item) const
+{
+ return ToNetwork(container, item);
+}
+
+std::string ExtensionItem::ToNetwork(const Extensible* container, void* item) const
+{
+ return std::string();
+}
+
+std::string ExtensionItem::serialize(SerializeFormat format, const Extensible* container, void* item) const
+{
+ // Wrap the deprecated API with the new API.
+ switch (format)
+ {
+ case FORMAT_USER:
+ return ToHuman(container, item);
+ case FORMAT_INTERNAL:
+ case FORMAT_PERSIST:
+ return ToInternal(container, item);
+ case FORMAT_NETWORK:
+ return ToNetwork(container, item);
+ }
+ return "";
+}
+
+
+void ExtensionItem::unserialize(SerializeFormat format, Extensible* container, const std::string& value)
+{
+ // Wrap the deprecated API with the new API.
+ switch (format)
+ {
+ case FORMAT_USER:
+ break;
+ case FORMAT_INTERNAL:
+ case FORMAT_PERSIST:
+ FromInternal(container, value);
+ break;
+ case FORMAT_NETWORK:
+ FromNetwork(container, value);
+ break;
+ }
+}
+
+LocalStringExt::LocalStringExt(const std::string& Key, ExtensibleType exttype, Module* Owner)
+ : SimpleExtItem<std::string>(Key, exttype, Owner)
+{
+}
+
+LocalStringExt::~LocalStringExt()
+{
+}
+
+std::string LocalStringExt::ToInternal(const Extensible* container, void* item) const
+{
+ return item ? *static_cast<std::string*>(item) : std::string();
+}
+
+void LocalStringExt::FromInternal(Extensible* container, const std::string& value)
+{
+ set(container, value);
+}
+
+LocalIntExt::LocalIntExt(const std::string& Key, ExtensibleType exttype, Module* mod)
+ : ExtensionItem(Key, exttype, mod)
+{
+}
+
+LocalIntExt::~LocalIntExt()
+{
+}
+
+std::string LocalIntExt::ToInternal(const Extensible* container, void* item) const
+{
+ return ConvToStr(reinterpret_cast<intptr_t>(item));
+}
+
+void LocalIntExt::FromInternal(Extensible* container, const std::string& value)
+{
+ set(container, ConvToNum<intptr_t>(value));
+}
+
+intptr_t LocalIntExt::get(const Extensible* container) const
+{
+ return reinterpret_cast<intptr_t>(get_raw(container));
+}
+
+intptr_t LocalIntExt::set(Extensible* container, intptr_t value)
+{
+ if (value)
+ return reinterpret_cast<intptr_t>(set_raw(container, reinterpret_cast<void*>(value)));
+ else
+ return reinterpret_cast<intptr_t>(unset_raw(container));
+}
+
+void LocalIntExt::free(Extensible* container, void* item)