+ // IRCv3 capability negotiation
+
+ /**
+ * Checks if a given capability is enabled.
+ *
+ * @param[in] capability Name of capability
+ * @returns True if enabled, otherwise false
+ */
+ inline bool capEnabled(const QString &capability) const { return _capsSupported.contains(capability); }
+
+ /**
+ * Checks if capability negotiation is currently ongoing.
+ *
+ * @returns True if in progress, otherwise false
+ */
+ inline bool capNegotiationInProgress() const { return !_capsQueued.empty(); }
+
+ /**
+ * Gets the value of an enabled or pending capability, e.g. sasl=plain.
+ *
+ * @param[in] capability Name of capability
+ * @returns Value of capability if one was specified, otherwise empty string
+ */
+ QString capValue(const QString &capability) const;
+
+ /**
+ * Gets the next capability to request, removing it from the queue.
+ *
+ * @returns Name of capability to request
+ */
+ QString takeQueuedCap();
+
+ // Specific capabilities for easy reference
+
+ /**
+ * Gets the status of the sasl authentication capability.
+ *
+ * http://ircv3.net/specs/extensions/sasl-3.2.html
+ *
+ * @returns True if SASL authentication is enabled, otherwise false
+ */
+ inline bool useCapSASL() const { return capEnabled("sasl"); }
+
+ /**
+ * Gets the status of the away-notify capability.
+ *
+ * http://ircv3.net/specs/extensions/away-notify-3.1.html
+ *
+ * @returns True if away-notify is enabled, otherwise false
+ */
+ inline bool useCapAwayNotify() const { return capEnabled("away-notify"); }
+
+ /**
+ * Gets the status of the account-notify capability.
+ *
+ * http://ircv3.net/specs/extensions/account-notify-3.1.html
+ *
+ * @returns True if account-notify is enabled, otherwise false
+ */
+ inline bool useCapAccountNotify() const { return capEnabled("account-notify"); }
+
+ /**
+ * Gets the status of the extended-join capability.
+ *
+ * http://ircv3.net/specs/extensions/extended-join-3.1.html
+ *
+ * @returns True if extended-join is enabled, otherwise false
+ */
+ inline bool useCapExtendedJoin() const { return capEnabled("extended-join"); }
+
+ /**
+ * Gets the status of the userhost-in-names capability.
+ *
+ * http://ircv3.net/specs/extensions/userhost-in-names-3.2.html
+ *
+ * @returns True if userhost-in-names is enabled, otherwise false
+ */
+ inline bool useCapUserhostInNames() const { return capEnabled("userhost-in-names"); }
+
+ /**
+ * Gets the status of the multi-prefix capability.
+ *
+ * http://ircv3.net/specs/extensions/multi-prefix-3.1.html
+ *
+ * @returns True if multi-prefix is enabled, otherwise false
+ */
+ inline bool useCapMultiPrefix() const { return capEnabled("multi-prefix"); }
+