diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 0000000..f0a1aae
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,37 @@
+FROM amazonlinux:2023.5.20240730.0
+
+# Install necessary packages
+RUN dnf -y install \
+ # these switches are used to force full java-17-corretto dependencies installation
+ ant -x java-22-amazon-corretto-headless -x java-21-amazon-corretto-headless \
+ # awscli \
+ tar \
+ gzip \
+ openssl \
+ unzip \
+ wget \
+ which \
+ && dnf clean all
+
+RUN mkdir -p /mda/inc/inc-meta
+COPY . /mda/inc/inc-meta
+
+# Set environment variables
+#
+# Note: XMLSECTOOL_PATH specifies the path to the xmlsectool installed with the
+# metadata aggregator. We use xmlsectool in startup.sh, but that will no
+# longer be required if we update the inc-meta MDA rules to check the
+# signature of the source aggregate.
+ENV INC_MD_VERIFIED_PATH=/metadata/inc-metadata.xml \
+ XMLSECTOOL_PATH=/mda/inc/inc-meta/tools/xmlsectool-3.0.0/xmlsectool.sh \
+ JAVA_HOME=/ \
+ JVMOPTS=-Xmx2048m \
+ MDQ_HOME=/mda/inc/inc-meta/ \
+ WWW_HOME=/mdqwww \
+ CERTGEN_MDQSIGN_SUBJECT=/C=US/ST=State/L=City/O=OrgName/CN=mdqsigning.example.org \
+ CERTGEN_WWW_SUBJECT=/C=US/ST=State/L=City/O=OrgName/CN=mdqweb.example.org
+
+# Create metadata output directory
+RUN mkdir /metadata
+
+# CMD ["/usr/local/bin/startup.sh"]
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..bb193d8
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,10 @@
+{
+ "build": {
+ "dockerfile": "Dockerfile"
+ },
+ "settings": {
+ "terminal.integrated.cwd": "/mda/inc/inc-meta/tests/incommon/scripts"
+ },
+ "workspaceMount": "source=${localWorkspaceFolder},target=/mda/inc/inc-meta,type=bind",
+ "workspaceFolder": "/mda/inc/inc-meta"
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index bf81465..affa2ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ Thumbs.db
/build/uai.html
/build/dml.html
/build/locations_noports.txt
+/build/mdq
# /charting/
/charting/cache
diff --git a/build.xml b/build.xml
index 9e96ff3..861a6fb 100644
--- a/build.xml
+++ b/build.xml
@@ -3076,6 +3076,23 @@
Generation complete.
+
+
+
+
+ Generating InCommon signed import aggregate in ${mda.inc.imported.xml}
+ (IdP-only aggregate in ${mda.inc.imported-idp.xml})
+ from production aggregate in ${mda.inc.production.xml}
+ and selected eduGAIN entities from ${mda.inc.edugain.xml}
+ signed using a local key
+
+ Generation complete.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/incommon/data/mda-signing.crt b/tests/incommon/data/mda-signing.crt
new file mode 100644
index 0000000..cf4a28a
--- /dev/null
+++ b/tests/incommon/data/mda-signing.crt
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIUEzalCDbvJJYJ7Zm1p/6gfHy9cuMwDQYJKoZIhvcNAQEL
+BQAwXzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
+MRAwDgYDVQQKDAdPcmdOYW1lMR8wHQYDVQQDDBZtZHFzaWduaW5nLmV4YW1wbGUu
+b3JnMB4XDTI1MDUwODE2MzQwMloXDTM1MDUwNjE2MzQwMlowXzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRAwDgYDVQQKDAdPcmdO
+YW1lMR8wHQYDVQQDDBZtZHFzaWduaW5nLmV4YW1wbGUub3JnMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEArE6DLEYQ4Aw6UV4rE7BLkqsgPjqvnJf2ZXAt
+n2tzSUjrqDpzFmBxcx8gnPHo9bm4VpOko3NkW3mdjFmWeF1Q7v0tWKNBpC8/s6Pr
+5EudPsamfbHNMJAd9E9UaCKko6BmNdc2+BQBwU5DFRDSmedebT7CW7SLoabQPrqx
+RUXzgFeJQ+MR9LnTq2zVyzR+BU0fU7lgXDgcPN0sfI43vlGYdkTzwSgZ0Tcd8UY9
+DaMPgPpju6wbufv7GfQQVTAGdO/Y456dyRmlUKF1J0rIvxtw0VHMBd0Ox8/cmYZS
+u+3llXBFoVK6NisS9dCr0MH78AsdeDxh6PBwJPVUTnU/2rvSjwIDAQABo1MwUTAd
+BgNVHQ4EFgQUZdLMKhHzOVQ3n5lyyxsM/iH1ojcwHwYDVR0jBBgwFoAUZdLMKhHz
+OVQ3n5lyyxsM/iH1ojcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
+AQEARX8WEYXdqw0o+ROe2tpeaFYODontvTs1Ee5mD17EN6SCGX2EUnx88KvhQ0cE
+z4NltOBZr1PqXSVP66Ci6zibDZvIGQLHQ6luWeX1M5OEVSwUBprN1CT3LZgQEBR/
+VLwWKYTNAFooO/MynuLlCrtUNVc8OWmXd8jQ7GxD4B8rhVkIkC3J3HsSHq9/Di6o
++SkZVb+Qc14U6KNYmhdbnONHx3Y2m7d7l6bdfwkvXCzP8LJH3RGZAvQHV7I/Y6E2
+KweQEIQ+0rZD0t8Sv24vjZPWoNLKsQ1I1QCFFQHozt48ynbOhB492sOLcWBxlwie
+5aF2XSbrY506ihuDqUJ7ub17rg==
+-----END CERTIFICATE-----
diff --git a/tests/incommon/data/mda-signing.key b/tests/incommon/data/mda-signing.key
new file mode 100644
index 0000000..7f7e703
--- /dev/null
+++ b/tests/incommon/data/mda-signing.key
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,936CC9FA7554348A97B0D5D26FE96EEE
+
+VvadNjFoGmpsvpu5dV2KWBwSo/QTCZ+1NxWSpN0H+jPa9540T3rQ1a4egwQaHl9K
+NOUg7hERj1n0WLjxPXAWrx3BO5X6ECQFjHGQiIsXakfIF23uPLYqLAKEVsk0u6Ft
+KOZUDRlPM3jd0wH43shlCSKM0CzggVwxCXrP0Unyk2Ttzr/lIRUAC9o6qsPN1O35
+cdyR/ykt4ec61SS6KaJtfvKEUdOZx9GbnmU5qzxQMr6+PM4p5ITfjInFpNbu6HVg
+AXLV8X3ojP6tqiNGa9UjzUNsNDtSLI0MCh2AIt4Sf+4uV5+HoT6ePjuBQUEmH5G+
+8aMCCF8baLPxDEd7VWQD9Bh4l+R/xETAH2BGGq6++4pAqKR7S56tAXzGkUqDj7WY
+qlrNr2uGynQ8KK5G/xBjnkJ/BmeM+Vp5JdxFCXDNXtLfeQchmKGPA+2zgBOoXYyT
+AtMs95vWWFOGQ2xl4YqMJ2R51FTNuHOAHFDUKOKy5frzAH3t55ycmpp7xepMWala
+z/fp18nfBBTDDZqcD+Lclv7JD5i80SoSCo07G32VlvQiFE5s7BZ/8CPKahisSHHM
+RPC9hVmS8IaPwEWnBKCvGx1CQRYVhW1YXQ1bK6/HzYwN3bmqwBxI3sNN54Ek9KUR
+Jea4Ky8x0TR5Fh9sq+nyTEm4ZCfLZeu6b8mo9aIKQca0GCFdQl4eMIqzxsBig9+P
+qTe4LgkGUgeI8q0j4p8+SorktMR3oRlXLCeAswf8Qh3DGiAmi/faaQQg7RsRjgnR
+jyhajrxnwQosWl1/dY1+HjSISNX655/Xz37H+wQvuu9em12kRDrc8f5PfZI7af2a
+ZQX93KQcpxNymMM64FdXxiEo3+9OVyZTMH99PbDmxxHGxmJWwkmUqPXT2x0UoX+/
+Apwuk4Kp7QhbWjdAxarQYMIRmv44L6yZ0EfJyIfMz3ALTWqGekgGO2Vr5BRp0sNN
+CezLiNEG77N1hXydf2mIKFAkdRgopiqYHUkSZjKy6Xd9kUtvyODbMP4kJLROzTGl
+L63u0IV+8zu301uS8VGovKAv/mAYQX5C+fKW+jYXnxSPWQvAk7A/q/H9gb7nGK7t
+4rZiFhRjPmBgdMtjlsiO1AOPp4Ngfks5wjAGP00JqzYz9Ldfv9teUXqPma/Wanu+
+6r89uPicwrJCo8C587M6SdGDWBQ74c75MbhP5T/0Xev2h4VTeAOjkkrVUCM59rxH
+r38FNnZd1Xk/DOhdVHSmX8Gm/FFR0ibS0My6flDklfCoX1pn2JuzpXnZqoNocG2J
+RytaJUktplxyNci1Ljh2ifijvbUFHOhBDCIPn9yKtHyY6BhkWLY08/OHUJXYdC0j
+LmVGisgIRwAk/HV97z2oIxMfHf+LCvCN0xAirGBAeETiYqluW6BSbaqw7sT+ATpK
+nHLok5nhPYz+RfHl+SV5a3Cb7VKTpiUutwF6DkurvbJ+xSxiFxCgNDtXN0uz51b7
+4QO2kuB48AzUgJtm3/TvJ4E4Bf8RIcKiuC8jcqExDeJ5r+XrIapN8GrbP7DWLL9v
+Iy00z+4QJhLBPQ148fwmxVgU5xg955zBwDbnqdpa4PjgpQDi3rsYPjsG9zIJq/Uv
+-----END RSA PRIVATE KEY-----
diff --git a/tests/incommon/data/test-cert.pem b/tests/incommon/data/test-cert.pem
new file mode 100644
index 0000000..2cd50be
--- /dev/null
+++ b/tests/incommon/data/test-cert.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICsjCCAZoCCQCIj9cyx103KjANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0ZXN0LmV4YW1w
+bGUub3JnMB4XDTE4MTAyMTE3MTc0NloXDTE5MTAyMTE3MTc0NlowGzEZMBcGA1UEAwwQdGVzdC5l
+eGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/lgbjJiZFJJBb9bsYN
+XKAdDzMmLxjP1ikR/zAkYMIMfNZZiJLsKdREs1tzDio6h1FgQ+jgiDwjpBGENfoKGDxg+DiViqIy
+wTh7zRduLfkVqgUHekZFPgn1T2SQb8IZ6EWOVZJwJyjffwiR2VfF5bUrSf+nvRen3wxxQM40Hb5T
+tzRRVtkWr1RoB+j4mxXdShBmk+aVFltD97aM3B/+ekW2deGAogF4+uKo3L0ikAKLjjz3uWny4kHV
+GMg+H6PxJWAZHcnHfH/EgI5F1E+H1MIi/4VCdek5BAsFlwPufEy+ah6FUNaa7xniOKm8kElzbMNa
+hd4IowqyZ9TPnKPPOg0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYSDTrlmXMILckXtSQqkJOrZ0
+BlQi+IIRV4xbYknTDb107RDm8RXHkpc6A8W8jcwU0djmgmuDlBzhvnzSwE+gxqU1/W3eWtz60rcA
+PwmF+r9wYvVnCmPkUw8RWPasrzRPQMzehA/251Zx6tMPwBkEqOyagi1sq1mZbQSlF08jVBL+J6tb
+P2yRc3pp19dGApL6klIA5Mi5+VmxwMtoQ5v6qHT1oDxeKWcSDNVeSYYoBiLB8hFN692NsDtY9Urd
+pBpLa6CxWSKZd11+sFclGfqh35+2PBfHSCiAFZ8RL2qsq5uIDz53XgfB33j723uF4xGsS80lMSOO
+LT9+TC1qkYRchQ==
+-----END CERTIFICATE-----
diff --git a/tests/incommon/data/test-edugain-metadata.xml b/tests/incommon/data/test-edugain-metadata.xml
new file mode 100644
index 0000000..9d501a6
--- /dev/null
+++ b/tests/incommon/data/test-edugain-metadata.xml
@@ -0,0 +1,216 @@
+
+ BH6UzP4yTXQCUUgZxVwzsU7kTgDlbb4+DRkU21UDcyY=wgiyVKQC3RX/fr9zf87Ij1tAN04KJr5bIijt55qHnIQrpd4PUSEjdEK8Uuv6gcU4Wq22hdy5CfbRw8nk0QhXtYQruZBPyzbu5IfRi0vatd5DdMbgFXWXQLZ86yR2qciC+bfJW2vlCJmVzNH6ZakkaTkNAdyvO3e6cs6NoKv9IKLCcGVR9pj+RNKORq4JyKcawd9J+6UDiOAPIr1nQdGnZyqK+5uuuHCU6P63l50XjoYrfQ5cAP4jY2EjvaSbB+lJ7xgjWq6/Zoo2fDRuq6aQVYVgmMHM80SNCoIO151WhBo1IBrnvNpgd8KnSIEcKfs0velg3Pxajp4SlZrEnfXaM9dVj15fzWVFJ9yjq77HtHFeAvs8WL48RjbEywgtCIz28U9u4WwuY5OdI9Kj1k8pwkBh5lFQZlYkoy/UikIfU1NDXBd7vRIoAYaoGBNixkfwfaQJeYkG+9AMv/qJrj8V17ReC0j0Pkuf0c5Lb1UQg2WfVEEGA8NWDczuRVJw9/CBqqyTbnRgs1CFgwsr4cLRHBY1F2al/qei/374UuhIanNXY8LCc7otbysTfqvk4PhEUCEs1ZZ6fXer4K8fPvnTOTuxH4TfLjtGK+se3oK/P5tKGsBSxSvtBL2NnXM0UukfcROwEN2DIWi/PB2+w61ZkrsS4doIZ/APBdRRR/x66bg=MIIFSzCCAzOgAwIBAgIUY99qGOKOxV+iz/+tWfwixuh0CpowDQYJKoZIhvcNAQEL
+BQAwNTEOMAwGA1UECgwFR0VBTlQxIzAhBgNVBAMMGmVkdUdBSU4gUlNBIFNpZ25l
+ciBDQSAyMDIyMB4XDTIyMDMwODA5MjIzMloXDTQyMDMwODA5MjIzMlowNTEOMAwG
+A1UECgwFR0VBTlQxIzAhBgNVBAMMGmVkdUdBSU4gUlNBIFNpZ25lciBDQSAyMDIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1H2PdoPu4QLKqfcg7uC9
+rzPA04tdUAdbdnByPddLFEeOfYUxkzbbmrEkUbvL65YAibbxJwEioIQTgSwrtoHL
+nT/puQnux7T7en5qYRDLpX7qR2ssNN4TiXS8Z8qDmI+LQw9YnNpI35qHguHKBr2J
+kbM7qdq6+8KQD0aK+7FyPcGsYDnOoLlJ8cfmIxY7mumfEbiAni/z/pP4Mo2g4rf4
+GY8nhHudJea6qSvxIGLRy7GlL0VOY/PCnxl+EPYSRZYEJEc9jNXsepIzpSU5AM6r
+kwO6Ue+5crYtJMey07b0IEaFNHc/Omt5KY+UO0ewYnjcdnKa5MWgTntxs+AzDiMp
+dIXGemo2SKfcqmAPUW8bLNFABdwxq/Bhcsqb1K+e4C61dPyI2rDWpaM+NIRLvpLD
+jDZsaMnhZK6/ezxKV4h94YKSF1fTunZsyEtaot53ztXjUgvALMFb/XqAes3V+o7D
+WSQ1JYvifkk2agzjel+A9m+e7UgaBuuqfwpkClgMExrB8CJI1xBuAHI/yldoaITL
+auPKWYb+bXpkPg8BznYhGIA9TSqTPNwd0WmH1SZ1lmINuN8ElKRmi+DKkKe9NRXf
+/jS3PKg9NnrFS9fnhTeaI8ikVSh8qPDfsUYtuDF1SL7B+27yT3+7WKCD6gqu/J4P
+8iYELM++C29VgApxlHnLdO8CAwEAAaNTMFEwHQYDVR0OBBYEFEgBijs8UaPzEW81
+hco9oyNH27b3MB8GA1UdIwQYMBaAFEgBijs8UaPzEW81hco9oyNH27b3MA8GA1Ud
+EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAMTQKHe5mybVO4hlTHeha1xo
+/OYREQsa0We4nR5Rbga6xDMHCjnDYdfZg6VqbgGUA97kOAymhlIFO0pNKGowlOdR
+o9AjEhW2mq2itD7e4T4bDWqJ+6YAVc94DIVAjaY8BSJiet5BccXB8oles+W9nQ8k
+k24X2uCa3lWTbUaNGootbN+DVKVvX85zt5p707++yRQJZH4AWSAgpglnnIxo/y2Z
+rVUl8LvbwU4SuSQnyorfaiA0Q4NCnJPoZh1sEyfqvcVkH915RwP+0Vl7oXYgYKx0
+52U+G6I3w5qm/PafUQ4K2hn2KIHYDCz4P8DV6pbUqzoZ15BvLPu/3eenzqvdtoGj
+hD8/3VxowicLrV69gEWJZ89VMjjPTHp7XyrEvKq4n7uquLArS3dW3+mNrmeFRA99
+Y59RFgtroEbIyk5Z/AQA0vuTfEATIMdn/jbeLC2juz57AAnuu6mE72KBdZY3OK2u
+F1sQCop/lWfN/khleo5EBWucQ+a7nZnByd6J0sp70AxjSOBTP5I0TBcdZgaDXJpH
+b4pOwX4EQeXUwlYTh2eYoZRP2thTdH0QrXKEEicynmBfvECz/4nAPwLPYk+yK9/a
+bYYSBn/KbBhBie7chsknzJ+XXb4C9ROubuuAl26yPQxX5uI03lYkVExpj5SdHzts
+/ULLKN5t9Us3gc9SQ3+6
+
+
+
+
+
+ https://example.server.com/Policy-v1.0.pdf
+
+
+
+
+ edugain.example.edu
+
+ Example IdP for eduGAIN
+ Example IdP for eduGAIN
+ https://example.server.com/idp/images/logo.png
+
+
+
+
+
+
+MIIEKDCCApCgAwIBAgIVAK3+epRpBYLkDFqBDJP9WacC+I7YMA0GCSqGSIb3DQEBCwUAMBoxGDAW
+BgNVBAMMD2lkcC5tYXJlbi5hYy5tdzAeFw0yNTAyMjUxMjQyMDZaFw00NTAyMjUxMjQyMDZaMBox
+GDAWBgNVBAMMD2lkcC5tYXJlbi5hYy5tdzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
+ANp2cU7amXDFx7ZbPgo1lzwB1aF/LirEjfmeLirqK5giWJsgM9H8pxJjC3wQsposaKjvrH574N1L
++yzwHZxHFImyEqp323lcPXzjBuCKQrSkTOxmVrrKSOEwMNQ9fpNluf67J7MvlumN1/OSwesEyA98
+u5J6spp1B2uq9uERyqRbKprxJoNHVfHXlI1bDEc4UqTW2Ca86p9yLjulzvCaN/kM5x76fYdvmGGG
+cmKgjNnc/nc8AsToKHE/2qzbE9AvfR4mEQ/JTf4sJE92rytDu3fr6LvpL8QrnabWe4jW0kjk/9ow
+UBsFAaIvo89qcjxANuY9wM0kTWO8Js0pK220hlim8/tOTFPWKmxNwa3BdKtmtNwI8L5ZQoN40Aq+
+oqy7MD0xl6JUsC7AymAsPYoSPntzAbNwr7Xku0fRwSk4Qki8BB4qrDkQ65jr3T+M87K8hnrKiKYy
+iwWHzoVa6uFINfjngZKy35ThD5cJ7JB7JBYnbE/3fRsfUSf1soFSuJdSaQIDAQABo2UwYzAdBgNV
+HQ4EFgQUmZ2pcY599AATx9dv1TG0sMhmNqQwQgYDVR0RBDswOYIPaWRwLm1hcmVuLmFjLm13hiZo
+dHRwczovL2lkcC5tYXJlbi5hYy5tdy9pZHAvc2hpYmJvbGV0aDANBgkqhkiG9w0BAQsFAAOCAYEA
+gvQQs9E3bI0WYKaaqwaekD/3LIV6haGYChQISFq7KBxcjSEpuAJif6P3cnjtlaiFwFtgZlh4PGZh
+jXxFyZRkunF8iwPAeZfyWvbwwk+zuPBvE0WNPdfzV2yeqQAzp1TnXP9fcgaRE1FCLzlGA0vgtBuf
+/pXLHw9gV+mcOZV0c6D/GSzshgpH+oRek3Cs1WmjttzFlkcQomCBat1e195Wu6nG7YE0SKsYY7+w
+WEB6rqzVdCPc1UsjpPSPCBbPWX5vD3AgO0VUEpdX9HIxCuBL24R2dMleww9bgErxDOjWOETN5Uv1
+SdGPTG3L1SdDvPnPGfjbYphKpcSpzIhO8HhhcUpUULklBRdgzDWZ8LVcT66O0B4ZRxkRk0zTlkCY
+vZvKZoeeAwuIVbLmfysxw8A74AbAzy/SshG1TJsDntwRUGCpCwsXl+Kvtd7HITTeKjfbItucB471
+MCNlu+JA+MrzGZc7CnjWHgSYkBnaVfjug9ZGxlt7OkEZsV6oxvWy71Av
+
+
+
+
+
+
+
+
+MIIEKDCCApCgAwIBAgIVAKYkzlzQ42lHFsDX1fgwgnxyxT74MA0GCSqGSIb3DQEBCwUAMBoxGDAW
+BgNVBAMMD2lkcC5tYXJlbi5hYy5tdzAeFw0yNTAyMjUxMjQyMDVaFw00NTAyMjUxMjQyMDVaMBox
+GDAWBgNVBAMMD2lkcC5tYXJlbi5hYy5tdzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
+AJUaaKVXg50HPzyCHqAtReMRPId9KP21LqdqcJtzZdmWpwoFKanY7sWNE7zLsIcerDp5lxFEM670
+ILO4dUJlQEWQBi7hHWe1jDLaruN/0a694Ptz/ncs3fIdnXs5Jt+RkSlTMHwSDWq/KdkMNc5tAeaw
+s1CyHaNPNa23fP4iA57LHKpJa7YPCgDABpdx0easTiUCuAOUQu5IeeIZGU0684iaTC7fcuYaIG/p
+majFZL+kqwskN0YsJn+mfO0Pcq9QpDQlSYv+X4uEy6fprfQWwALhwiifFLA4TdSVUObb9QkVgCqo
+vOTNScw9fkfsOhTGtj/A9vfaf0ekOtcWLwcJHUj2rTeGXCnWE0/mUqTmvn7NKlwLYkXUSMYSlSEM
+ZEHMtNkPz2HH1hrhPb7VbKLfekG4k10Vz7QSiyGudALmEpxtmBrz7JMmjmv60MvmOiodGFAs53lL
+fTjvYxxmOLvjRSYrt1itRLni932KgI/VQPDpwmS3tUtZI5jfR7bA4hF+9QIDAQABo2UwYzAdBgNV
+HQ4EFgQU54aph3TZpsUp1YtPNoMurShgyrowQgYDVR0RBDswOYIPaWRwLm1hcmVuLmFjLm13hiZo
+dHRwczovL2lkcC5tYXJlbi5hYy5tdy9pZHAvc2hpYmJvbGV0aDANBgkqhkiG9w0BAQsFAAOCAYEA
+TPaNsUAR/NHEdRQ4ahOQGW3ohbBOg5ven9wTBSKhRTJYZDLdDT7aKodS0DXWIYWN/+WWkdYs8hmz
+mmB5sYmSfJP/PLdjl7p632dsu0P8nlJaWhw+rQ7I7nogKSnKIkGqp/SUBq6cqP9I0Xy9Q/08IjHB
+Bd4OunnRjjYdU87yyhBi7dYBO8X1b2M0X7B5VM0Ig4M9XrjMOfdBzgXi5b4q3Y0o3lqNA0CFLarX
+Gyev+qJ/rWA3iOZas/lWO3TC8gWlY1mNiaZmGnHauqJqPVK2qgzjN2uJHGFXHtBMLphiPLkCG/1Y
+V20CYpX2pN82nLSNtcQlFD0oTmTgjv7abfhfcn8yA6Zw9iXicTpJVJR5rbaJ8JY1XYq6PqFtcMUB
+B/IyINRPpwZmo/npLH1o5LzXfKJXjxX4vmAVz19rL1Bk4ad96qE3vzn6+kKq+c97bZqiPQiaPLb/
+pK+jqOPkWfE5intH8cqLJ8qIi2pmWHnnxrQpQ4nsaztCq8cnJ9muKKCM
+
+
+
+
+
+
+
+
+MIIEJzCCAo+gAwIBAgIUFsBZm9KQOzx8TL3LuDzyMyc50WkwDQYJKoZIhvcNAQELBQAwGjEYMBYG
+A1UEAwwPaWRwLm1hcmVuLmFjLm13MB4XDTI1MDIyNTEyNDIwNloXDTQ1MDIyNTEyNDIwNlowGjEY
+MBYGA1UEAwwPaWRwLm1hcmVuLmFjLm13MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA
+mtbsq2HLu/lXVgBl07pfvojQMADa8LBnzHMLcH/4vm7QDm2jKZKCK11Xyn1pdTDeVOE1/uHfm8BP
+cwWWKcWEY+lyIWSijPyiBo3PenpVfd/gLsI9L8BoKPzbQMFIVMJd8pvZ+k6CpyAkK/ePH/LLTmNV
+LK5O0wtZSAyoPLtmPAtssVlzqVvcmAYSxLao+/uwLGaTB54Gxki4kQkRN+ydfD6Afy0Slw9jvRb9
+yHXw3GyIc7zlWilgkvu+wm9vlJ18bxgSozkv4PCEWirxPl36XzW7KxSCBpIbKNc3KTskMDKesAL/
+w2kJODBdsAj11AKO8gkotstQzCZLefsdFSq0zUqtp10RZaemz+OVTG/FHM/1T0l+t6e2FQG3tJAP
++W760Gnt0YmnrZ9WjryIdOjQkA2RGIMJKthLu80k8AlWG/Ukk8gTOs+JZYBlJQFJ9ItFz5jXru3h
+QtROJ+7G3nSaiGtpki1f5BP8vV/XjzaUFdFEnbReB3AdUoj0/WnrUZtFAgMBAAGjZTBjMB0GA1Ud
+DgQWBBSThV/OvOzPYkPuTxSEuuBWiVmCVjBCBgNVHREEOzA5gg9pZHAubWFyZW4uYWMubXeGJmh0
+dHBzOi8vaWRwLm1hcmVuLmFjLm13L2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEBCwUAA4IBgQAM
+tkfqBgHIVQfVAa/TvutCHDY/0ZQCs/Zy4xT2ycKM18+M/eYLVKCwA4yDnStrckYYPt0o+uw7W9mL
+z8o1+pPONO/P2vZ0m7QszHH4nbv6XMpUnGBxV+x/JHsEsJkTSLZdIyR/vMNSgA9vMdt+DrwOcmhM
+0CrcEnNGuNFctBdUXW/juvoGIZJR8YUTpMbteBjFMtYLHA7eNaZGYgW+Ay9xV4Uh+VoNNinly/ka
+xd5gcJvmtbQS79o/g1HdOc/14USXsPWGDszFafy25d+8mRnnDL2rx0Sp0Eza7c9V/uozGzBiuBgd
+mf3RmuGSP37ESswiYPGOzJS+bwPmMixtNI/YNr5OizAWMpdUJvTi9l2hUdjdnNwO9jJW0Ytd72Pl
+gXP7dr9U0aiyUO2fWkf11XLsR7w2EJlXisv0gZw/NAoQjj6IaYypox/ltxDhSFXN94vH8hJE8MpT
+wn2o+KL6rZHCiWfybfZAjZaH/poZz/kbOz1rRqFEmQtKUz70Y78auBQ=
+
+
+
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
+
+
+
+
+
+ eduGAIN example
+ eduGain example
+ https://edugain.example.edu
+
+
+ mailto:systems@edugain.example.edu
+
+
+ mailto:support@edugain.example.edu
+
+
+
+
+
+ https://gif.sp.example.edugain.edu/pdf/metadatastatement.pdf
+
+
+
+
+
+
+ eduGAIN Example SP
+ eduGAIN Example SP
+ Satosa SP-SE
+ Satosa SP-EN
+ http://sp.example.edugain.edu/
+ http://sp.example.edugain.edu/
+ https://wsidp.sp.example.edugain.edu/idp/images/logo.png
+
+
+
+
+
+
+MIIEATCCAumgAwIBAgIUS4N+ue40exBaQsY3B6rcNQRcFZAwDQYJKoZIhvcNAQEL
+BQAwgY8xCzAJBgNVBAYTAkdIMQ4wDAYDVQQIDAVHaGFuYTEOMAwGA1UEBwwFQWNj
+cmExDzANBgNVBAoMBkdBUk5FVDEPMA0GA1UECwwGR0FSTkVUMRwwGgYDVQQDDBNw
+cm94eS5nYXJuZXQuZWR1LmdoMSAwHgYJKoZIhvcNAQkBFhFub2NAZ2FybmV0LmVk
+dS5naDAeFw0yNDA4MzExNzIyNDRaFw0yNTA4MzExNzIyNDRaMIGPMQswCQYDVQQG
+EwJHSDEOMAwGA1UECAwFR2hhbmExDjAMBgNVBAcMBUFjY3JhMQ8wDQYDVQQKDAZH
+QVJORVQxDzANBgNVBAsMBkdBUk5FVDEcMBoGA1UEAwwTcHJveHkuZ2FybmV0LmVk
+dS5naDEgMB4GCSqGSIb3DQEJARYRbm9jQGdhcm5ldC5lZHUuZ2gwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCMwnFBOO1iAtGGLiTkflGJL6+jJVnQiOB2
+mnTZJvoMzRrD1PSrnexftZ4HFhZN7+6mqp/KzO4CeVyWILPH8D1s3dOju5pLM1Al
+6PcUDyx3fSHzOTQ2CKIyygapdhlARQ9G4nJCs1ch38szwDOTZlTf5ddAkDCveG6u
+GZKmoBXTMH3Vf2L0VpRA+NBzA6YYPTYBZ/q+rUa/RgqlKsRdHJkw20IEEkweRmcV
+CpRFXeK2oex9Qej9zAgHwHCbBOfcs5B/Z6M5NB6SvS4EFumZVFvGd6o7TnKKjARo
+XhH5bovBIjiQ/+RCAgOoWYR9+8iis2njwqXWSAqcF1phi7R0olSzAgMBAAGjUzBR
+MB0GA1UdDgQWBBSzC8ESDVwCfcONyo+BgdVi74mp3TAfBgNVHSMEGDAWgBSzC8ES
+DVwCfcONyo+BgdVi74mp3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA
+A4IBAQATOEuBFJOPuZwSL1bn+sJnu7vI9RDdn8d6YzydKc/83WmrMfEsN9QLTYr2
+IrBRR5hsFtOucGTgqn+0/fEB5sKCKIM0tsbSJpmx9bG3W6WG5xQ+FiIjRiOa3wdK
+MXMVPlza1zWAGdR39T/acG8Vt7jtpDA436dsZyRAfSDsz3EJHKT6/afDNrIzY/rg
+ofsmgmwUUN0pPni9tGyzGlmC9cBszYFGX16ksRdOuWCvyyw46stYo6pIHGIJqpuG
+vjLEEu/SD3S9BDNCVnU3xCWHAJuiMuWL78nuAYLOnapV9BQ1wfZAPyfrF7BfJQAc
+rCQ5wiQlCiUdMUTWlNVfhJR1n5Pp
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+
+
+
+ sp.example.edugain.edu
+ sp.example.edugain.edu
+ http://sp.example.edugain.edu
+
+
+ Technical
+ mailto:admin@sp.example.edugain.edu
+
+
+ Technical
+ mailto:admin@sp.example.edugain.edu
+
+
+
diff --git a/tests/incommon/data/test-metadata-signed.xml b/tests/incommon/data/test-metadata-signed.xml
new file mode 100644
index 0000000..88c90b8
--- /dev/null
+++ b/tests/incommon/data/test-metadata-signed.xml
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+
+
+
+sB7Njem2CLBoTYaJqS720jGD2JV9fvyTHxJUtcy57Rs=
+
+
+
+DuOJlj86XnWZb7wTo0kp9licHMDO0jcW7/feDVyGd+glglqkBFEG4ojQ7KokSK/Z7aT9VyXOygBL
+EZUZeUDtU1EMrkZeVfMNV4gVcUU9Ls9pZ0uIFNz0Vj8Ot4yUKHroXJearCyNnT6hILFCDfzCCQV9
+VnD2Mn0Mm7XdFXQy2P2FJXRUPiGWGIYsPfemHofVzazxQtXtVmVmi7AZ5/rGEYUQckrQZL++IvGo
+S45xlNH3qUuUt9vr+w00ihiBWBjYQGZFPxafrYlMmbX/SZqRATM7HF9oC+1isG4prHQkCyhMxXir
+lxhq/Ffeg16TmMTBwpgPY6TyihHlqdn7RdWxeA==
+
+
+
+
+
+v+WBuMmJkUkkFv1uxg1coB0PMyYvGM/WKRH/MCRgwgx81lmIkuwp1ESzW3MOKjqHUWBD6OCIPCOk
+EYQ1+goYPGD4OJWKojLBOHvNF24t+RWqBQd6RkU+CfVPZJBvwhnoRY5VknAnKN9/CJHZV8XltStJ
+/6e9F6ffDHFAzjQdvlO3NFFW2RavVGgH6PibFd1KEGaT5pUWW0P3tozcH/56RbZ14YCiAXj64qjc
+vSKQAouOPPe5afLiQdUYyD4fo/ElYBkdycd8f8SAjkXUT4fUwiL/hUJ16TkECwWXA+58TL5qHoVQ
+1prvGeI4qbyQSXNsw1qF3gijCrJn1M+co886DQ==
+
+AQAB
+
+
+
+
+MIICsjCCAZoCCQCIj9cyx103KjANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0ZXN0LmV4YW1w
+bGUub3JnMB4XDTE4MTAyMTE3MTc0NloXDTE5MTAyMTE3MTc0NlowGzEZMBcGA1UEAwwQdGVzdC5l
+eGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/lgbjJiZFJJBb9bsYN
+XKAdDzMmLxjP1ikR/zAkYMIMfNZZiJLsKdREs1tzDio6h1FgQ+jgiDwjpBGENfoKGDxg+DiViqIy
+wTh7zRduLfkVqgUHekZFPgn1T2SQb8IZ6EWOVZJwJyjffwiR2VfF5bUrSf+nvRen3wxxQM40Hb5T
+tzRRVtkWr1RoB+j4mxXdShBmk+aVFltD97aM3B/+ekW2deGAogF4+uKo3L0ikAKLjjz3uWny4kHV
+GMg+H6PxJWAZHcnHfH/EgI5F1E+H1MIi/4VCdek5BAsFlwPufEy+ah6FUNaa7xniOKm8kElzbMNa
+hd4IowqyZ9TPnKPPOg0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYSDTrlmXMILckXtSQqkJOrZ0
+BlQi+IIRV4xbYknTDb107RDm8RXHkpc6A8W8jcwU0djmgmuDlBzhvnzSwE+gxqU1/W3eWtz60rcA
+PwmF+r9wYvVnCmPkUw8RWPasrzRPQMzehA/251Zx6tMPwBkEqOyagi1sq1mZbQSlF08jVBL+J6tb
+P2yRc3pp19dGApL6klIA5Mi5+VmxwMtoQ5v6qHT1oDxeKWcSDNVeSYYoBiLB8hFN692NsDtY9Urd
+pBpLa6CxWSKZd11+sFclGfqh35+2PBfHSCiAFZ8RL2qsq5uIDz53XgfB33j723uF4xGsS80lMSOO
+LT9+TC1qkYRchQ==
+
+
+
+
+
+
+
+
+
+
+
+
+ http://id.incommon.org/category/research-and-scholarship
+ http://refeds.org/category/research-and-scholarship
+ http://id.incommon.org/category/registered-by-incommon
+
+
+
+
+
+
+
+
+ Example Service
+ Example Service at Example Company.
+ https://example.com/services/view/example-service
+ https://example.com/privacy
+ https://example.com/images/logo200x200.gif
+
+
+
+
+
+
+
+MIIDGzCCAgOgAwIBAgIJANI+yGM0M1N2MA0GCSqGSIb3DQEBBQUAMCcxJTAjBgNV
+BAMTHGx0Y2F3aWtpMDEuaXQub2hpby1zdGF0ZS5lZHUwHhcNMTAwNzA3MjI0MzA1
+WhcNMjAwNzA0MjI0MzA1WjAnMSUwIwYDVQQDExxsdGNhd2lraTAxLml0Lm9oaW8t
+c3RhdGUuZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5fsEv25M
+r9wfa48qfjn8m40yB/lwimJ8dSnYw2erd/tfB+sPESw42Is5Lv2B3pI3mj9a0PT0
+Gf1VgUoQW0RCT6L4VOW50WsPFv/RKPfT/AIRl00dTCqb440PgotGbrK9ivZqlvkz
+lSGUKuFcg2gLj+CJlbMcwEneSwn0FE1xKEGpMDUk91lZH1XxmnIDDOQn1G5qul4q
+AbXITMpLi2MlsHAEXxnLrthFFas6zDrviTwHcqGXq9zJJkPHDcbu1qg6AUT7bRJr
+qszxxktSV6mFclkgLPpcVkigMR8RNVMQkWaaWSnfBkFy2iAe3xw3DNp7obtzgItY
+i9N8U6K5qorSkQIDAQABo0owSDAnBgNVHREEIDAeghxsdGNhd2lraTAxLml0Lm9o
+aW8tc3RhdGUuZWR1MB0GA1UdDgQWBBR32XnCliG78DdyTtZhyIQSHChtyjANBgkq
+hkiG9w0BAQUFAAOCAQEAVEweCxPElHGmam4Iv2QeJsGE7m4de7axp3epAJb7uVbN
+Z2P1S/s4GZQhmGsUoGoxwqca3wyQ+C1ZkpQJdyFl5s1tFc26D+Z0KTDo174GzO9i
+I9SeQ4YSp3FNhZqxn4xH3DULzzHwoVSwFr5irLPAVtrqK8H/rzBREhqOse2VSJ/1
+PkI+p7lUiElIzMiObLGjumF2fDOPkXOSMNyC4c5oCCJtcrip/BaLo6bqdqn3DKP8
+onMw/lHZQolyVsupuhGsSX13WVJ0uyGvuA7hiHnGEkpDmskUd3TsriyQAt47RZzY
+tTupO/NdWvz8SvXU1qIOk9CTQ0D2b2OOftfUW+FuAQ==
+
+
+
+
+
+
+
+
+
+
+ Example Service
+ Example Service at Example Company.
+
+
+
+
+
+
+ Example Company, Inc.
+ Example Company
+ https://www.example.com/
+
+
+ Administrative Contact
+ admin@example.com
+
+
+ Support Contact
+ support@example.com
+
+
+ Technical Contact
+ technical@example.com
+
+
+ Security Contact
+ security@example.com
+
+
+
+
+
+
+
+ http://refeds.org/category/research-and-scholarship
+
+
+ https://refeds.org/sirtfi
+
+
+ http://id.incommon.org/category/registered-by-incom
+mon
+
+
+
+
+
+ example.edu
+
+ Example University
+ https://example.edu/information/
+ https://example.edu/privacy/
+ https://example.edu/images/logo64x64.png
+
+
+
+
+
+
+
+MIIDITCCAgmgAwIBAgIJAKu+jRod+TYIMA0GCSqGSIb3DQEBBQUAMCkxJzAlBgNV
+BAMTHndlYmF1dGguc2VydmljZS5vaGlvLXN0YXRlLmVkdTAeFw0xMDAyMDkyMDA3
+MzdaFw0zMDAyMDQyMDA3MzdaMCkxJzAlBgNVBAMTHndlYmF1dGguc2VydmljZS5v
+aGlvLXN0YXRlLmVkdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMpZ
+P+xV7kNCuuUtg4X8MTxTnS2TSU/tompvYjI0af4q7N5od7uzEqHBD9FMvh9bZ7GS
+CACX5yYjBYZCb59i0tstfpCsDBho2Wi497EjmaTw81EQ1AjM6EhRb/we0MLj0er8
+8q+vnVC7Jb7DoStoNIEFoOTv8LvKldrrXVX3yHZR3bEVtvblZbGMSYtPdH/TYMDQ
+cmqkpzldfz9rQFDLSM8mqBqf56zmB8uzkZKhujTXOzb4STvaq7hhAnDwT3z9c00O
+XbDBWxd1CplgHwZvrbWxYxf5gTCaPvHuLY5WeA8Ky5SUZifO/szEDvEm8K0rHStK
+H/blQiX5fUQ6t3SfxbsCAwEAAaNMMEowKQYDVR0RBCIwIIIed2ViYXV0aC5zZXJ2
+aWNlLm9oaW8tc3RhdGUuZWR1MB0GA1UdDgQWBBR70C49vjOa/Ikk86hkX998wqQt
+UDANBgkqhkiG9w0BAQUFAAOCAQEAlgMMaTIwrly4U896lUa92iif3bLGADPjc0Is
+6a6k6RytjJm/r0lbtjCWW6zs1T6L7458Ow+57fyF0Oh/iXvj65m+dvCBWXnag7hN
+1yMBJQMRpSjH7dLko7y0EJ/ZrKEYQwYnBGmCILvJB/MIj2eEkq2Z47uWpvrehJfb
+zsEeAbjNqw1V/AJN7E4paw8aYg8TXEXAdOvNL5h7KRQw8Ui0kCw2DeTTIXExSxZd
+bqw6ldfQD2fVYnLxDGTFqITCi1a9TidA4xCXD95F7uQaEao3O8ArZcyag62uiMtv
+i24RvCRvD/vsnUhI82pV/DK+2icz6UDtiiKrFNAmIiR14TanfA==
+
+
+
+
+
+
+
+
+
+
+
+ Example University
+ Example University
+ https://www.example.edu/
+
+
+ Support Contact
+ support@example.edu
+
+
+ Technical Contactt
+ technical@example.edu
+
+
+ Administrative Contact
+ admin@example.edu
+
+
+ Security Contact
+ security@example.edu
+
+
+
diff --git a/tests/incommon/data/test-metadata.xml b/tests/incommon/data/test-metadata.xml
new file mode 100644
index 0000000..dd8b92b
--- /dev/null
+++ b/tests/incommon/data/test-metadata.xml
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+ http://id.incommon.org/category/research-and-scholarship
+ http://refeds.org/category/research-and-scholarship
+ http://id.incommon.org/category/registered-by-incommon
+
+
+
+
+
+
+
+
+ Example Service
+ Example Service at Example Company.
+ https://example.com/services/view/example-service
+ https://example.com/privacy
+ https://example.com/images/logo200x200.gif
+
+
+
+
+
+
+
+MIIDGzCCAgOgAwIBAgIJANI+yGM0M1N2MA0GCSqGSIb3DQEBBQUAMCcxJTAjBgNV
+BAMTHGx0Y2F3aWtpMDEuaXQub2hpby1zdGF0ZS5lZHUwHhcNMTAwNzA3MjI0MzA1
+WhcNMjAwNzA0MjI0MzA1WjAnMSUwIwYDVQQDExxsdGNhd2lraTAxLml0Lm9oaW8t
+c3RhdGUuZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5fsEv25M
+r9wfa48qfjn8m40yB/lwimJ8dSnYw2erd/tfB+sPESw42Is5Lv2B3pI3mj9a0PT0
+Gf1VgUoQW0RCT6L4VOW50WsPFv/RKPfT/AIRl00dTCqb440PgotGbrK9ivZqlvkz
+lSGUKuFcg2gLj+CJlbMcwEneSwn0FE1xKEGpMDUk91lZH1XxmnIDDOQn1G5qul4q
+AbXITMpLi2MlsHAEXxnLrthFFas6zDrviTwHcqGXq9zJJkPHDcbu1qg6AUT7bRJr
+qszxxktSV6mFclkgLPpcVkigMR8RNVMQkWaaWSnfBkFy2iAe3xw3DNp7obtzgItY
+i9N8U6K5qorSkQIDAQABo0owSDAnBgNVHREEIDAeghxsdGNhd2lraTAxLml0Lm9o
+aW8tc3RhdGUuZWR1MB0GA1UdDgQWBBR32XnCliG78DdyTtZhyIQSHChtyjANBgkq
+hkiG9w0BAQUFAAOCAQEAVEweCxPElHGmam4Iv2QeJsGE7m4de7axp3epAJb7uVbN
+Z2P1S/s4GZQhmGsUoGoxwqca3wyQ+C1ZkpQJdyFl5s1tFc26D+Z0KTDo174GzO9i
+I9SeQ4YSp3FNhZqxn4xH3DULzzHwoVSwFr5irLPAVtrqK8H/rzBREhqOse2VSJ/1
+PkI+p7lUiElIzMiObLGjumF2fDOPkXOSMNyC4c5oCCJtcrip/BaLo6bqdqn3DKP8
+onMw/lHZQolyVsupuhGsSX13WVJ0uyGvuA7hiHnGEkpDmskUd3TsriyQAt47RZzY
+tTupO/NdWvz8SvXU1qIOk9CTQ0D2b2OOftfUW+FuAQ==
+
+
+
+
+
+
+
+
+
+
+ Example Service
+ Example Service at Example Company.
+
+
+
+
+
+
+ Example Company, Inc.
+ Example Company
+ https://www.example.com/
+
+
+ Administrative Contact
+ admin@example.com
+
+
+ Support Contact
+ support@example.com
+
+
+ Technical Contact
+ technical@example.com
+
+
+ Security Contact
+ security@example.com
+
+
+
+
+
+
+
+ http://refeds.org/category/research-and-scholarship
+
+
+ https://refeds.org/sirtfi
+
+
+ http://id.incommon.org/category/registered-by-incom
+mon
+
+
+
+
+
+ example.edu
+
+ Example University
+ https://example.edu/information/
+ https://example.edu/privacy/
+ https://example.edu/images/logo64x64.png
+
+
+
+
+
+
+
+MIIDITCCAgmgAwIBAgIJAKu+jRod+TYIMA0GCSqGSIb3DQEBBQUAMCkxJzAlBgNV
+BAMTHndlYmF1dGguc2VydmljZS5vaGlvLXN0YXRlLmVkdTAeFw0xMDAyMDkyMDA3
+MzdaFw0zMDAyMDQyMDA3MzdaMCkxJzAlBgNVBAMTHndlYmF1dGguc2VydmljZS5v
+aGlvLXN0YXRlLmVkdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMpZ
+P+xV7kNCuuUtg4X8MTxTnS2TSU/tompvYjI0af4q7N5od7uzEqHBD9FMvh9bZ7GS
+CACX5yYjBYZCb59i0tstfpCsDBho2Wi497EjmaTw81EQ1AjM6EhRb/we0MLj0er8
+8q+vnVC7Jb7DoStoNIEFoOTv8LvKldrrXVX3yHZR3bEVtvblZbGMSYtPdH/TYMDQ
+cmqkpzldfz9rQFDLSM8mqBqf56zmB8uzkZKhujTXOzb4STvaq7hhAnDwT3z9c00O
+XbDBWxd1CplgHwZvrbWxYxf5gTCaPvHuLY5WeA8Ky5SUZifO/szEDvEm8K0rHStK
+H/blQiX5fUQ6t3SfxbsCAwEAAaNMMEowKQYDVR0RBCIwIIIed2ViYXV0aC5zZXJ2
+aWNlLm9oaW8tc3RhdGUuZWR1MB0GA1UdDgQWBBR70C49vjOa/Ikk86hkX998wqQt
+UDANBgkqhkiG9w0BAQUFAAOCAQEAlgMMaTIwrly4U896lUa92iif3bLGADPjc0Is
+6a6k6RytjJm/r0lbtjCWW6zs1T6L7458Ow+57fyF0Oh/iXvj65m+dvCBWXnag7hN
+1yMBJQMRpSjH7dLko7y0EJ/ZrKEYQwYnBGmCILvJB/MIj2eEkq2Z47uWpvrehJfb
+zsEeAbjNqw1V/AJN7E4paw8aYg8TXEXAdOvNL5h7KRQw8Ui0kCw2DeTTIXExSxZd
+bqw6ldfQD2fVYnLxDGTFqITCi1a9TidA4xCXD95F7uQaEao3O8ArZcyag62uiMtv
+i24RvCRvD/vsnUhI82pV/DK+2icz6UDtiiKrFNAmIiR14TanfA==
+
+
+
+
+
+
+
+
+
+
+
+ Example University
+ Example University
+ https://www.example.edu/
+
+
+ Support Contact
+ support@example.edu
+
+
+ Technical Contactt
+ technical@example.edu
+
+
+ Administrative Contact
+ admin@example.edu
+
+
+ Security Contact
+ security@example.edu
+
+
+
diff --git a/tests/incommon/scripts/consolidateIncommonAndEdugain.sh b/tests/incommon/scripts/consolidateIncommonAndEdugain.sh
new file mode 100755
index 0000000..56837ee
--- /dev/null
+++ b/tests/incommon/scripts/consolidateIncommonAndEdugain.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# Generate metadata files required for the MDQ service
+
+# TODO:
+# * Wrap mda output in debug function
+# * Count files
+
+set -euo pipefail
+
+# Get script name
+PROG=`basename $0`
+
+# Get metadata validation funtions
+source /$MDQ_HOME/tests/incommon/scripts/metadataValidation.sh
+
+# Print debug output
+function debug {
+ echo [DEBUG] $PROG: "$@"
+}
+
+# Print error output
+function error {
+ echo [ERROR] $PROG: "$@"
+}
+
+# Print informational output
+function info {
+ echo [INFO] $PROG: "$@"
+}
+
+info "Starting at $(date)"
+
+# Use local key
+debug "Using local key"
+
+# The inc.generate.import_sign_localkey target erroneously depends on sign.uk.keyPassword
+# The mda.inc.imported-idp.xml is the parameter for the unsigned idp-only aggregate output file
+# The mda.inc.imported.xml is the parameter for the unsigned aggregate output file
+ANT_OPTS=(inc.generate.import_sign_localkey \
+ "-Dedugain.dir=/mda/inc/inc-meta/mdx/int_edugain" \
+ "-Dmda.inc.edugain.xml=tests/incommon/data/test-edugain-metadata.xml" \
+ "-Dmda.inc.imported.xml=/tmp/incommon-and-edugain-metadata.xml" \
+ "-Dmda.inc.imported-idp.xml=/tmp/incommon-and-edugain-idp-metadata.xml" \
+ "-Dmda.inc.production.xml=tests/incommon/data/test-metadata.xml" \
+ "-Dmda.sign.keyResource=file:///keys/mda-signing.key" \
+ "-Dshared.ws.dir=/mda/inc/inc-meta" \
+ "-Dsign.uk.keyPassword=dummypassword")
+
+# Set source for signed InCommon metadata aggregate
+MD_SOURCE_FILE=$MDQ_HOME/tests/incommon/data/test-metadata.xml
+MD_SOURCE_CERT=/$MDQ_HOME/tests/incommon/data/test-cert.pem
+
+# Create temp local signing key/cert
+SGNPWD=dummypassword
+export SGNPWD
+mkdir -p /keys
+[ ! -L /keys/mda-signing.crt ] && ln -s /$MDQ_HOME/tests/incommon/data/mda-signing.crt /keys/mda-signing.crt
+[ ! -L /keys/mda-signing.key ] && ln -s /$MDQ_HOME/tests/incommon/data/mda-signing.key /keys/mda-signing.key
+
+# Generate all required metadata for the MDQ service
+debug "Generating metadata"
+cd "$MDQ_HOME" || exit 1
+if ! /usr/bin/ant "${ANT_OPTS[@]}"
+then
+ error "Metadata generation failed"
+ exit 1
+fi
diff --git a/tests/incommon/scripts/edugainDownload.sh b/tests/incommon/scripts/edugainDownload.sh
new file mode 100755
index 0000000..b6d2121
--- /dev/null
+++ b/tests/incommon/scripts/edugainDownload.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Download metadata files required for the MDQ service
+
+ANT_OPTS=(inc.edugain.download \
+ "-Dshared.ws.dir=/mda/inc/inc-meta" \
+ "-Dedugain.dir=/mda/inc/inc-meta/mdx/int_edugain" \
+ "-Dmda.inc.edugain.xml=/tmp/edugain-metadata.xml")
+
+# Download eduGAIN metadata for the MDQ service
+echo "Running ant to download the eduGAIN metadata file."
+cd "$MDQ_HOME" || exit 1
+if ! /usr/bin/ant "${ANT_OPTS[@]}"
+then
+ echo "Download failed"
+ exit 1
+fi
diff --git a/tests/incommon/scripts/genMDFromSignedMD.sh b/tests/incommon/scripts/genMDFromSignedMD.sh
new file mode 100755
index 0000000..163a2ff
--- /dev/null
+++ b/tests/incommon/scripts/genMDFromSignedMD.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# Generate metadata files required for the MDQ service
+
+# TODO:
+# * Wrap mda output in debug function
+# * Count files
+
+set -euo pipefail
+
+# Get script name
+PROG=`basename $0`
+
+# Get metadata validation funtions
+source /$MDQ_HOME/tests/incommon/scripts/metadataValidation.sh
+
+# Print debug output
+function debug {
+ echo [DEBUG] $PROG: "$@"
+}
+
+# Print error output
+function error {
+ echo [ERROR] $PROG: "$@"
+}
+
+# Print informational output
+function info {
+ echo [INFO] $PROG: "$@"
+}
+
+info "Starting at $(date)"
+
+# Use local key
+debug "Using local key"
+# The inc.mdq.generate.all.localkey target erroneously depends on sign.uk.keyPassword
+ANT_OPTS=(inc.mdq.generate.all.localkey \
+ "-Dshared.ws.dir=/mda/inc/inc-meta" \
+ "-Dmda.sign.keyResource=file:///keys/mda-signing.key" \
+ "-Dmda.inc.imported.xml=tests/incommon/data/test-metadata-signed.xml" \
+ "-Dsign.uk.keyPassword=dummypassword")
+
+# Set source for signed InCommon metadata aggregate
+MD_SOURCE_FILE=$MDQ_HOME/tests/incommon/data/test-metadata-signed.xml
+MD_SOURCE_CERT=/$MDQ_HOME/tests/incommon/data/test-cert.pem
+
+debug "Verifying source metadata signature"
+# Get the timestamp from the metadata aggregate file
+MDTIME=$(stat -c %y "$MD_SOURCE_FILE" | cut -d ' ' -f1,2)
+export MDTIME
+
+# Verify the signature on the metadata aggregate
+args=(--verifySignature \
+ --inFile "$MD_SOURCE_FILE" \
+ --certificate "$MD_SOURCE_CERT" \
+ --outFile "$INC_MD_VERIFIED_PATH")
+if ! "$XMLSECTOOL_PATH" "${args[@]}"
+then
+ error "Source metadata signature verification failed"
+ exit 1
+fi
+
+rm -f /tmp/inc-metadata.xml
+
+# Create temp local signing key/cert
+SGNPWD=dummypassword
+export SGNPWD
+mkdir -p /keys
+[ ! -L /keys/mda-signing.crt ] && ln -s /$MDQ_HOME/tests/incommon/data/mda-signing.crt /keys/mda-signing.crt
+[ ! -L /keys/mda-signing.key ] && ln -s /$MDQ_HOME/tests/incommon/data/mda-signing.key /keys/mda-signing.key
+
+# Generate all required metadata for the MDQ service
+debug "Generating metadata"
+cd "$MDQ_HOME" || exit 1
+if ! /usr/bin/ant "${ANT_OPTS[@]}"
+then
+ error "Metadata generation failed"
+ exit 1
+fi
diff --git a/tests/incommon/scripts/genMDFromUnsignedMD.sh b/tests/incommon/scripts/genMDFromUnsignedMD.sh
new file mode 100755
index 0000000..d3b6d44
--- /dev/null
+++ b/tests/incommon/scripts/genMDFromUnsignedMD.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# Generate metadata files required for the MDQ service
+
+# TODO:
+# * Wrap mda output in debug function
+# * Count files
+
+set -euo pipefail
+
+# Get script name
+PROG=`basename $0`
+
+# Get metadata validation funtions
+source /$MDQ_HOME/tests/incommon/scripts/metadataValidation.sh
+
+# Print debug output
+function debug {
+ echo [DEBUG] $PROG: "$@"
+}
+
+# Print error output
+function error {
+ echo [ERROR] $PROG: "$@"
+}
+
+# Print informational output
+function info {
+ echo [INFO] $PROG: "$@"
+}
+
+info "Starting at $(date)"
+
+# Use local key
+debug "Using local key"
+# The inc.mdq.generate.all.localkey target erroneously depends on sign.uk.keyPassword
+ANT_OPTS=(inc.mdq.generate.all.localkey \
+ "-Dshared.ws.dir=/mda/inc/inc-meta" \
+ "-Dmda.sign.keyResource=file:///keys/mda-signing.key" \
+ "-Dmda.inc.imported.xml=tests/incommon/data/test-edugain-metadata.xml" \
+ "-Dsign.uk.keyPassword=dummypassword")
+
+# Set source for signed InCommon metadata aggregate
+MD_SOURCE_FILE=$MDQ_HOME/tests/incommon/data/test-metadata.xml
+MD_SOURCE_CERT=/$MDQ_HOME/tests/incommon/data/test-cert.pem
+
+# Create temp local signing key/cert
+SGNPWD=dummypassword
+export SGNPWD
+mkdir -p /keys
+[ ! -L /keys/mda-signing.crt ] && ln -s /$MDQ_HOME/tests/incommon/data/mda-signing.crt /keys/mda-signing.crt
+[ ! -L /keys/mda-signing.key ] && ln -s /$MDQ_HOME/tests/incommon/data/mda-signing.key /keys/mda-signing.key
+
+# Generate all required metadata for the MDQ service
+debug "Generating metadata"
+cd "$MDQ_HOME" || exit 1
+if ! /usr/bin/ant "${ANT_OPTS[@]}"
+then
+ error "Metadata generation failed"
+ exit 1
+fi
diff --git a/tests/incommon/scripts/metadataValidation.sh b/tests/incommon/scripts/metadataValidation.sh
new file mode 100755
index 0000000..5b5f203
--- /dev/null
+++ b/tests/incommon/scripts/metadataValidation.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Function to check metadata validity window (validUntil attribute)
+check_validity_window() {
+ local file="$1"
+
+ # Check if the file exists
+ if [ ! -f "$file" ]; then
+ echo "File $file does not exist."
+ exit 1
+ fi
+
+ # echo "Verifying metadata validity window in file: $file"
+
+ # Extract a specific element/attribute value
+ valid_until_timestamp_string=$(grep -oP '(Entity|Entities)Descriptor[^>]*\svalidUntil="\K[^"]*' "$file")
+
+ # Extract the date portion from the date string (YYYY-MM-DD)
+ valid_until_date=$(echo "$valid_until_timestamp_string" | cut -d'T' -f1)
+
+ # Get the current date in YYYY-MM-DD format
+ current_date=$(date +%Y-%m-%d)
+
+ # Calculate the date for two weeks in the future
+ future_date=$(date -d "$current_date + 14 days" +%Y-%m-%d)
+
+ # Compare the date portion of the date string with the future date
+ if [ "$valid_until_date" != "$future_date" ]; then
+ echo "[ERROR] $file"
+ echo "[ERROR] validUntil date $valid_until_date is not 2 weeks in the future from $current_date"
+ exit 1
+ fi
+}