diff --git a/src/XML/fed/AbstractPseudonymType.php b/src/XML/fed/AbstractPseudonymType.php
new file mode 100644
index 00000000..75ff7c20
--- /dev/null
+++ b/src/XML/fed/AbstractPseudonymType.php
@@ -0,0 +1,213 @@
+setElements($children);
+ $this->setAttributesNS($namespacedAttributes);
+ }
+
+
+ /**
+ * Collect the value of the pseudonymBasis-property
+ *
+ * @return \SimpleSAML\WSSecurity\XML\fed\PseudonymBasis
+ */
+ public function getPseudonymBasis(): PseudonymBasis
+ {
+ return $this->pseudonymBasis;
+ }
+
+
+ /**
+ * Collect the value of the relativeTo-property
+ *
+ * @return \SimpleSAML\WSSecurity\XML\fed\RelativeTo
+ */
+ public function getRelativeTo(): RelativeTo
+ {
+ return $this->relativeTo;
+ }
+
+
+ /**
+ * Collect the value of the expires-property
+ *
+ * @return \SimpleSAML\WSSecurity\XML\wsu\Expires|null
+ */
+ public function getExpires(): ?Expires
+ {
+ return $this->expires;
+ }
+
+
+ /**
+ * Collect the value of the securityToken-property
+ *
+ * @return \SimpleSAML\WSSecurity\XML\fed\SecurityToken[]
+ */
+ public function getSecurityToken(): array
+ {
+ return $this->securityToken;
+ }
+
+
+ /**
+ * Collect the value of the proofToken-property
+ *
+ * @return \SimpleSAML\WSSecurity\XML\fed\ProofToken[]
+ */
+ public function getProofToken(): array
+ {
+ return $this->proofToken;
+ }
+
+
+ /**
+ * Create an instance of this object from its XML representation.
+ *
+ * @param \DOMElement $xml
+ * @return static
+ *
+ * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
+ * if the qualified name of the supplied element is wrong
+ */
+ public static function fromXML(DOMElement $xml): static
+ {
+ Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
+ Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
+
+ $children = $pseudonymBasis = $relativeTo = $expires = $securityToken = $proofToken = [];
+ foreach ($xml->childNodes as $child) {
+ if (!($child instanceof DOMElement)) {
+ continue;
+ } elseif ($child->namespaceURI === static::NS) {
+ if ($child->localName === 'PseudonymBasis') {
+ $pseudonymBasis[] = PseudonymBasis::fromXML($child);
+ } elseif ($child->localName === 'RelativeTo') {
+ $relativeTo[] = RelativeTo::fromXML($child);
+ } elseif ($child->localName === 'SecurityToken') {
+ $securityToken[] = SecurityToken::fromXML($child);
+ } elseif ($child->localName === 'ProofToken') {
+ $proofToken[] = ProofToken::fromXML($child);
+ } else {
+ $children[] = new Chunk($child);
+ }
+ continue;
+ } elseif ($child->namespaceURI === C::NS_SEC_UTIL) {
+ $expires[] = Expires::fromXML($child);
+ continue;
+ }
+
+ $children[] = new Chunk($child);
+ }
+
+ return new static(
+ array_pop($pseudonymBasis),
+ array_pop($relativeTo),
+ array_pop($expires),
+ $securityToken,
+ $proofToken,
+ $children,
+ self::getAttributesNSFromXML($xml),
+ );
+ }
+
+
+ /**
+ * Add this PseudonymType to an XML element.
+ *
+ * @param \DOMElement $parent The element we should append this username token to.
+ * @return \DOMElement
+ */
+ public function toXML(DOMElement $parent = null): DOMElement
+ {
+ $e = parent::instantiateParentElement($parent);
+
+ $this->getPseudonymBasis()->toXML($e);
+ $this->getRelativeTo()->toXML($e);
+ $this->getExpires()?->toXML($e);
+
+ foreach ($this->getSecurityToken() as $st) {
+ $st->toXML($e);
+ }
+
+ foreach ($this->getProofToken() as $pt) {
+ $pt->toXML($e);
+ }
+
+ foreach ($this->getAttributesNS() as $attr) {
+ $attr->toXML($e);
+ }
+
+ /** @psalm-var \SimpleSAML\XML\SerializableElementInterface $child */
+ foreach ($this->getElements() as $child) {
+ if (!$child->isEmptyElement()) {
+ $child->toXML($e);
+ }
+ }
+
+ return $e;
+ }
+}
diff --git a/src/XML/fed/PseudonymType.php b/src/XML/fed/PseudonymType.php
new file mode 100644
index 00000000..342fa26c
--- /dev/null
+++ b/src/XML/fed/PseudonymType.php
@@ -0,0 +1,14 @@
+
+
+ Basis
+
+
+ Relative
+
+ 2001-10-13T09:00:00Z
+
+ Security
+
+
+ Proof
+
+ Some
+