+ ret.push_back('1');
+
+ return ret;
+ }
+}
+
+Cap::ExtItem::ExtItem(Module* mod)
+ : LocalIntExt("caps", ExtensionItem::EXT_USER, mod)
+{
+}
+
+std::string Cap::ExtItem::ToHuman(const Extensible* container, void* item) const
+{
+ return SerializeCaps(container, item, true);
+}
+
+std::string Cap::ExtItem::ToInternal(const Extensible* container, void* item) const
+{
+ return SerializeCaps(container, item, false);
+}
+
+void Cap::ExtItem::FromInternal(Extensible* container, const std::string& value)
+{
+ LocalUser* user = IS_LOCAL(static_cast<User*>(container));
+ if (!user)
+ return; // Can't happen
+
+ // Process the cap protocol version which is a single character at the end of the serialized string
+ const char verchar = *value.rbegin();
+ if (verchar == '2')
+ managerimpl->Set302Protocol(user);
+
+ // Remove the version indicator from the string passed to HandleReq
+ std::string caplist(value, 0, value.size()-1);
+ managerimpl->HandleReq(user, caplist);
+}
+
+class CapMessage : public Cap::MessageBase
+{
+ public:
+ CapMessage(LocalUser* user, const std::string& subcmd, const std::string& result)
+ : Cap::MessageBase(subcmd)
+ {
+ SetUser(user);
+ PushParamRef(result);
+ }
+};
+
+class CommandCap : public SplitCommand
+{
+ Events::ModuleEventProvider evprov;
+ Cap::ManagerImpl manager;
+ ClientProtocol::EventProvider protoevprov;
+
+ void DisplayResult(LocalUser* user, const std::string& subcmd, std::string& result)
+ {
+ if (*result.rbegin() == ' ')
+ result.erase(result.end()-1);
+ DisplayResult2(user, subcmd, result);
+ }
+
+ void DisplayResult2(LocalUser* user, const std::string& subcmd, const std::string& result)
+ {
+ CapMessage msg(user, subcmd, result);
+ ClientProtocol::Event ev(protoevprov, msg);
+ user->Send(ev);
+ }
+
+ public:
+ LocalIntExt holdext;
+
+ CommandCap(Module* mod)
+ : SplitCommand(mod, "CAP", 1)
+ , evprov(mod, "event/cap")
+ , manager(mod, evprov)
+ , protoevprov(mod, name)
+ , holdext("cap_hold", ExtensionItem::EXT_USER, mod)
+ {
+ works_before_reg = true;
+ }
+
+ CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE
+ {
+ if (user->registered != REG_ALL)
+ holdext.set(user, 1);
+
+ std::string subcommand(parameters[0].length(), ' ');
+ std::transform(parameters[0].begin(), parameters[0].end(), subcommand.begin(), ::toupper);
+
+ if (subcommand == "REQ")