diff --git a/Dockerfile b/Dockerfile
index 94bcac4..9862d09 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@
 #  Building assumes midpoint-dist.tar.gz is present in the current directory.
 #
 
-FROM tier/shibboleth_sp
+FROM tier/shibboleth_sp:3.0.4_03122019
 
 MAINTAINER info@evolveum.com
 
@@ -10,7 +10,7 @@ RUN rpm --import http://repos.azulsystems.com/RPM-GPG-KEY-azulsystems
 RUN curl -o /etc/yum.repos.d/zulu.repo http://repos.azulsystems.com/rhel/zulu.repo
 RUN yum -y update
 RUN yum -y install \
- 	zulu-8 \
+ 	zulu-11 \
         cron \
         supervisor \
 	libcurl \
@@ -60,7 +60,9 @@ COPY container_files/mp-dir/ ${MP_DIR}/
 RUN echo 'Extracting midPoint archive...' \
  && tar xzf ${MP_DIR}/${MP_DIST_FILE} -C ${MP_DIR} --strip-components=1
 
-VOLUME ${MP_DIR}/var
+# Disabled because of wider compatibility issues (e.g. AWS)
+# TODO: consider all the consequences
+#VOLUME ${MP_DIR}/var
 
 # Repository parameters
 
diff --git a/Jenkinsfile b/Jenkinsfile
index 2021ac0..86236af 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -58,10 +58,10 @@ pipeline {
                         sh 'bin/test.sh 2>&1 | tee debug ; test ${PIPESTATUS[0]} -eq 0'
                         sh 'echo Docker containers before compositions tests ; docker ps -a'		// temporary
 
-                        sh '(cd demo/simple ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
-                        sh '(cd demo/shibboleth ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
-                        sh '(cd demo/postgresql ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
-                        sh '(cd demo/complex ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
+                        //sh '(cd demo/simple ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
+                        //sh '(cd demo/shibboleth ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
+                        //sh '(cd demo/postgresql ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
+                        // sh '(cd demo/complex ; bats tests ) 2>&1 | tee -a debug ; test ${PIPESTATUS[0]} -eq 0'
                     } catch (error) {
                         def error_details = readFile('./debug')
                         def message = "BUILD ERROR: There was a problem testing ${imagename}:${tag}. \n\n ${error_details}"
diff --git a/common.bash b/common.bash
index f61b220..3ef722b 100644
--- a/common.bash
+++ b/common.bash
@@ -1,3 +1,3 @@
 maintainer="tier"
 imagename="midpoint"
-tag="latest"
+tag="laboratory"
diff --git a/container_files/usr-local-bin/start-httpd.sh b/container_files/usr-local-bin/start-httpd.sh
index 7d002cd..29827f8 100755
--- a/container_files/usr-local-bin/start-httpd.sh
+++ b/container_files/usr-local-bin/start-httpd.sh
@@ -21,7 +21,8 @@ case $AUTHENTICATION in
     echo "*** Starting httpd WITH Shibboleth support"
     set -e
     rm -f /etc/httpd/logs/httpd.pid
-    (/usr/sbin/shibd) & httpd -DFOREGROUND
+    export LD_LIBRARY_PATH=/opt/shibboleth/lib64:$LD_LIBRARY_PATH
+    (/usr/sbin/shibd -f) & httpd -DFOREGROUND
     ;;
   internal)
     echo "*** Starting httpd WITHOUT Shibboleth support"
diff --git a/demo/complex/add-ref-groups.gsh b/demo/complex/add-ref-groups.gsh
index 679910c..0e952ac 100644
--- a/demo/complex/add-ref-groups.gsh
+++ b/demo/complex/add-ref-groups.gsh
@@ -1,14 +1,14 @@
 
-def addGroups(gs,stem) {
-	def supergroup = GroupFinder.findByName(gs, "etc:midpointGroups", true)
+def addGroups(gs,stem,owner,regexp) {
 	for (group in stem.childGroups) {
 		if (!group.name.endsWith('_includes') &&
 		    !group.name.endsWith('_excludes') &&
 		    !group.name.endsWith('_systemOfRecord') &&
-		    !group.name.endsWith('_systemOfRecordAndIncludes')) {
+		    !group.name.endsWith('_systemOfRecordAndIncludes') &&
+		    (regexp == null || group.extension ==~ regexp)) {
 			println 'Adding: ' + group
 			def s = SubjectFinder.findById(group.getId(), 'group', 'g:gsa')
-			supergroup.addMember(s, false)
+			owner.addMember(s, false)
 		} else {
 			println 'Ignoring: ' + group
 		}
@@ -16,8 +16,11 @@ def addGroups(gs,stem) {
 }
 
 gs = GrouperSession.startRootSession()
+def supergroup = GroupFinder.findByName(gs, "etc:midpointGroups", true)
+def cs = GroupFinder.findByName(gs, "app:cs", true)
 
-addGroups(gs, StemFinder.findByName(gs, 'ref:affiliation'))
-addGroups(gs, StemFinder.findByName(gs, 'ref:dept'))
-addGroups(gs, StemFinder.findByName(gs, 'ref:course'))
+addGroups(gs, StemFinder.findByName(gs, 'ref:affiliation'), supergroup, null)
+//addGroups(gs, StemFinder.findByName(gs, 'ref:dept'), null)
+//addGroups(gs, StemFinder.findByName(gs, 'ref:course'), null)
 
+addGroups(gs, StemFinder.findByName(gs, 'ref:course'), cs, /CS.*/)
diff --git a/demo/complex/add-ref-groups.sh b/demo/complex/add-ref-groups.sh
index 735b5ae..4fb90c1 100755
--- a/demo/complex/add-ref-groups.sh
+++ b/demo/complex/add-ref-groups.sh
@@ -1,2 +1,6 @@
-docker cp add-ref-groups.gsh complex_grouper_daemon_1:/tmp/
-docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/add-ref-groups.gsh"
+source ../../library.bash
+
+execute_gsh complex_grouper_daemon_1 add-ref-groups.gsh
+
+#docker cp add-ref-groups.gsh complex_grouper_daemon_1:/tmp/
+#docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/add-ref-groups.gsh"
diff --git a/demo/complex/directory/container_files/seed-data/users.ldif b/demo/complex/directory/container_files/seed-data/users.ldif
index 5381f7d..383b1b7 100644
--- a/demo/complex/directory/container_files/seed-data/users.ldif
+++ b/demo/complex/directory/container_files/seed-data/users.ldif
@@ -12,9 +12,24 @@ uniqueMember: uid=banderson,ou=People,dc=internet2,dc=edu
 uniqueMember: uid=jsmith,ou=People,dc=internet2,dc=edu
 cn: users
 
+dn: ou=Affiliations,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Affiliations
+
 dn: ou=Courses,ou=Groups,dc=internet2,dc=edu
 objectClass: top
 objectClass: organizationalUnit
 ou: Courses
 
+dn: ou=midpoint,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: midpoint
+
+dn: ou=Generic,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Generic
+
 
diff --git a/demo/complex/get-import-sis-courses-status.sh b/demo/complex/get-import-sis-courses-status.sh
new file mode 100755
index 0000000..7976300
--- /dev/null
+++ b/demo/complex/get-import-sis-courses-status.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+get_task_execution_status "Import from SIS courses"
diff --git a/demo/complex/get-import-sis-persons-status.sh b/demo/complex/get-import-sis-persons-status.sh
new file mode 100755
index 0000000..26d3fcd
--- /dev/null
+++ b/demo/complex/get-import-sis-persons-status.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+get_task_execution_status "Import from SIS persons"
diff --git a/demo/complex/grouper_data/container_files/seed-data/demo.gsh b/demo/complex/grouper_data/container_files/seed-data/demo.gsh
index e584add..2cb43fd 100644
--- a/demo/complex/grouper_data/container_files/seed-data/demo.gsh
+++ b/demo/complex/grouper_data/container_files/seed-data/demo.gsh
@@ -65,7 +65,7 @@ attributeAssign = group.getAttributeDelegate().retrieveAssignment(null, LoaderLd
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapQuartzCronName(), "0 * * * * ?");
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapTypeName(), "LDAP_SIMPLE");
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapFilterName(), "(cn=sysadmingroup)");
-attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSearchDnName(), "ou=Groups");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSearchDnName(), "ou=midpoint,ou=Groups");
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapServerIdName(), "demo");
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSourceIdName(), "ldap");
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectExpressionName(), '${loaderLdapElUtils.convertDnToSpecificValue(subjectId)}');
@@ -73,7 +73,16 @@ attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperL
 attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectIdTypeName(), "subjectId");
 
 midpointGroupsGroup = new GroupSave(gs).assignName("etc:midpointGroups").assignCreateParentStemsIfNotExist(true).save();
+
 testGroup = new GroupSave(gs).assignName("midpoint:test").assignCreateParentStemsIfNotExist(true).save();
+chess = new GroupSave(gs).assignName("app:mailinglist:chess").assignCreateParentStemsIfNotExist(true).save()
+idmfans = new GroupSave(gs).assignName("app:mailinglist:idm-fans").assignCreateParentStemsIfNotExist(true).save()
+cs = new GroupSave(gs).assignName("app:cs").assignCreateParentStemsIfNotExist(true).save()
+volunteers = new GroupSave(gs).assignName("test:volunteers").assignCreateParentStemsIfNotExist(true).save()
+
+midpointGroupsGroup.addMember(SubjectFinder.findById(testGroup.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(chess.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(idmfans.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(cs.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(volunteers.getId(), 'group', 'g:gsa'), false)
 
-s = SubjectFinder.findById(testGroup.getId(), 'group', 'g:gsa');
-midpointGroupsGroup.addMember(s, false);
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-org-affiliation.xml b/demo/complex/midpoint-objects/objectTemplates/template-org-affiliation.xml
new file mode 100644
index 0000000..ee29edb
--- /dev/null
+++ b/demo/complex/midpoint-objects/objectTemplates/template-org-affiliation.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d87aa04f-189c-4d6f-b6e1-216dad622142">
+    <name>template-org-affiliation</name>
+    <mapping>
+    	<name>metarole</name>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>fecae27b-d1d3-40ae-95fa-8f7e44e2ee70</oid>     <!--  metarole-affiliation -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <name>identifier</name>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        grouperName?.substring(16)           // from ref:affiliation:xxx
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <name>name</name>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'affiliation_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <name>displayName</name>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'Affiliation: ' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+</objectTemplate>
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-org-course.xml b/demo/complex/midpoint-objects/objectTemplates/template-org-course.xml
index 4eafd08..62f0825 100644
--- a/demo/complex/midpoint-objects/objectTemplates/template-org-course.xml
+++ b/demo/complex/midpoint-objects/objectTemplates/template-org-course.xml
@@ -14,5 +14,31 @@
             <path>assignment</path>
         </target>
     </mapping>
-    
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <name>name</name>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'course_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <name>displayName</name>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>
 </objectTemplate>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-org-department.xml b/demo/complex/midpoint-objects/objectTemplates/template-org-department.xml
index df9b223..7d7a8b6 100644
--- a/demo/complex/midpoint-objects/objectTemplates/template-org-department.xml
+++ b/demo/complex/midpoint-objects/objectTemplates/template-org-department.xml
@@ -14,5 +14,29 @@
             <path>assignment</path>
         </target>
     </mapping>
-    
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'department_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>
 </objectTemplate>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-org-generic-group.xml b/demo/complex/midpoint-objects/objectTemplates/template-org-generic-group.xml
new file mode 100644
index 0000000..3492c5a
--- /dev/null
+++ b/demo/complex/midpoint-objects/objectTemplates/template-org-generic-group.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="e2a6193a-8981-4143-9da1-9a7b32c0b819">
+    <name>template-org-generic-group</name>
+    <mapping>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>48e231be-8474-4ed0-a85e-6acf4c5e8d52</oid>     <!--  metarole-generic-group -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'generic_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>    
+</objectTemplate>
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-org-mailing-list.xml b/demo/complex/midpoint-objects/objectTemplates/template-org-mailing-list.xml
new file mode 100644
index 0000000..aba0e38
--- /dev/null
+++ b/demo/complex/midpoint-objects/objectTemplates/template-org-mailing-list.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="be84a39a-c004-490b-9b78-a871b837f6df">
+    <name>template-org-mailing-list</name>
+    <mapping>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>1c7beff4-cdf6-4e9f-b54c-79d0766f6fbe</oid>     <!--  metarole-mailing-list -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        grouperName?.substring(16)           // from app:mailinglist:xxx
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'mailinglist_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <expression>
+                <script>
+                    <code>
+                        'Mailing list: ' + identifier
+                    </code>
+                </script>
+            </expression>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>        
+</objectTemplate>
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-role-affiliation.xml b/demo/complex/midpoint-objects/objectTemplates/template-role-affiliation.xml
deleted file mode 100644
index 3a9c726..0000000
--- a/demo/complex/midpoint-objects/objectTemplates/template-role-affiliation.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0"?>
-<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
-    oid="d87aa04f-189c-4d6f-b6e1-216dad622142">
-    <name>template-role-affiliation</name>
-    <mapping>
-        <strength>strong</strength>
-        <expression>
-            <assignmentTargetSearch>
-                <targetType>RoleType</targetType>
-                <oid>fecae27b-d1d3-40ae-95fa-8f7e44e2ee70</oid>     <!--  metarole-affiliation -->
-            </assignmentTargetSearch>
-        </expression>
-        <target>
-            <path>assignment</path>
-        </target>
-    </mapping>
-</objectTemplate>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-role-generic-group.xml b/demo/complex/midpoint-objects/objectTemplates/template-role-midpoint-group.xml
similarity index 83%
rename from demo/complex/midpoint-objects/objectTemplates/template-role-generic-group.xml
rename to demo/complex/midpoint-objects/objectTemplates/template-role-midpoint-group.xml
index 1205f6d..62296e9 100644
--- a/demo/complex/midpoint-objects/objectTemplates/template-role-generic-group.xml
+++ b/demo/complex/midpoint-objects/objectTemplates/template-role-midpoint-group.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0"?>
 <objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
     oid="804f8658-0828-4dab-a2ed-f13985e4f80b">
-    <name>template-role-generic-group</name>
+    <name>template-role-midpoint-group</name>
     <mapping>
         <strength>strong</strength>
         <expression>
             <assignmentTargetSearch>
                 <targetType>RoleType</targetType>
-                <oid>c691e15a-f30b-4e15-8445-532db07ceeeb</oid>     <!--  metarole-generic-group -->
+                <oid>c691e15a-f30b-4e15-8445-532db07ceeeb</oid>     <!--  metarole-midpoint-group -->
             </assignmentTargetSearch>
         </expression>
         <target>
             <path>assignment</path>
         </target>
     </mapping>
-</objectTemplate>
\ No newline at end of file
+</objectTemplate>
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-user.xml b/demo/complex/midpoint-objects/objectTemplates/template-user.xml
index 455ccc0..d381aaa 100644
--- a/demo/complex/midpoint-objects/objectTemplates/template-user.xml
+++ b/demo/complex/midpoint-objects/objectTemplates/template-user.xml
@@ -4,47 +4,57 @@
     <mapping>
         <strength>strong</strength>
         <source>
-            <path>extension/grouper_group</path>
+            <path>extension/grouperGroup</path>
         </source>
         <expression>
             <assignmentTargetSearch>
                 <targetType>OrgType</targetType>
                 <filter>
                     <q:equal>
-                        <q:path>name</q:path>                       
+                        <q:path>extension/grouperName</q:path>                       
                         <expression>
                             <script>
                                 <code>
-                                    grouper_group
+                                    grouperGroup
                                 </code>
                             </script>
                         </expression>
                     </q:equal>
                 </filter>
                 <assignmentProperties>
-                    <subtype>group</subtype>
+                    <subtype>grouper-group</subtype>
                 </assignmentProperties>
                 <createOnDemand>true</createOnDemand>
                 <populateObject>
                     <populateItem>
                         <target>
-                            <path>name</path>
+                            <path>subtype</path>
                         </target>
                         <expression>
                             <script>
                                 <code>
-                                    grouper_group
+                                    switch (grouperGroup) {
+                                        case ~/ref:affiliation:.*/: return 'affiliation'
+                                        case ~/ref:dept:.*/: return 'department'
+                                        case ~/ref:course:.*/: return 'course'
+                                        case ~/app:mailinglist:.*/: return 'mailing-list'
+                                        default: return 'generic-group'
+                                    }
                                 </code>
                             </script>
                         </expression>
                     </populateItem>
                     <populateItem>
-                        <target>
-                            <path>subtype</path>
-                        </target>
                         <expression>
-                            <value>group</value>
+                            <script>
+                                <code>
+                                    grouperGroup
+                                </code>
+                            </script>
                         </expression>
+                        <target>
+                            <path>extension/grouperName</path>
+                        </target>
                     </populateItem>
                 </populateObject>
             </assignmentTargetSearch>       
@@ -55,7 +65,7 @@
                 <condition>
                     <script>
                         <code>
-                            assignment?.subtype.contains('group')
+                            assignment?.subtype.contains('grouper-group')
                         </code>
                     </script>
                 </condition>
diff --git a/demo/complex/midpoint-objects/orgs/org-affiliations.xml b/demo/complex/midpoint-objects/orgs/org-affiliations.xml
new file mode 100644
index 0000000..618f9ee
--- /dev/null
+++ b/demo/complex/midpoint-objects/orgs/org-affiliations.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1d7c0e3a-4456-409c-9f50-95407b2eb785">
+    <name>affiliations</name>
+    <displayName>Affiliations</displayName>
+</org>
diff --git a/demo/complex/midpoint-objects/orgs/org-groups.xml b/demo/complex/midpoint-objects/orgs/org-generic-groups.xml
similarity index 65%
rename from demo/complex/midpoint-objects/orgs/org-groups.xml
rename to demo/complex/midpoint-objects/orgs/org-generic-groups.xml
index 4998a2f..fa39bbc 100644
--- a/demo/complex/midpoint-objects/orgs/org-groups.xml
+++ b/demo/complex/midpoint-objects/orgs/org-generic-groups.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
     oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d">
-    <name>groups</name>
-    <displayName>Groups</displayName>
+    <name>generic-groups</name>
+    <displayName>Generic groups</displayName>
 </org>
diff --git a/demo/complex/midpoint-objects/orgs/org-mailing-lists.xml b/demo/complex/midpoint-objects/orgs/org-mailing-lists.xml
new file mode 100644
index 0000000..136c3ee
--- /dev/null
+++ b/demo/complex/midpoint-objects/orgs/org-mailing-lists.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d81fb46c-20c7-44d3-8402-fef404ea1264">
+    <name>mailing-lists</name>
+    <displayName>Mailing lists</displayName>
+</org>
diff --git a/demo/complex/midpoint-objects/resources/ldap-main.xml b/demo/complex/midpoint-objects/resources/ldap-main.xml
index f826cc7..fdb66ec 100644
--- a/demo/complex/midpoint-objects/resources/ldap-main.xml
+++ b/demo/complex/midpoint-objects/resources/ldap-main.xml
@@ -180,22 +180,21 @@
 				</attribute>
 				<attribute>
 					<ref>ri:eduPersonAffiliation</ref>
+					<outbound>
+						<strength>strong</strength>
+						<source>
+							<path>extension/rawAffiliation</path>
+						</source>
+					</outbound>
                     <tolerant>false</tolerant>
 				</attribute>
-                <attribute>
-                    <ref>ri:eduPersonEntitlement</ref>
-                    <tolerant>false</tolerant>
-                    <outbound>
-                        <source>
-                            <path>extension/grouper_group</path>
-                        </source>
-                    </outbound>
-                </attribute>
                 <association>
                     <tolerant>false</tolerant>
                     <ref>ri:group</ref>
                     <kind>entitlement</kind>
+                    <intent>affiliation-group</intent>
                     <intent>course-group</intent>
+                    <intent>midpoint-group</intent>
                     <intent>generic-group</intent>
                     <direction>objectToSubject</direction>
                     <associationAttribute>ri:uniqueMember</associationAttribute>
@@ -221,6 +220,44 @@
                 </credentials>
 			</objectType>
             
+            <objectType>
+                <kind>entitlement</kind>
+                <intent>affiliation-group</intent>
+                <displayName>LDAP Group for affiliations</displayName>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <attribute>
+                    <ref>ri:uniqueMember</ref>
+                    <matchingRule>mr:distinguishedName</matchingRule>
+                    <fetchStrategy>minimal</fetchStrategy>
+                </attribute>
+                <attribute>
+                    <ref>ri:dn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    basic.composeDnWithSuffix('cn', identifier, 'ou=Affiliations,ou=Groups,dc=internet2,dc=edu')
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+                </attribute>
+                <attribute>
+                    <ref>ri:cn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>weak</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                    </outbound>
+                </attribute>
+            </objectType>
             <objectType>
                 <kind>entitlement</kind>
                 <intent>course-group</intent>
@@ -261,7 +298,7 @@
             </objectType>
             <objectType>
                 <kind>entitlement</kind>
-                <intent>generic-group</intent>
+                <intent>midpoint-group</intent>
                 <displayName>LDAP Group</displayName>
                 <objectClass>ri:groupOfUniqueNames</objectClass>
                 <attribute>
@@ -281,7 +318,7 @@
                         <expression>
                             <script>
                                 <code>
-                                    basic.composeDnWithSuffix('cn', identifier, 'ou=Groups,dc=internet2,dc=edu')
+                                    basic.composeDnWithSuffix('cn', identifier, 'ou=midpoint,ou=Groups,dc=internet2,dc=edu')
                                 </code>
                             </script>
                         </expression>
@@ -297,6 +334,45 @@
                         </source>
                     </outbound>
                 </attribute>
+            </objectType>
+            <objectType>
+                <kind>entitlement</kind>
+                <intent>generic-group</intent>
+                <displayName>LDAP Group</displayName>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <attribute>
+                    <ref>ri:uniqueMember</ref>
+                    <matchingRule>mr:distinguishedName</matchingRule>
+                    <fetchStrategy>minimal</fetchStrategy>
+                </attribute>
+                <attribute>
+                    <ref>ri:dn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <trace>true</trace>
+                        <source>
+                            <path>extension/grouperName</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    basic.composeDnWithSuffix('cn', grouperName, 'ou=generic,ou=Groups,dc=internet2,dc=edu')
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+                </attribute>
+                <attribute>
+                    <ref>ri:cn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>weak</strength>
+                        <source>
+                            <path>extension/grouperName</path>
+                        </source>
+                    </outbound>
+                </attribute>
             </objectType>
 		</schemaHandling>
 
@@ -340,6 +416,59 @@
 					</action>
 				</reaction>
 			</objectSynchronization>
+            <objectSynchronization>
+                <name>affiliation-group sync</name>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <kind>entitlement</kind>
+                <intent>affiliation-group</intent>
+                <focusType>OrgType</focusType>
+                <enabled>true</enabled>
+                <condition>
+                    <script>
+                        <code>
+                            import javax.naming.ldap.*
+                            dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                            log.info('affiliation-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=Affiliations,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=Affiliations,ou=Groups,dc=internet2,dc=edu'))
+                        </code>
+                    </script>
+                </condition>
+                <correlation>
+                    <q:and>
+                        <q:equal>
+                            <q:path>identifier</q:path>
+                            <expression>
+                                <path>$shadow/attributes/ri:cn</path>
+                            </expression>
+                        </q:equal>
+                        <q:equal>
+                            <q:path>subtype</q:path>
+                            <q:value>affiliation</q:value>
+                        </q:equal>
+                    </q:and>
+                </correlation>
+                <reaction>
+                    <situation>linked</situation>
+                    <synchronize>true</synchronize>
+                </reaction>
+                <reaction>
+                    <situation>deleted</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unlinked</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unmatched</situation>
+                </reaction>
+            </objectSynchronization>
             <objectSynchronization>
                 <name>course-group sync</name>
                 <objectClass>ri:groupOfUniqueNames</objectClass>
@@ -393,20 +522,73 @@
                     <situation>unmatched</situation>
                 </reaction>
             </objectSynchronization>
+            <objectSynchronization>
+                <name>midpoint-group sync</name>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <kind>entitlement</kind>
+                <intent>midpoint-group</intent>
+                <focusType>RoleType</focusType>
+                <enabled>true</enabled>
+                <condition>
+                    <script>
+                        <code>
+                            import javax.naming.ldap.*
+                            dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                            log.info('midpoint-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=midpoint,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=midpoint,ou=Groups,dc=internet2,dc=edu'))
+                        </code>
+                    </script>
+                </condition>
+                <correlation>
+                    <q:and>
+                        <q:equal>
+                            <q:path>identifier</q:path>
+                            <expression>
+                                <path>$shadow/attributes/ri:cn</path>
+                            </expression>
+                        </q:equal>
+                        <q:equal>
+                            <q:path>subtype</q:path>
+                            <q:value>midpoint-group</q:value>
+                        </q:equal>
+                    </q:and>
+                </correlation>
+                <reaction>
+                    <situation>linked</situation>
+                    <synchronize>true</synchronize>
+                </reaction>
+                <reaction>
+                    <situation>deleted</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unlinked</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unmatched</situation>
+                </reaction>
+            </objectSynchronization>
             <objectSynchronization>
                 <name>generic-group sync</name>
                 <objectClass>ri:groupOfUniqueNames</objectClass>
                 <kind>entitlement</kind>
                 <intent>generic-group</intent>
-                <focusType>RoleType</focusType>
+                <focusType>OrgType</focusType>
                 <enabled>true</enabled>
                 <condition>
                     <script>
                         <code>
                             import javax.naming.ldap.*
                             dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
-                            log.info('generic-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=Groups,dc=internet2,dc=edu')))
-                            dn.size() == 4 &amp;&amp; dn.startsWith(new LdapName('ou=Groups,dc=internet2,dc=edu'))
+                            log.info('generic-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=Generic,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=Generic,ou=Groups,dc=internet2,dc=edu'))
                         </code>
                     </script>
                 </condition>
diff --git a/demo/complex/midpoint-objects/resources/resource-grouper.xml b/demo/complex/midpoint-objects/resources/resource-grouper.xml
index ca43a21..618a0bf 100644
--- a/demo/complex/midpoint-objects/resources/resource-grouper.xml
+++ b/demo/complex/midpoint-objects/resources/resource-grouper.xml
@@ -43,8 +43,10 @@
 			<rest:password>password</rest:password>
 			<rest:superGroup>etc:midpointGroups</rest:superGroup>
 			<rest:groupIncludePattern>midpoint:.*</rest:groupIncludePattern>
-			<rest:groupIncludePattern>ref:.*</rest:groupIncludePattern>
-			<rest:groupExcludePattern>ref:.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)</rest:groupExcludePattern>
+			<rest:groupIncludePattern>app:.*</rest:groupIncludePattern>
+			<rest:groupIncludePattern>test:.*</rest:groupIncludePattern>
+			<rest:groupIncludePattern>ref:affiliation:.*</rest:groupIncludePattern>
+			<rest:groupExcludePattern>.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)</rest:groupExcludePattern>
 			<rest:subjectSource>ldap</rest:subjectSource>
 			<rest:groupSource>g:gsa</rest:groupSource>
 			<rest:ignoreSslValidation>true</rest:ignoreSslValidation>
@@ -76,8 +78,8 @@
 
 						parameters = [
 							superGroup: 'etc:midpointGroups',
-							groupIncludePattern: [ 'midpoint:.*', 'ref:.*' ],
-							groupExcludePattern: [ 'ref:.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)' ],
+							groupIncludePattern: [ 'midpoint:.*', 'app:.*', 'test:.*', 'ref:affiliation:.*' ],
+							groupExcludePattern: [ '.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)' ],
 							relevantSourceId: 'ldap'
 						]
 
@@ -99,6 +101,7 @@
 			<attribute>
 				<ref>icfs:name</ref>
 				<inbound>
+                    <strength>strong</strength>
 					<target>
 						<path>name</path>
 					</target>
@@ -108,9 +111,9 @@
 				<ref>ri:group</ref>
 				<displayName>Subject Groups</displayName>
 				<inbound>
-			                <strength>strong</strength>
+			        <strength>strong</strength>
 					<target>
-						<path>extension/grouper_group</path>
+						<path>extension/grouperGroup</path>
 					</target>
 				</inbound>
 			</attribute>
@@ -123,20 +126,28 @@
 			<attribute>
 				<ref>icfs:name</ref>
 				<inbound>
-			                <strength>strong</strength>
+			        <strength>strong</strength>
 					<target>
-						<path>name</path>
-					</target>
-				</inbound>
-				<inbound>
-			                <strength>strong</strength>
-					<expression>
-						<value>group</value>
-					</expression>
-					<target>
-						<path>subtype</path>
+						<path>extension/grouperName</path>
 					</target>
 				</inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>
+                                switch (input) {
+                                    case ~/ref:affiliation:.*/: return 'affiliation'
+                                    case ~/app:mailinglist:.*/: return 'mailing-list'
+                                    default: return 'generic-group'
+                                }
+                            </code>
+                        </script>
+                    </expression>
+                    <target>
+                        <path>subtype</path>
+                    </target>
+                </inbound>
 			</attribute>
 		</objectType>
 	</schemaHandling>
@@ -188,12 +199,12 @@
 			<focusType>OrgType</focusType>
 			<correlation>
 				<q:equal>
-					<q:path>name</q:path>
-					<expression>
-						<path>
-							$account/attributes/name
-						</path>
-					</expression>
+					<q:path>extension/grouperName</q:path>
+                    <expression>
+                        <path>
+                            $account/attributes/name
+                        </path>
+                    </expression>
 				</q:equal>
 			</correlation>
 			<reaction>
diff --git a/demo/complex/midpoint-objects/resources/scriptedsql-sis-courses.xml b/demo/complex/midpoint-objects/resources/scriptedsql-sis-courses.xml
index 6b5f84b..e069ff8 100644
--- a/demo/complex/midpoint-objects/resources/scriptedsql-sis-courses.xml
+++ b/demo/complex/midpoint-objects/resources/scriptedsql-sis-courses.xml
@@ -29,9 +29,9 @@
 			<!-- >icscscriptedsql:clearTextPasswordToScript>true</icscscriptedsql:clearTextPasswordToScript -->
 			<icscscriptedsql:scriptingLanguage>GROOVY</icscscriptedsql:scriptingLanguage>
 
-			<icscscriptedsql:searchScriptFileName>/opt/midpoint/var/res/sis/SearchScript.groovy</icscscriptedsql:searchScriptFileName>
-			<icscscriptedsql:testScriptFileName>/opt/midpoint/var/res/sis/TestScript.groovy</icscscriptedsql:testScriptFileName>
-			<icscscriptedsql:schemaScriptFileName>/opt/midpoint/var/res/sis/SchemaScript.groovy</icscscriptedsql:schemaScriptFileName>
+			<icscscriptedsql:searchScriptFileName>/opt/midpoint/var/res/sis-courses/SearchScript.groovy</icscscriptedsql:searchScriptFileName>
+			<icscscriptedsql:testScriptFileName>/opt/midpoint/var/res/sis-courses/TestScript.groovy</icscscriptedsql:testScriptFileName>
+			<icscscriptedsql:schemaScriptFileName>/opt/midpoint/var/res/sis-courses/SchemaScript.groovy</icscscriptedsql:schemaScriptFileName>
 			
 			<icscscriptedsql:reloadScriptOnExecution>true</icscscriptedsql:reloadScriptOnExecution>
 			<!-- >icscscriptedsql:syncScriptFileName>/opt/midpoint/var/res/SyncScript.groovy</icscscriptedsql:syncScriptFileName -->
@@ -72,54 +72,25 @@
                         <assignmentTargetSearch>
                             <targetType>OrgType</targetType>
                             <filter>
-                                <q:equal>
-                                    <q:path>name</q:path>                       
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'course_' + input
-                                            </code>
-                                        </script>
-                                    </expression>                       
-                                </q:equal>
+                                <q:and>
+                                    <q:equal>
+                                        <q:path>identifier</q:path>                       
+                                        <expression>
+                                            <script>
+                                                <code>
+                                                    input
+                                                </code>
+                                            </script>
+                                        </expression>                       
+                                    </q:equal>
+                                    <q:equal>
+                                        <q:path>subtype</q:path>
+                                        <q:value>course</q:value>
+                                    </q:equal>
+                                </q:and>
                             </filter>
                             <createOnDemand>true</createOnDemand>
                             <populateObject>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'course_' + input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>name</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>displayName</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <assignmentTargetSearch>
-                                            <targetType>OrgType</targetType>
-                                            <oid>225e9360-0639-40ba-8a31-7f31bef067be</oid>
-                                        </assignmentTargetSearch>
-                                    </expression>
-                                    <target>
-                                        <path>assignment</path>
-                                    </target>
-                                </populateItem>
                                 <populateItem>
                                     <expression>
                                         <script>
diff --git a/demo/complex/midpoint-objects/resources/scriptedsql-sis-persons.xml b/demo/complex/midpoint-objects/resources/scriptedsql-sis-persons.xml
index 568074d..eb1926b 100644
--- a/demo/complex/midpoint-objects/resources/scriptedsql-sis-persons.xml
+++ b/demo/complex/midpoint-objects/resources/scriptedsql-sis-persons.xml
@@ -154,54 +154,25 @@
                         <assignmentTargetSearch>
                             <targetType>OrgType</targetType>
                             <filter>
-                                <q:equal>
-                                    <q:path>name</q:path>                       
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'department_' + input
-                                            </code>
-                                        </script>
-                                    </expression>                       
-                                </q:equal>
+                                <q:and>
+                                    <q:equal>
+                                        <q:path>identifier</q:path>                       
+                                        <expression>
+                                            <script>
+                                                <code>
+                                                    input
+                                                </code>
+                                            </script>
+                                        </expression>                       
+                                    </q:equal>
+                                    <q:equal>
+                                        <q:path>subtype</q:path>
+                                        <q:value>department</q:value>
+                                    </q:equal>
+                                </q:and>
                             </filter>
                             <createOnDemand>true</createOnDemand>
                             <populateObject>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'department_' + input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>name</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>displayName</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <assignmentTargetSearch>
-                                            <targetType>OrgType</targetType>
-                                            <oid>bee44c51-2469-411d-bac7-695728e9c241</oid>
-                                        </assignmentTargetSearch>
-                                    </expression>
-                                    <target>
-                                        <path>assignment</path>
-                                    </target>
-                                </populateItem>
                                 <populateItem>
                                     <expression>
                                         <script>
@@ -246,85 +217,9 @@
                 <ref>ri:affiliation</ref>
                 <inbound>
                     <strength>strong</strength>
-                    <expression>
-                        <assignmentTargetSearch>
-                            <targetType>RoleType</targetType>
-                            <filter>
-                                <q:equal>
-                                    <q:path>name</q:path>                       
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'affiliation_' + input
-                                            </code>
-                                        </script>
-                                    </expression>                       
-                                </q:equal>
-                            </filter>
-                            <createOnDemand>true</createOnDemand>
-                            <populateObject>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'affiliation_' + input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>name</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                'Affiliation: ' + input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>displayName</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <script>
-                                            <code>
-                                                input
-                                            </code>
-                                        </script>
-                                    </expression>
-                                    <target>
-                                        <path>identifier</path>
-                                    </target>
-                                </populateItem>
-                                <populateItem>
-                                    <expression>
-                                        <value>affiliation</value>
-                                    </expression>
-                                    <target>
-                                        <path>subtype</path>
-                                    </target>
-                                </populateItem>
-                            </populateObject>
-                            <assignmentProperties>
-                                <subtype>affiliation</subtype>
-                            </assignmentProperties>
-                        </assignmentTargetSearch>       
-                    </expression>
                     <target>
-                        <path>assignment</path>
-                        <set>
-                            <condition>
-                                <script>
-                                    <code>
-                                        assignment.subtype.contains('affiliation')
-                                    </code>
-                                </script>
-                            </condition>
-                        </set>
-                    </target>
+			<path>extension/rawAffiliation</path>
+		    </target>
                 </inbound>
             </attribute>
 		</objectType>
diff --git a/demo/complex/midpoint-objects/resources/target-cs-portal.xml b/demo/complex/midpoint-objects/resources/target-cs-portal.xml
new file mode 100644
index 0000000..7706bcb
--- /dev/null
+++ b/demo/complex/midpoint-objects/resources/target-cs-portal.xml
@@ -0,0 +1,111 @@
+<c:resource oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Computer science portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/cs-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>identifier</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:identifier</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:name</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:courses</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-course -->
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/identifier
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/resources/target-faculty-portal.xml b/demo/complex/midpoint-objects/resources/target-faculty-portal.xml
new file mode 100644
index 0000000..f3e7aed
--- /dev/null
+++ b/demo/complex/midpoint-objects/resources/target-faculty-portal.xml
@@ -0,0 +1,120 @@
+<c:resource oid="e417225d-8a08-46f3-9b5d-624990b52386" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Faculty portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/faculty-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>givenName</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:familyName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>familyName</path>
+                    </source>
+                </outbound>
+            </attribute>
+			<attribute>
+				<ref>ri:fullName</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/resources/target-mailing-lists.xml b/demo/complex/midpoint-objects/resources/target-mailing-lists.xml
new file mode 100644
index 0000000..4d60d27
--- /dev/null
+++ b/demo/complex/midpoint-objects/resources/target-mailing-lists.xml
@@ -0,0 +1,101 @@
+<c:resource oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Mailing lists (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/mailing-lists.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:lists</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-mailing-list -->
+            </attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/roles/metarole-affiliation.xml b/demo/complex/midpoint-objects/roles/metarole-affiliation.xml
index be64d72..aaef986 100644
--- a/demo/complex/midpoint-objects/roles/metarole-affiliation.xml
+++ b/demo/complex/midpoint-objects/roles/metarole-affiliation.xml
@@ -10,20 +10,45 @@
       oid="fecae27b-d1d3-40ae-95fa-8f7e44e2ee70">
     <name>metarole-affiliation</name>
     <inducement id="1">
+        <targetRef oid="1d7c0e3a-4456-409c-9f50-95407b2eb785" relation="org:default" type="c:OrgType" />     <!-- affiliations -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>affiliation-group</intent>
+        </construction>
+    </inducement>
+    <inducement id="3">
         <construction>
-            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
-            <attribute>
-                <ref>ri:eduPersonAffiliation</ref>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
                 <outbound>
-                    <strength>strong</strength>
                     <expression>
-                        <script>
-                            <code>assignmentPath[0].target.identifier</code>
-                        </script>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>affiliation-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
                     </expression>
                 </outbound>
-            </attribute>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <resourceRef oid="e417225d-8a08-46f3-9b5d-624990b52386" relation="org:default" type="c:ResourceType" />     <!-- Faculty CSV -->
         </construction>
         <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier == 'faculty'</code>
+                </script>
+            </expression>
+        </condition>
     </inducement>
 </role>
diff --git a/demo/complex/midpoint-objects/roles/metarole-course.xml b/demo/complex/midpoint-objects/roles/metarole-course.xml
index 3e26105..b1acba8 100644
--- a/demo/complex/midpoint-objects/roles/metarole-course.xml
+++ b/demo/complex/midpoint-objects/roles/metarole-course.xml
@@ -10,15 +10,18 @@
       oid="8aa99e7b-f7d3-4585-9800-14bab4d26a43">
     <name>metarole-course</name>
     <inducement id="1">
+        <targetRef oid="225e9360-0639-40ba-8a31-7f31bef067be" type="c:OrgType"/>            <!-- courses -->
+    </inducement>
+    <inducement id="2">
         <construction>
-            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
             <kind>entitlement</kind>
             <intent>course-group</intent>
         </construction>
     </inducement>
-    <inducement id="2">
+    <inducement id="3">
         <construction>
-            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
             <association>
                 <c:ref>ri:group</c:ref>
                 <outbound>
@@ -35,4 +38,29 @@
         </construction>
         <order>2</order>
     </inducement>
+    <inducement id="4">
+        <construction>
+            <strength>weak</strength>
+            <resourceRef oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" relation="org:default" type="c:ResourceType" />     <!-- CS CSV -->
+            <attribute>
+                <c:ref>ri:courses</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier?.startsWith('CS')</code>
+                </script>
+            </expression>
+        </condition>
+        <order>2</order>
+    </inducement>
 </role>
diff --git a/demo/complex/midpoint-objects/roles/metarole-department.xml b/demo/complex/midpoint-objects/roles/metarole-department.xml
index 96947e3..4b8ed2b 100644
--- a/demo/complex/midpoint-objects/roles/metarole-department.xml
+++ b/demo/complex/midpoint-objects/roles/metarole-department.xml
@@ -10,6 +10,9 @@
       oid="ffa9eaec-9539-4d15-97aa-24cd5b92ca5b">
     <name>metarole-department</name>
     <inducement id="1">
+        <targetRef oid="bee44c51-2469-411d-bac7-695728e9c241" type="c:OrgType"/>            <!-- departments -->
+    </inducement>
+    <inducement id="2">
         <construction>
             <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
             <attribute>
diff --git a/demo/complex/midpoint-objects/roles/metarole-grouper-group.xml b/demo/complex/midpoint-objects/roles/metarole-grouper-group.xml
new file mode 100644
index 0000000..34df300
--- /dev/null
+++ b/demo/complex/midpoint-objects/roles/metarole-grouper-group.xml
@@ -0,0 +1,55 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="48e231be-8474-4ed0-a85e-6acf4c5e8d52">
+    <name>metarole-grouper-group</name>
+    <inducement id="1">
+        <targetRef oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d" relation="org:default" type="c:OrgType" />     <!-- groups -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>generic-group</intent>
+        </construction>
+        <order>1</order>
+    </inducement>
+    <inducement id="3">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>generic-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <resourceRef oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" relation="org:default" type="c:ResourceType" />     <!-- CS CSV -->
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier == 'app:cs'</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</role>
diff --git a/demo/complex/midpoint-objects/roles/metarole-mailing-list.xml b/demo/complex/midpoint-objects/roles/metarole-mailing-list.xml
new file mode 100644
index 0000000..e5a680c
--- /dev/null
+++ b/demo/complex/midpoint-objects/roles/metarole-mailing-list.xml
@@ -0,0 +1,59 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="1c7beff4-cdf6-4e9f-b54c-79d0766f6fbe">
+    <name>metarole-mailing-list</name>
+    <inducement id="1">
+        <targetRef oid="d81fb46c-20c7-44d3-8402-fef404ea1264" relation="org:default" type="c:OrgType" />     <!-- mailing-lists -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>generic-group</intent>
+        </construction>
+        <order>1</order>
+    </inducement>
+    <inducement id="3">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>generic-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <resourceRef oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" relation="org:default" type="c:ResourceType" />     <!-- Mailing lists CSV -->
+            <attribute>
+                <c:ref>ri:lists</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</role>
diff --git a/demo/complex/midpoint-objects/roles/metarole-generic-group.xml b/demo/complex/midpoint-objects/roles/metarole-midpoint-group.xml
similarity index 92%
rename from demo/complex/midpoint-objects/roles/metarole-generic-group.xml
rename to demo/complex/midpoint-objects/roles/metarole-midpoint-group.xml
index f0e93c5..a2a2c9a 100644
--- a/demo/complex/midpoint-objects/roles/metarole-generic-group.xml
+++ b/demo/complex/midpoint-objects/roles/metarole-midpoint-group.xml
@@ -8,12 +8,12 @@
       xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       oid="c691e15a-f30b-4e15-8445-532db07ceeeb">
-    <name>metarole-generic-group</name>
+    <name>metarole-midpoint-group</name>
     <inducement id="1">
         <construction>
             <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
             <kind>entitlement</kind>
-            <intent>generic-group</intent>
+            <intent>midpoint-group</intent>
         </construction>
     </inducement>
     <inducement id="2">
@@ -26,7 +26,7 @@
                         <associationFromLink>
                             <projectionDiscriminator>
                                 <kind>entitlement</kind>
-                                <intent>generic-group</intent>
+                                <intent>midpoint-group</intent>
                             </projectionDiscriminator>
                         </associationFromLink>
                     </expression>
diff --git a/demo/complex/midpoint-objects/roles/role-grouper-sysadmin.xml b/demo/complex/midpoint-objects/roles/role-grouper-sysadmin.xml
index 5b559f8..cb81a23 100644
--- a/demo/complex/midpoint-objects/roles/role-grouper-sysadmin.xml
+++ b/demo/complex/midpoint-objects/roles/role-grouper-sysadmin.xml
@@ -10,8 +10,8 @@
       oid="d48ec05b-fffd-4262-acd3-d9ff63365b62">
     <name>role-grouper-sysadmin</name>
     <assignment id="1">
-        <targetRef oid="c691e15a-f30b-4e15-8445-532db07ceeeb" type="RoleType"/>         <!--  metarole-generic-group -->
+        <targetRef oid="c691e15a-f30b-4e15-8445-532db07ceeeb" type="RoleType"/>         <!--  metarole-midpoint-group -->
     </assignment>
-    <subtype>generic-group</subtype>
+    <subtype>midpoint-group</subtype>
     <identifier>sysadmingroup</identifier>
 </role>
diff --git a/demo/complex/midpoint-objects/systemConfigurations/SystemConfiguration.xml b/demo/complex/midpoint-objects/systemConfigurations/SystemConfiguration.xml
index 3c162e1..4d8dba6 100644
--- a/demo/complex/midpoint-objects/systemConfigurations/SystemConfiguration.xml
+++ b/demo/complex/midpoint-objects/systemConfigurations/SystemConfiguration.xml
@@ -91,7 +91,7 @@
          </auditing>
       </logging>
       <defaultObjectPolicyConfiguration id="18">
-         <type>RoleType</type>
+         <type>OrgType</type>
          <subtype>affiliation</subtype>
          <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="d87aa04f-189c-4d6f-b6e1-216dad622142" relation="org:default" type="tns:ObjectTemplateType"/>
       </defaultObjectPolicyConfiguration>
@@ -105,14 +105,19 @@
          <subtype>course</subtype>
          <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="d35bdec6-643b-41d8-ad5d-8eeb701169d1" relation="org:default" type="tns:ObjectTemplateType"/>
       </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="110">
+         <type>OrgType</type>
+         <subtype>mailing-list</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="be84a39a-c004-490b-9b78-a871b837f6df" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
       <defaultObjectPolicyConfiguration id="100">
          <type>OrgType</type>
-         <subtype>group</subtype>
+         <subtype>generic-group</subtype>
          <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="e2a6193a-8981-4143-9da1-9a7b32c0b819" relation="org:default" type="tns:ObjectTemplateType"/>
       </defaultObjectPolicyConfiguration>
       <defaultObjectPolicyConfiguration id="21">
          <type>RoleType</type>
-         <subtype>generic-group</subtype>
+         <subtype>midpoint-group</subtype>
          <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="804f8658-0828-4dab-a2ed-f13985e4f80b" relation="org:default" type="tns:ObjectTemplateType"/>
       </defaultObjectPolicyConfiguration>
       <defaultObjectPolicyConfiguration id="101">
@@ -171,6 +176,6 @@
             <color>purple</color>
             <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#resources</authorization>
          </userDashboardLink>
-         <enableExperimentalFeatures>true</enableExperimentalFeatures>
+         <enableExperimentalFeatures>false</enableExperimentalFeatures>
       </adminGuiConfiguration>
    </systemConfiguration>
diff --git a/demo/complex/midpoint_server/Dockerfile b/demo/complex/midpoint_server/Dockerfile
index 49e5fb4..43dac56 100644
--- a/demo/complex/midpoint_server/Dockerfile
+++ b/demo/complex/midpoint_server/Dockerfile
@@ -1,7 +1,9 @@
-FROM tier/midpoint
+FROM tier/midpoint:laboratory
 
 MAINTAINER info@evolveum.com
 
 ENV MP_DIR /opt/midpoint
 
+VOLUME ${MP_DIR}/var
+
 COPY container_files/mp-home/ ${MP_DIR}/var/
diff --git a/demo/complex/midpoint_server/container_files/mp-home/cs-portal.csv b/demo/complex/midpoint_server/container_files/mp-home/cs-portal.csv
new file mode 100644
index 0000000..dfe12f9
--- /dev/null
+++ b/demo/complex/midpoint_server/container_files/mp-home/cs-portal.csv
@@ -0,0 +1 @@
+identifier,name,mail,courses
diff --git a/demo/complex/midpoint_server/container_files/mp-home/faculty-portal.csv b/demo/complex/midpoint_server/container_files/mp-home/faculty-portal.csv
new file mode 100644
index 0000000..68a2307
--- /dev/null
+++ b/demo/complex/midpoint_server/container_files/mp-home/faculty-portal.csv
@@ -0,0 +1 @@
+uid,givenName,familyName,fullName,mail
diff --git a/demo/complex/midpoint_server/container_files/mp-home/mailing-lists.csv b/demo/complex/midpoint_server/container_files/mp-home/mailing-lists.csv
new file mode 100644
index 0000000..f9ee89b
--- /dev/null
+++ b/demo/complex/midpoint_server/container_files/mp-home/mailing-lists.csv
@@ -0,0 +1 @@
+uid,mail,lists
diff --git a/demo/complex/midpoint_server/container_files/mp-home/res/sis/SchemaScript.groovy b/demo/complex/midpoint_server/container_files/mp-home/res/sis-courses/SchemaScript.groovy
similarity index 100%
rename from demo/complex/midpoint_server/container_files/mp-home/res/sis/SchemaScript.groovy
rename to demo/complex/midpoint_server/container_files/mp-home/res/sis-courses/SchemaScript.groovy
diff --git a/demo/complex/midpoint_server/container_files/mp-home/res/sis/SearchScript.groovy b/demo/complex/midpoint_server/container_files/mp-home/res/sis-courses/SearchScript.groovy
similarity index 100%
rename from demo/complex/midpoint_server/container_files/mp-home/res/sis/SearchScript.groovy
rename to demo/complex/midpoint_server/container_files/mp-home/res/sis-courses/SearchScript.groovy
diff --git a/demo/complex/midpoint_server/container_files/mp-home/res/sis/TestScript.groovy b/demo/complex/midpoint_server/container_files/mp-home/res/sis-courses/TestScript.groovy
similarity index 100%
rename from demo/complex/midpoint_server/container_files/mp-home/res/sis/TestScript.groovy
rename to demo/complex/midpoint_server/container_files/mp-home/res/sis-courses/TestScript.groovy
diff --git a/demo/complex/midpoint_server/container_files/mp-home/schema/user-schema.xsd b/demo/complex/midpoint_server/container_files/mp-home/schema/internet2.xsd
similarity index 56%
rename from demo/complex/midpoint_server/container_files/mp-home/schema/user-schema.xsd
rename to demo/complex/midpoint_server/container_files/mp-home/schema/internet2.xsd
index 329534a..4c8e3af 100644
--- a/demo/complex/midpoint_server/container_files/mp-home/schema/user-schema.xsd
+++ b/demo/complex/midpoint_server/container_files/mp-home/schema/internet2.xsd
@@ -14,7 +14,19 @@
       </xsd:appinfo>
     </xsd:annotation>
     <xsd:sequence>
-        <xsd:element name="grouper_group" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="grouperGroup" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="rawAffiliation" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="OrgExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:OrgType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperName" type="xsd:string" minOccurs="0"/>
     </xsd:sequence>
   </xsd:complexType>  
 </xsd:schema>
diff --git a/demo/complex/show-queue-size.sh b/demo/complex/show-queue-size.sh
new file mode 100755
index 0000000..53b1e52
--- /dev/null
+++ b/demo/complex/show-queue-size.sh
@@ -0,0 +1 @@
+docker exec complex_mq_1 rabbitmqctl list_queues
diff --git a/demo/complex/targets/container_files/seed-data/target.sql b/demo/complex/targets/container_files/seed-data/target.sql
deleted file mode 100644
index 8b13789..0000000
--- a/demo/complex/targets/container_files/seed-data/target.sql
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/demo/complex/targets/container_files/seed-data/target.tmp b/demo/complex/targets/container_files/seed-data/target.tmp
new file mode 100644
index 0000000..01fa4ef
--- /dev/null
+++ b/demo/complex/targets/container_files/seed-data/target.tmp
@@ -0,0 +1,531 @@
+USE target;
+
+CREATE TABLE FACULTY_PORTAL_MEMBERS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE MAILING_LIST_MEMBERS (
+    list VARCHAR(255) NOT NULL,
+    member VARCHAR(255) NOT NULL,
+    PRIMARY KEY (list, member)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex/test-resources-1.sh b/demo/complex/test-resources-1.sh
index cfab1b3..c10c360 100755
--- a/demo/complex/test-resources-1.sh
+++ b/demo/complex/test-resources-1.sh
@@ -5,3 +5,6 @@ source $(dirname "$0")/../../library.bash
 test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
 test_resource 13660d60-071b-4596-9aa1-5efcd1256c04
 test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+test_resource a343fc2e-3954-4034-ba1a-2b72c21e577a
+test_resource e417225d-8a08-46f3-9b5d-624990b52386
+test_resource fe805d13-481b-43ec-97d8-9d2df72cd38e
diff --git a/demo/complex/update-bgasper-in-grouper.gsh b/demo/complex/update-bgasper-in-grouper.gsh
new file mode 100644
index 0000000..b0ed0b2
--- /dev/null
+++ b/demo/complex/update-bgasper-in-grouper.gsh
@@ -0,0 +1,13 @@
+
+def add(gs,groupName,subject) {
+	GroupFinder.findByName(gs, groupName, true).addMember(subject, false)
+}
+
+gs = GrouperSession.startRootSession()
+
+def bgasper = SubjectFinder.findById('bgasper', 'user', 'ldap')
+add(gs, 'ref:affiliation:alum_excludes', bgasper)
+add(gs, 'ref:affiliation:faculty_includes', bgasper)
+add(gs, 'app:mailinglist:chess', bgasper)
+add(gs, 'app:mailinglist:idm-fans', bgasper)
+add(gs, 'test:volunteers', bgasper)
diff --git a/demo/complex/update-bgasper-in-grouper.sh b/demo/complex/update-bgasper-in-grouper.sh
new file mode 100755
index 0000000..d318a74
--- /dev/null
+++ b/demo/complex/update-bgasper-in-grouper.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+source ../../library.bash
+
+#docker cp update-bgasper-in-grouper.gsh complex_grouper_daemon_1:/tmp/
+#docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/update-bgasper-in-grouper.gsh"
+
+execute_gsh complex_grouper_daemon_1 update-bgasper-in-grouper.gsh
diff --git a/demo/complex/upload-async-update-task.sh b/demo/complex/upload-async-update-task.sh
new file mode 100755
index 0000000..bdf8ba2
--- /dev/null
+++ b/demo/complex/upload-async-update-task.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-async-update-grouper.xml
diff --git a/demo/complex/upload-import-sis-courses.sh b/demo/complex/upload-import-sis-courses.sh
new file mode 100755
index 0000000..20d8b20
--- /dev/null
+++ b/demo/complex/upload-import-sis-courses.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-import-sis-courses.xml
diff --git a/demo/complex/upload-import-sis-persons.sh b/demo/complex/upload-import-sis-persons.sh
new file mode 100755
index 0000000..058c9af
--- /dev/null
+++ b/demo/complex/upload-import-sis-persons.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-import-sis-persons.xml
diff --git a/demo/complex/upload-reconcile-grouper-groups.sh b/demo/complex/upload-reconcile-grouper-groups.sh
new file mode 100755
index 0000000..94deb18
--- /dev/null
+++ b/demo/complex/upload-reconcile-grouper-groups.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
diff --git a/demo/complex/upload-reconcile-grouper-users.sh b/demo/complex/upload-reconcile-grouper-users.sh
new file mode 100755
index 0000000..f6089ac
--- /dev/null
+++ b/demo/complex/upload-reconcile-grouper-users.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
diff --git a/demo/complex0/.env b/demo/complex0/.env
new file mode 100644
index 0000000..75949b1
--- /dev/null
+++ b/demo/complex0/.env
@@ -0,0 +1,14 @@
+AUTHENTICATION=internal
+ENV=demo
+REPO_DATABASE_TYPE=mariadb
+REPO_JDBC_URL=default
+REPO_HOST=midpoint_data
+REPO_PORT=default
+REPO_DATABASE=registry
+REPO_USER=registry_user
+REPO_MISSING_SCHEMA_ACTION=create
+REPO_UPGRADEABLE_SCHEMA_ACTION=stop
+MP_MEM_MAX=2048m
+MP_MEM_INIT=1024m
+SSO_HEADER=uid
+TIMEZONE=UTC
diff --git a/demo/complex0/README.md b/demo/complex0/README.md
new file mode 100644
index 0000000..9b7f0f6
--- /dev/null
+++ b/demo/complex0/README.md
@@ -0,0 +1,9 @@
+This is a demonstration of using midPoint dockerization for TIER environment in a broader context. It is a work in progress.
+
+# Building and execution
+```
+$ ../../build.sh
+$ docker-compose up --build
+```
+
+Please see a detailed description [here](https://spaces.at.internet2.edu/display/MID/Complex+midPoint+integration+demo).
diff --git a/demo/complex0/after-installation.sh b/demo/complex0/after-installation.sh
new file mode 100755
index 0000000..68582e3
--- /dev/null
+++ b/demo/complex0/after-installation.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+B='\033[1;33m'
+N='\033[0m'
+
+echo -e "${B} * Uploading objects...${N}"
+$(dirname "$0")/upload-objects.sh
+
+echo -e "${B} * Testing LDAP and SQL resources...${N}"
+$(dirname "$0")/test-resources-1.sh
+
+echo -e "${B} * Recomputing Grouper admin group and user object...${N}"
+$(dirname "$0")/recompute.sh
+
+echo -e "${B} * Waiting 120 seconds for changes to propagate to Grouper...${N}"
+sleep 120
+
+echo -e "${B} * Testing Grouper resource...${N}"
+$(dirname "$0")/test-resource-grouper.sh
+
+echo -e "${B} * Done${N}"
diff --git a/demo/complex0/configs-and-secrets/grouper/application/database_password.txt b/demo/complex0/configs-and-secrets/grouper/application/database_password.txt
new file mode 100644
index 0000000..e69de29
diff --git a/demo/complex0/configs-and-secrets/grouper/application/grouper-loader.properties b/demo/complex0/configs-and-secrets/grouper/application/grouper-loader.properties
new file mode 100644
index 0000000..62ef5f0
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/application/grouper-loader.properties
@@ -0,0 +1,71 @@
+#################################
+## LDAP connections
+#################################
+# specify the ldap connection with user, pass, url
+# the string after "ldap." is the ID of the connection, and it should not have
+# spaces or other special chars in it.  In this case is it "personLdap"
+
+#note the URL should start with ldap: or ldaps: if it is SSL.  
+#It should contain the server and port (optional if not default), and baseDn,
+#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu
+ldap.demo.url = ldap://directory:389/dc=internet2,dc=edu
+ 
+#optional, if authenticated
+ldap.demo.user = cn=admin,dc=internet2,dc=edu
+#ldap.demo.user = cn=admin
+ 
+#optional, if authenticated note the password can be stored encrypted in an external file
+#ldap.demo.pass = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+ldap.demo.pass = password
+ 
+#optional, if you are using tls, set this to true.  Generally you will not be using an SSL URL to use TLS...
+ldap.demo.tls = false
+ 
+#optional, if using sasl
+#ldap.personLdap.saslAuthorizationId =
+#ldap.personLdap.saslRealm =
+ 
+#optional (note, time limit is for search operations, timeout is for connection timeouts),
+#most of these default to vt-ldap defaults.  times are in millis
+#validateOnCheckout defaults to true if all other validate methods are false
+#ldap.personLdap.batchSize =
+#ldap.personLdap.countLimit =
+#ldap.personLdap.timeLimit =
+#ldap.personLdap.timeout =
+#ldap.personLdap.minPoolSize =
+#ldap.personLdap.maxPoolSize =
+#ldap.personLdap.validateOnCheckIn =
+#ldap.personLdap.validateOnCheckOut =
+#ldap.personLdap.validatePeriodically =
+#ldap.personLdap.validateTimerPeriod =
+#ldap.personLdap.pruneTimerPeriod =
+#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes)
+#ldap.personLdap.expirationTime =
+
+#make the paths fully qualified and not relative to the loader group.
+loader.ldap.requireTopStemAsStemFromConfigGroup=false
+
+
+db.sis.user = sis_user
+db.sis.pass = 49321420423
+db.sis.url = jdbc:mysql://sources:3306/sis
+db.sis.driver = com.mysql.jdbc.Driver
+
+
+#####################################
+## Messaging integration with change log
+#####################################
+changeLog.consumer.rabbitMqMessagingSample.quartzCron = 0 * * * * ?                                                          
+
+# note, change "messagingSample" in key to be the name of the consumer.  e.g. changeLog.consumer.someNameAnyName.class
+changeLog.consumer.rabbitMqMessagingSample.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer
+
+changeLog.consumer.rabbitMqMessagingSample.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher
+changeLog.consumer.rabbitMqMessagingSample.publisher.messagingSystemName = rabbitmq
+# note, routingKey property is valid only for rabbitmq. For other messaging systems, it is ignored.
+changeLog.consumer.rabbitMqMessagingSample.publisher.routingKey = 
+## queue or topic
+changeLog.consumer.rabbitMqMessagingSample.publisher.messageQueueType = queue
+changeLog.consumer.rabbitMqMessagingSample.publisher.queueOrTopicName = sampleQueue
+## this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml
+#changeLog.consumer.rabbitMqMessagingSample.publisher.addSubjectAttributes = email
diff --git a/demo/complex0/configs-and-secrets/grouper/application/grouper.client.properties b/demo/complex0/configs-and-secrets/grouper/application/grouper.client.properties
new file mode 100644
index 0000000..d25ad96
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/application/grouper.client.properties
@@ -0,0 +1,112 @@
+#
+# Copyright 2014 Internet2
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Grouper client configuration
+# $Id: grouper.client.example.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $
+#
+
+# The grouper client uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.client.base.properties
+# (which should not be edited), and the grouper.client.properties overlays
+# the base settings.  See the grouper.client.base.properties for the possible
+# settings that can be applied to the grouper.client.properties
+
+########################################
+## LDAP connection settings
+########################################
+
+# url of directory, including the base DN (distinguished name)
+# e.g. ldap://server.school.edu/dc=school,dc=edu
+# e.g. ldaps://server.school.edu/dc=school,dc=edu
+grouperClient.ldap.url =
+
+# kerberos principal used to connect to ldap
+grouperClient.ldap.login =
+
+# password for shared secret authentication to ldap
+# or you can put a filename with an encrypted password
+grouperClient.ldap.password =
+
+########################################
+## Web service Connection settings
+########################################
+
+# url of web service, should include everything up to the first resource to access
+# e.g. http://groups.school.edu:8090/grouper-ws/servicesRest
+# e.g. https://groups.school.edu/grouper-ws/servicesRest
+grouperClient.webService.url = https://grouper_ws/grouper-ws/servicesRest
+
+# kerberos principal used to connect to web service
+grouperClient.webService.login = banderson
+
+# password for shared secret authentication to web service
+# or you can put a filename with an encrypted password
+grouperClient.webService.password.elConfig = ${java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD') }
+
+
+################################
+## Grouper Messaging System
+################################
+ 
+# name of messaging system which is the default
+grouper.messaging.default.name.of.messaging.system = rabbitmq
+ 
+# name of a messaging system.  note, "grouperBuiltinMessaging" can be arbitrary
+# grouper.messaging.system.grouperBuiltinMessaging.name = grouperBuiltinMessaging
+ 
+# class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem
+# grouper.messaging.system.grouperBuiltinMessaging.class = edu.internet2.middleware.grouper.messaging.GrouperBuiltinMessagingSystem
+ 
+# name of a messaging system.  note, "grouperBuiltinMessaging" can be arbitrary
+grouper.messaging.system.rabbitmqSystem.name = rabbitmqSystem
+ 
+# class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem
+grouper.messaging.system.rabbitmqSystem.class = edu.internet2.middleware.grouperMessagingRabbitmq.GrouperMessagingRabbitmqSystem
+ 
+# host address of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.host = mq
+ 
+# virtual host of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.virtualhost =
+ 
+# port of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.port =
+ 
+grouper.messaging.system.rabbitmqSystem.defaultPageSize = 10
+ 
+grouper.messaging.system.rabbitmqSystem.maxPageSize = 50
+ 
+ 
+# name of a messaging system, required
+grouper.messaging.system.rabbitmq.name = rabbitmq
+ 
+# default system settings to this messaging system, note, there is only one level of inheritance
+grouper.messaging.system.rabbitmq.defaultSystemName = rabbitmqSystem
+
+grouper.messaging.system.rabbitmq.user = guest
+
+#pass
+grouper.messaging.system.rabbitmq.password.elConfig = ${java.lang.System.getenv().get('RABBITMQ_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('RABBITMQ_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('RABBITMQ_PASSWORD') }
+# set the following three properties if you want to use TLS connection to rabbitmq. All three need to be populated.
+# TLS Version
+#grouper.messaging.system.rabbitmqSystem.tlsVersion = TLSv1.1
+ 
+# path to trust store file
+#grouper.messaging.system.rabbitmqSystem.pathToTrustStore =
+ 
+# trust passphrase
+#grouper.messaging.system.rabbitmqSystem.trustPassphrase =
diff --git a/demo/complex0/configs-and-secrets/grouper/application/grouper.hibernate.properties b/demo/complex0/configs-and-secrets/grouper/application/grouper.hibernate.properties
new file mode 100644
index 0000000..deb0d75
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/application/grouper.hibernate.properties
@@ -0,0 +1,29 @@
+#
+# Grouper Hibernate Configuration
+# $Id: grouper.hibernate.example.properties,v 1.9 2009-08-11 20:18:09 mchyzer Exp $
+#
+
+# The grouper hibernate config uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.hibernate.base.properties
+# (which should not be edited), and the grouper.hibernate.properties overlays
+# the base settings.  See the grouper.hibernate.base.properties for the possible
+# settings that can be applied to the grouper.hibernate.properties
+
+########################################
+## DB settings
+########################################
+
+# e.g. mysql:           jdbc:mysql://localhost:3306/grouper
+# e.g. p6spy (log sql): [use the URL that your DB requires]
+# e.g. oracle:          jdbc:oracle:thin:@server.school.edu:1521:sid
+# e.g. hsqldb (a):      jdbc:hsqldb:dist/run/grouper;create=true
+# e.g. hsqldb (b):      jdbc:hsqldb:hsql://localhost:9001/grouper
+# e.g. postgres:        jdbc:postgresql://localhost:5432/database
+# e.g. mssql:           jdbc:sqlserver://localhost:3280;databaseName=grouper
+hibernate.connection.url = jdbc:mysql://grouper_data:3306/grouper?CharSet=utf8&useUnicode=true&characterEncoding=utf8
+
+hibernate.connection.username         = root
+# If you are using an empty password, depending upon your version of
+# Java and Ant you may need to specify a password of "".
+# Note: you can keep passwords external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122
+hibernate.connection.password.elConfig = ${java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD') }
diff --git a/demo/complex0/configs-and-secrets/grouper/application/grouper.properties b/demo/complex0/configs-and-secrets/grouper/application/grouper.properties
new file mode 100644
index 0000000..c931287
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/application/grouper.properties
@@ -0,0 +1,25 @@
+#
+# Grouper Configuration
+# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $
+#
+
+# Grouper uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.base.properties
+# (which should not be edited), and the grouper.properties overlays
+# the base settings.  See the grouper.base.properties for the possible
+# settings that can be applied to the grouper.properties
+
+#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on)
+configuration.autocreate.system.groups = true
+
+# A wheel group allows you to enable non-GrouperSystem subjects to act
+# like a root user when interacting with the registry.
+groups.wheel.use                      = true
+
+# Set to the name of the group you want to treat as the wheel group.
+# The members of this group will be treated as root-like users.
+groups.wheel.group                    = etc:sysadmingroup
+
+# Used to allow Include Exclude groups
+grouperIncludeExclude.use = true
+grouperIncludeExclude.requireGroups.use = true
diff --git a/demo/complex0/configs-and-secrets/grouper/application/rabbitmq_password.txt b/demo/complex0/configs-and-secrets/grouper/application/rabbitmq_password.txt
new file mode 100644
index 0000000..158f675
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/application/rabbitmq_password.txt
@@ -0,0 +1 @@
+guest
\ No newline at end of file
diff --git a/demo/complex0/configs-and-secrets/grouper/application/subject.properties b/demo/complex0/configs-and-secrets/grouper/application/subject.properties
new file mode 100644
index 0000000..577db03
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/application/subject.properties
@@ -0,0 +1,78 @@
+#subject.sources.xml.location =
+
+subjectApi.source.ldap.param.ldapServerId.value = demo
+
+subjectApi.source.ldap.id = ldap
+subjectApi.source.ldap.name = EDU Ldap 
+subjectApi.source.ldap.types = person
+subjectApi.source.ldap.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter
+#subjectApi.source.ldap.param.INITIAL_CONTEXT_FACTORY.value = com.sun.jndi.ldap.LdapCtxFactory
+#subjectApi.source.ldap.param.PROVIDER_URL.value = ldap://directory:389
+#subjectApi.source.ldap.param.SECURITY_AUTHENTICATION.value = simple
+#subjectApi.source.ldap.param.SECURITY_PRINCIPAL.value = cn=admin,dc=internet2,dc=edu
+#subjectApi.source.ldap.param.SECURITY_CREDENTIALS.value.elConfig = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+#subjectApi.source.ldap.param.VTLDAP_VALIDATOR.value = ConnectLdapValidator
+
+subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid
+subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false
+subjectApi.source.ldap.param.Name_AttributeType.value = cn
+subjectApi.source.ldap.param.Description_AttributeType.value = cn
+subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")}
+subjectApi.source.ldap.param.sortAttribute0.value = cn
+subjectApi.source.ldap.param.searchAttribute0.value = searchAttribute0
+
+# STATUS SECTION for searches to filter out inactives and allow
+# the user to filter by status with e.g. status=all
+# this is optional, and advanced
+#
+# field in database or ldap or endpoint that is the status field
+#subjectApi.source.example.param.statusDatastoreFieldName.value = status
+
+# search string from user which represents the status.  e.g. status=active
+#subjectApi.source.example.param.statusLabel.value = status
+
+# available statuses from screen (if not specified, any will be allowed). comma separated list.
+# Note, this is optional and you probably dont want to configure it, it is mostly necessary
+# when you have multiple sources with statuses...  if someone types an invalid status
+# and you have this configured, it will not filter by it
+#subjectApi.source.example.param.statusesFromUser.value = Active, Inactive, Pending, All
+
+# all label from the user
+#subjectApi.source.example.param.statusAllFromUser.value = All
+
+# if no status is specified, this will be used (e.g. for active only).  Note, the value should be of the
+# form the user would type in
+#subjectApi.source.example.param.statusSearchDefault.value = status=active
+
+# translate between screen values of status, and the data store value.  Increment the 0 to 1, 2, etc for more translations.
+# so the user could enter: status=active, and that could translate to status_col=A.  The 'user' is what the user types in,
+# the 'datastore' is what is in the datastore.  The user part is not case-sensitive.  Note, this could be a many to one
+#subjectApi.source.example.param.statusTranslateUser0.value = active
+#subjectApi.source.example.param.statusTranslateDatastore0.value = A
+
+# subject identifier to store in grouper's member table.  this is used to increase speed of loader and perhaps for provisioning
+# you can have up to max 1 subject identifier
+#subjectApi.source.example.param.subjectIdentifierAttribute0.value = uid
+
+#searchSubject: find a subject by ID.  ID is generally an opaque and permanent identifier, e.g. 12345678.
+#  Each subject has one and only on ID.  Returns one result when searching for one ID.
+subjectApi.source.ldap.search.searchSubject.param.filter.value = (&(uid=%TERM%)(objectclass=person))
+subjectApi.source.ldap.search.searchSubject.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubject.param.base.value = ou=people
+
+#searchSubjectByIdentifier: find a subject by identifier.  Identifier is anything that uniquely
+#  identifies the user, e.g. jsmith or jsmith@institution.edu.
+#  Subjects can have multiple identifiers.  Note: it is nice to have if identifiers are unique
+#  even across sources.  Returns one result when searching for one identifier.
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.filter.value = (&(|(uid=%TERM%)(employeeNumber=%TERM%))(objectclass=person))
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.base.value = ou=people
+
+#   search: find subjects by free form search.  Returns multiple results.
+
+subjectApi.source.ldap.search.search.param.filter.value = (&(|(|(uid=%TERM%)(cn=*%TERM%*))(uid=%TERM%*))(objectclass=person))
+subjectApi.source.ldap.search.search.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.search.param.base.value = ou=people
+
+subjectApi.source.ldap.attributes = givenName, sn, uid, mail, employeeNumber
+subjectApi.source.ldap.internalAttributes = searchAttribute0
diff --git a/demo/complex0/configs-and-secrets/grouper/httpd/cachain-cer.pem b/demo/complex0/configs-and-secrets/grouper/httpd/cachain-cer.pem
new file mode 100644
index 0000000..e69de29
diff --git a/demo/complex0/configs-and-secrets/grouper/httpd/host-cert.pem b/demo/complex0/configs-and-secrets/grouper/httpd/host-cert.pem
new file mode 100644
index 0000000..9cc228a
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/httpd/host-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+-----END CERTIFICATE-----
diff --git a/demo/complex0/configs-and-secrets/grouper/httpd/host-key.pem b/demo/complex0/configs-and-secrets/grouper/httpd/host-key.pem
new file mode 100644
index 0000000..1b0b579
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEzSZrDaU6UeDa
+wycDoCv6N1GJTXYtXOsQX5bfpYiwLEHNetEEXleHUkhivC2bzefGvwUyLB/HS4UJ
+VEPKkFGNgH6JVazcW+1mrpnofzzs2FE0cpZ6BqVN1mxjBD8RPwHYD+VP2nWL8ruF
+yOXqb+8I2STk6nFWoNeUmpWPmrKPmQv+ZflM0cZlgWcSk7Ei9cuzxXoWOP2Zd2N6
+BlbFZf87KbeZbXqGUHnlcVF9vUtwH9dch2OMaRKfu67wM2P55bE4hwLFKAhSvzRU
+Nnr70kcedgfRZNXFj9TA1Q5tkI0Kg/cQRmEp1+m4UHo1ceyVCR5W5btkOaeV3VtA
+YoYBZbqBAgMBAAECggEAA/5t0ypZug9DUu0283niqpdIzlKGHXGPS6vE8hD37ytW
+wobFiyMm/5YJ5gcPnePV2lCyGEyQ8Ih10LSnE4tOPGLpLnxQn8A11ymf8fnzEJNr
+Qnc42o0b+bJqTLAfX4g5z1qzOqWiUQ7CA3sKP3G6FiHh/8tKNYnaFif09Q8cpJFb
+YDDkvm48NJgsrIoCgmaFIQIn+yDzGQKWwTNMIks+RByWpc67j1x1kiyQM1RfrEev
+Yyq/ZkP66IYZzmZKpFCWGs5qbRZdxyXNpq85DjwA99lAH7vxtMJHQM4z1h1eDH4L
+Ma5hEnmmHu4D5lF2GDQYflvuFdDGH5tThO6MV0IrSQKBgQD+kvEtNxJCMxLOVFyV
+NWF3pk/i2nkD+53t/VPXjMPtW7IesouEGzU82I/fT2wUTkNwFdkVpv37qoLypKZm
+npJFxr6abQNjiDh2Fsh8/iuJfvdZUFJbCEY6NS58qgjix8XCQKRD06EugK7uekIZ
+zJnttF3qVBBD8Z8Uwxz8i+jF1wKBgQDF51y/5XB6Bz47cdxw7P8NsfnTz2V3H0HU
+OnlEBANbhmBadjU8dqbM54Nxbn7VOdooXPuSnAKJ9vPDg1n5Y/GO+lgldNzfyK6g
+HnbldSu0zBvAaGvmAjLjetEtOkBqYkrHJlT6JAems/Kc/YX5uooAz9/jNJFXP9++
+KbjH3CzHZwKBgQC6ppxEDZPKi83nD/2NvMTIyFzcNFj0LaEepFW7vc7NkiSn0zrt
+0lEXWqUqEv5oaPWTEcHH2VdxFRTLuSL0LKGMnWqUqQcKDA9xrcSzuFvNhRTwHC81
+5XwwI1wBNV4sgFKj2WdW/6y2/szDt0oNxnC50zvkmlwOpPKBc4kmNaKmowKBgBmC
+uXIDIXyZcmw3QTNNWZNqXcnv8iRo4xN4dilOWyBxMfp3QmWI5feD4G2+0Jqr2nNZ
+iRRdB/bA3qtVQ0PinkDQBIzPg6lVNS1uv+TUNc4YgXtL+pyrq+Om8U/jMmqEQR9q
+0YltG49houSZyatnYGK6aSHgpNuaYD0jI66fsyYBAoGAMefyD0I/ncArjuf58hVQ
+zSjxfcvlja9okrC8ZgqsVluezcm4rQNcSjBnESGTCjJC7O29AofGLHkvnsBQDiGk
+hE38IRisd+okXdApr41ifWDhmtASud5q6wlhOpMmQxg+OALf1rTvFYhbnFEXV/KY
+e5A4iXLRIbxbmXZDa35Rebw=
+-----END PRIVATE KEY-----
diff --git a/demo/complex0/configs-and-secrets/grouper/shibboleth/idp-metadata.xml b/demo/complex0/configs-and-secrets/grouper/shibboleth/idp-metadata.xml
new file mode 100644
index 0000000..4fa67a7
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/shibboleth/idp-metadata.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex0/configs-and-secrets/grouper/shibboleth/shibboleth2.xml b/demo/complex0/configs-and-secrets/grouper/shibboleth/shibboleth2.xml
new file mode 100644
index 0000000..0c38f82
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/shibboleth/shibboleth2.xml
@@ -0,0 +1,136 @@
+<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"    
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    clockSkew="180">
+
+    <!--
+    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
+    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
+    -->
+
+    <!--
+    To customize behavior for specific resources on Apache, and to link vhosts or
+    resources to ApplicationOverride settings below, use web server options/commands.
+    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
+    
+    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
+    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
+    -->
+    <TCPListener address="127.0.0.1" port="1600"/> 
+
+
+    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
+    <ApplicationDefaults entityID="https://grouperdemo/shibboleth"
+                         REMOTE_USER="uid">
+
+        <!--
+        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
+        You MUST supply an effectively unique handlerURL value for each of your applications.
+        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
+        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
+        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
+        Note that while we default checkAddress to "false", this has a negative impact on the
+        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
+        -->
+        <Sessions lifetime="28800" timeout="28800" relayState="ss:mem"
+                  checkAddress="false" handlerSSL="true" cookieProps="https">
+
+            <!--
+            Configures SSO for a default IdP. To allow for >1 IdP, remove
+            entityID property and adjust discoveryURL to point to discovery service.
+            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
+            You can also override entityID on /Login query string, or in RequestMap/htaccess.
+            -->
+		<SSO entityID="https://idptestbed/idp/shibboleth">
+			SAML2
+		</SSO>
+
+            <!-- SAML and local-only logout. -->
+            <Logout>SAML2 Local</Logout>
+            
+            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
+            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
+
+            <!-- Status reporting service. -->
+            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
+
+            <!-- Session diagnostic service. -->
+            <Handler type="Session" Location="/Session" showAttributeValues="true"/>
+
+            <!-- JSON feed of discovery information. -->
+            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
+        </Sessions>
+
+        <!--
+        Allows overriding of error template information/filenames. You can
+        also add attributes with values that can be plugged into the templates.
+        -->
+        <Errors supportContact="root@localhost"
+            helpLocation="/about.html"
+            styleSheet="/shibboleth-sp/main.css"/>
+        
+        <!-- Example of remotely supplied batch of signed metadata. -->
+        <!--
+        <MetadataProvider type="XML" validate="true"
+	      uri="http://example.org/federation-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <MetadataProvider type="XML" validate="true" file="idp-metadata.xml"/>
+
+        <!--
+        InCommon
+	  <MetadataProvider type="XML" validate="true"
+		uri="http://md.incommon.org/InCommon/InCommon-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+		<MetdataFilter type="Signature" certificate="inc-md-cert.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <!-- Map to extract attributes from SAML assertions. -->
+        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
+        
+        <!-- Use a SAML query if no attributes are supplied during SSO. -->
+        <AttributeResolver type="Query" subjectMatch="true"/>
+
+        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
+        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
+
+        <!-- Simple file-based resolver for using a single keypair. -->
+        <CredentialResolver type="File" key="sp-key.pem" certificate="sp-cert.pem"/>
+
+        <!--
+        The default settings can be overridden by creating ApplicationOverride elements (see
+        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
+        Resource requests are mapped by web server commands, or the RequestMapper, to an
+        applicationId setting.
+        
+        Example of a second application (for a second vhost) that has a different entityID.
+        Resources on the vhost would map to an applicationId of "admin":
+        -->
+        <!--
+        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
+        -->
+    </ApplicationDefaults>
+    
+    <!-- Policies that determine how to process and authenticate runtime messages. -->
+    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
+
+    <!-- Low-level configuration about protocols and bindings available for use. -->
+    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
+
+</SPConfig>
diff --git a/demo/complex0/configs-and-secrets/grouper/shibboleth/sp-cert.pem b/demo/complex0/configs-and-secrets/grouper/shibboleth/sp-cert.pem
new file mode 100644
index 0000000..9cc228a
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/shibboleth/sp-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+-----END CERTIFICATE-----
diff --git a/demo/complex0/configs-and-secrets/grouper/shibboleth/sp-key.pem b/demo/complex0/configs-and-secrets/grouper/shibboleth/sp-key.pem
new file mode 100644
index 0000000..1b0b579
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/grouper/shibboleth/sp-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEzSZrDaU6UeDa
+wycDoCv6N1GJTXYtXOsQX5bfpYiwLEHNetEEXleHUkhivC2bzefGvwUyLB/HS4UJ
+VEPKkFGNgH6JVazcW+1mrpnofzzs2FE0cpZ6BqVN1mxjBD8RPwHYD+VP2nWL8ruF
+yOXqb+8I2STk6nFWoNeUmpWPmrKPmQv+ZflM0cZlgWcSk7Ei9cuzxXoWOP2Zd2N6
+BlbFZf87KbeZbXqGUHnlcVF9vUtwH9dch2OMaRKfu67wM2P55bE4hwLFKAhSvzRU
+Nnr70kcedgfRZNXFj9TA1Q5tkI0Kg/cQRmEp1+m4UHo1ceyVCR5W5btkOaeV3VtA
+YoYBZbqBAgMBAAECggEAA/5t0ypZug9DUu0283niqpdIzlKGHXGPS6vE8hD37ytW
+wobFiyMm/5YJ5gcPnePV2lCyGEyQ8Ih10LSnE4tOPGLpLnxQn8A11ymf8fnzEJNr
+Qnc42o0b+bJqTLAfX4g5z1qzOqWiUQ7CA3sKP3G6FiHh/8tKNYnaFif09Q8cpJFb
+YDDkvm48NJgsrIoCgmaFIQIn+yDzGQKWwTNMIks+RByWpc67j1x1kiyQM1RfrEev
+Yyq/ZkP66IYZzmZKpFCWGs5qbRZdxyXNpq85DjwA99lAH7vxtMJHQM4z1h1eDH4L
+Ma5hEnmmHu4D5lF2GDQYflvuFdDGH5tThO6MV0IrSQKBgQD+kvEtNxJCMxLOVFyV
+NWF3pk/i2nkD+53t/VPXjMPtW7IesouEGzU82I/fT2wUTkNwFdkVpv37qoLypKZm
+npJFxr6abQNjiDh2Fsh8/iuJfvdZUFJbCEY6NS58qgjix8XCQKRD06EugK7uekIZ
+zJnttF3qVBBD8Z8Uwxz8i+jF1wKBgQDF51y/5XB6Bz47cdxw7P8NsfnTz2V3H0HU
+OnlEBANbhmBadjU8dqbM54Nxbn7VOdooXPuSnAKJ9vPDg1n5Y/GO+lgldNzfyK6g
+HnbldSu0zBvAaGvmAjLjetEtOkBqYkrHJlT6JAems/Kc/YX5uooAz9/jNJFXP9++
+KbjH3CzHZwKBgQC6ppxEDZPKi83nD/2NvMTIyFzcNFj0LaEepFW7vc7NkiSn0zrt
+0lEXWqUqEv5oaPWTEcHH2VdxFRTLuSL0LKGMnWqUqQcKDA9xrcSzuFvNhRTwHC81
+5XwwI1wBNV4sgFKj2WdW/6y2/szDt0oNxnC50zvkmlwOpPKBc4kmNaKmowKBgBmC
+uXIDIXyZcmw3QTNNWZNqXcnv8iRo4xN4dilOWyBxMfp3QmWI5feD4G2+0Jqr2nNZ
+iRRdB/bA3qtVQ0PinkDQBIzPg6lVNS1uv+TUNc4YgXtL+pyrq+Om8U/jMmqEQR9q
+0YltG49houSZyatnYGK6aSHgpNuaYD0jI66fsyYBAoGAMefyD0I/ncArjuf58hVQ
+zSjxfcvlja9okrC8ZgqsVluezcm4rQNcSjBnESGTCjJC7O29AofGLHkvnsBQDiGk
+hE38IRisd+okXdApr41ifWDhmtASud5q6wlhOpMmQxg+OALf1rTvFYhbnFEXV/KY
+e5A4iXLRIbxbmXZDa35Rebw=
+-----END PRIVATE KEY-----
diff --git a/demo/complex0/configs-and-secrets/midpoint/application/database_password.txt b/demo/complex0/configs-and-secrets/midpoint/application/database_password.txt
new file mode 100644
index 0000000..11bff19
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/application/database_password.txt
@@ -0,0 +1 @@
+WJzesbe3poNZ91qIbmR7
diff --git a/demo/complex0/configs-and-secrets/midpoint/application/keystore_password.txt b/demo/complex0/configs-and-secrets/midpoint/application/keystore_password.txt
new file mode 100644
index 0000000..1d40192
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/application/keystore_password.txt
@@ -0,0 +1 @@
+changeit
diff --git a/demo/complex0/configs-and-secrets/midpoint/httpd/host-cert.pem b/demo/complex0/configs-and-secrets/midpoint/httpd/host-cert.pem
new file mode 100644
index 0000000..9b1021b
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/httpd/host-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAMOSkn4oS2aAMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXbWlkcG9pbnQuc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU1OTQ1WhcNMTkwOTE0MDU1OTQ1WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF21pZHBvaW50LnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApj/b7MEUSfu3oXMfNgRwTse7
+a5UV7Jswf1M/ZN/ZZkAkIxNBevZgozjesvLPWrmsTgONi7XigJUJvCjdjmlW9eDM
+lri/rkD8HuOR1DQCVKL9nvoS2c3D7sq5Emda3V8Tlj82VqfEmePd3sajx7mcTfbH
+8jwAL9NhkC+WMib5IpjLGpG0FEAC0ha7Lxb+7jIiqHVJaqLXJGCyGN4mh6c1Q9S1
+f8RVTiW2a8x22G+9wnZYbkiA2Kxls177imHlhSz8EdvV4IpGw1amrEWhhuDEum7B
+vZ1xQDLatgRqh4qAKLIVYeRnJ8H1FelMa90qB4G08MIPifmTsQwqJyBYaEdgWQID
+AQABo1MwUTAdBgNVHQ4EFgQUqb9BteODF6wv5R57aEON/wGXMiowHwYDVR0jBBgw
+FoAUqb9BteODF6wv5R57aEON/wGXMiowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAAcKhxI+tSItrXmqC0PSmgWyAYpqbkz6W/cefTutXqhIgY09f
+h0LSv7ogTahoGpyiZk9vy6u3OE9bYwxapEfa4KBjO6HxBMIVBBb3RegVjoPzjElN
+BDwAx0VGFcZTXwMxDWycWdG8ql7rCZBvS50w04uTaIgnGmqXAdWWmBgfJ9cRbxW+
+JwO/mOl1QM1lR/5142NpvuUVWlmZSKEGydE5A1qPz2wpDbBR1ym1BQNS4NEqw6Kp
+GSB8jKyCS1Ve0v2wVze2038Wukz02dq9uKPTIO3T+B+ibZmxn6Op/kFCc1/kK5NS
+Q6JdO1B6KquGAYdGmKAcQ19mv+jqGktqWEEf0g==
+-----END CERTIFICATE-----
diff --git a/demo/complex0/configs-and-secrets/midpoint/httpd/host-key.pem b/demo/complex0/configs-and-secrets/midpoint/httpd/host-key.pem
new file mode 100644
index 0000000..5746e59
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmP9vswRRJ+7eh
+cx82BHBOx7trlRXsmzB/Uz9k39lmQCQjE0F69mCjON6y8s9auaxOA42LteKAlQm8
+KN2OaVb14MyWuL+uQPwe45HUNAJUov2e+hLZzcPuyrkSZ1rdXxOWPzZWp8SZ493e
+xqPHuZxN9sfyPAAv02GQL5YyJvkimMsakbQUQALSFrsvFv7uMiKodUlqotckYLIY
+3iaHpzVD1LV/xFVOJbZrzHbYb73CdlhuSIDYrGWzXvuKYeWFLPwR29XgikbDVqas
+RaGG4MS6bsG9nXFAMtq2BGqHioAoshVh5GcnwfUV6Uxr3SoHgbTwwg+J+ZOxDCon
+IFhoR2BZAgMBAAECggEAEIRBpjjceiku6jRUwnoYaks/nIWYQwR8AfpUTwJKR/VR
+Yca097Fokm7A+UhUP3A45RtHQb0VPq8P44iv0kk24YCu8r5yFK7SHYOAZnOwU5ZJ
+2jSAEPF3aM7tKh3okhuzB3dKP7u1NZDE5zAW723KUJiW7sL1RcsbY0bHBj6G+9/H
+NplmsjuGt684vRBB0qOBfKF7EiG7mT69tHuNj4gRza9SMY31UtKbZdt2fNY6mp5V
+HscMba7egZP+Ke0pVX4+go9j7K8GG8hYaQDLjrzlPqrxZ2c5X9cC+CRDI/CHuL/s
+V/2yGZJ6n6UabwZoH83RdFrbQ94rU8Hkli6EvxXvMQKBgQDRpheNW5jDG5TfeJKh
+yfKTDQqH2Tk3BsBYYBN7Hf3m7vbkzlxnAKJAoSLmtRMuoeXvI5MrhzaHGsNIUS76
+LDIZnvB7DLUxhFUZsCPkpAA1QHuTWY96oR3PHnPjpk8lSUvtbOPwDLdzVApeFJgZ
+VqMNArZ7AHsK3Kkyi+f4WVQjbQKBgQDLAWiGb5dx6fAM2W6B6HjNmzjBWOuVEXa2
+76to9jzupBZmETfZgxtWUaWUDuNS+f7dtVUTE+p6v/w8clrHEhEZYkqunIOLo/UA
+LFPiuoTfEsWb1rh+nsCjCgy4uimixj/bSkf7NC6NyKTvCygA1mGnVVJUEPegYlDy
+LXCkaKWxHQKBgQCmyHSKL2lrJkEcOwakEU2acNCE3Gno/cT9SYmV83kvQ8JEqmrW
+QqnRsp9aXIljGscapPmKsmnNt5vNp1AxFAHTYh88NRLczsMIyZj0ZwgHVUI6KhC7
+5Psa78YQQBlMt2/g9TSsnuE+rYgF6mpKFiNm0Vasqeg47uzn2mdzqlUGTQKBgE04
+JutkTUY+h1pL5vYxWKpVDfy19z7H2tFxT1FowPrBneeLSyRI88Ac5I/yLdRlVeY9
+0LOmEr5Igwj3MsKgg7KVKfVLgdo/LrW3Jt2Kt3onKNXDkoBPoNUjwH0QC0Boiue+
+VK0gR0kVdm+bXccbxR+im+NwZNE0NLg6Qqu3RredAoGBALuVoqbPPmTCZXYG328H
+bzOs2aiR7BzPSVByV+qG6jW7w03RAnFPJZp7HMU+ViI5VY0wabUscMSvz5163+gM
+4KwY3v9ZjZzZGukIfLuudkdqtaiVOx/KeAC0n+nG21YU+wpZww8gkfHh1/sa2CME
+CWYCgOnmiTHcj83UaTqEXtmv
+-----END PRIVATE KEY-----
diff --git a/demo/complex0/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml b/demo/complex0/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
new file mode 100644
index 0000000..4fa67a7
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex0/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml b/demo/complex0/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
new file mode 100644
index 0000000..ee05a97
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
@@ -0,0 +1,139 @@
+<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"    
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    clockSkew="180">
+
+    <!--
+    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
+    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
+    -->
+
+    <!--
+    To customize behavior for specific resources on Apache, and to link vhosts or
+    resources to ApplicationOverride settings below, use web server options/commands.
+    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
+    
+    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
+    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
+    -->
+    <TCPListener address="127.0.0.1" port="1600"/> 
+
+
+    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
+    <ApplicationDefaults entityID="https://midpointdemo/shibboleth"
+                         REMOTE_USER="uid">
+
+        <!--
+        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
+        You MUST supply an effectively unique handlerURL value for each of your applications.
+        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
+        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
+        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
+        Note that while we default checkAddress to "false", this has a negative impact on the
+        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
+        -->
+        <Sessions lifetime="28800" timeout="28800" relayState="ss:mem"
+                  checkAddress="false" handlerSSL="true" cookieProps="https">
+
+            <!--
+            Configures SSO for a default IdP. To allow for >1 IdP, remove
+            entityID property and adjust discoveryURL to point to discovery service.
+            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
+            You can also override entityID on /Login query string, or in RequestMap/htaccess.
+            -->
+		<SSO entityID="https://idptestbed/idp/shibboleth">
+			SAML2
+		</SSO>
+
+            <!-- SAML and local-only logout. -->
+            <Logout>SAML2 Local</Logout>
+            
+            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
+            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
+
+            <!-- Status reporting service. -->
+            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
+
+            <!-- Session diagnostic service. -->
+            <Handler type="Session" Location="/Session" showAttributeValues="true"/>
+
+            <!-- JSON feed of discovery information. -->
+            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
+        </Sessions>
+
+        <!--
+        Allows overriding of error template information/filenames. You can
+        also add attributes with values that can be plugged into the templates.
+        -->
+        <Errors supportContact="root@localhost"
+            helpLocation="/about.html"
+            styleSheet="/shibboleth-sp/main.css"/>
+        
+        <!-- Example of remotely supplied batch of signed metadata. -->
+        <!--
+        <MetadataProvider type="XML" validate="true"
+	      uri="http://example.org/federation-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <MetadataProvider type="XML" validate="true" file="idp-metadata.xml"/>
+
+        <!--
+        InCommon
+	  <MetadataProvider type="XML" validate="true"
+		uri="http://md.incommon.org/InCommon/InCommon-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+		<MetdataFilter type="Signature" certificate="inc-md-cert.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <!-- Map to extract attributes from SAML assertions. -->
+        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
+        
+        <!-- Use a SAML query if no attributes are supplied during SSO. -->
+        <AttributeResolver type="Query" subjectMatch="true"/>
+
+        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
+        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
+
+        <!-- Simple file-based resolvers for separate signing/encryption keys. -->
+        <CredentialResolver type="File" use="signing"
+            key="sp-signing-key.pem" certificate="sp-signing-cert.pem"/>
+        <CredentialResolver type="File" use="encryption"
+            key="sp-encrypt-key.pem" certificate="sp-encrypt-cert.pem"/>
+
+        <!--
+        The default settings can be overridden by creating ApplicationOverride elements (see
+        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
+        Resource requests are mapped by web server commands, or the RequestMapper, to an
+        applicationId setting.
+        
+        Example of a second application (for a second vhost) that has a different entityID.
+        Resources on the vhost would map to an applicationId of "admin":
+        -->
+        <!--
+        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
+        -->
+    </ApplicationDefaults>
+    
+    <!-- Policies that determine how to process and authenticate runtime messages. -->
+    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
+
+    <!-- Low-level configuration about protocols and bindings available for use. -->
+    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
+
+</SPConfig>
diff --git a/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
new file mode 100644
index 0000000..7a66196
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAmWgAwIBAgIJAINng1bI63LGMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
+BAMTEnNwdGVzdC5leGFtcGxlLmVkdTAeFw0xODEyMjAyMjM4MDJaFw0yODEyMTcy
+MjM4MDJaMB0xGzAZBgNVBAMTEnNwdGVzdC5leGFtcGxlLmVkdTCCAaIwDQYJKoZI
+hvcNAQEBBQADggGPADCCAYoCggGBAOjmPSBzRsjbPBBA6jYVW+QtsYM5fvIuNErG
+VDRvKHyCTNbmdFZ37qEl/fwsrdF4hn4V7fAZ6jW6R1aMGFl1vQyJ289B8l5HOPjf
+GuB2gL9IxulOmrkYVN8nfgjlbFNNktMQJ8NprYEyl3o786xCCxx3AiA5Mgdv400L
+6vlmEfNHIwsOHAUTNRyCwMS9P6jBJ5IIxD0Mef+3oUjAvVsPZu24EJnzTUasZnI0
+F8aC/YzVbxObBNcymtA2Ipec/gLe1B09eDZUduXPL/as57QWvgJrWj8bCK+Ldj0P
+MPSvWzr4BnN58dxaYgCgRH7tnhZudPvCjBakQzkxo/njsRIKtm3lN9UmUYiXbl+e
+bu0DSQFUaFfO2hOOUTNAr/QuC+GQL+U7VAdybTbP+KcH5LbNUSqYkxSwhbFz5aym
+o5KppnYB9K5iySRWvGIhnwXHNv5yFrmUbet2BPJlMzv7NaePaZ76ypobzNjjNBbg
+aNECsQ1ZD9fe2Q8UBe0m2gQP5Yux5QIDAQABo0AwPjAdBgNVHREEFjAUghJzcHRl
+c3QuZXhhbXBsZS5lZHUwHQYDVR0OBBYEFGcLIl5kg+GFIh9HXeZyLzsv5e7qMA0G
+CSqGSIb3DQEBCwUAA4IBgQAf8/iZXUWtWGMBw2OfonDDWbuhgLnNWddpllcVx7v/
+Yu75+wgfIdNXg6XM4WkGkpbhlkpDLRt2c6rMQpxrQtq/5G3OKEXKyjUOl5pZsYkG
+asVENYPSCfuu3rlK85XaW3H1SSJqSax/UKcYXyB1TIW6mNy3OxuvHak6y4LzFnug
+CO7p/W2jvffwmxfqjbO7wQfXUQz3SZS04sHMqQoStOwy2N5xxQ3uTF34EoXBto+n
+XIEOptKPhV2NkEzj+UUIi1588dck8T0SstbSElbTnJ4sNZFriX6JOPFNW08fezot
+izerOHuAFpFQvtugWoZT87YYaFwG+Zr5QNa4fNOcAL+FHvbOfEqIGs+H6GSf0dZV
+lkcJyzWZvuK/4RGqWbLvfAYRm0PAGTQSLdO8QJSYWdJtJvZFEMgddQ2HoIzeO5wo
+B42FKDSHottI9avilApQBdRCtust8XRPtEAzDB/t/1jbO7u2tkzgY3614mX5xgut
+Ileaae5eVCjw4uYbkh+Mt5M=
+-----END CERTIFICATE-----
diff --git a/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
new file mode 100644
index 0000000..1622ef3
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDo5j0gc0bI2zwQ
+QOo2FVvkLbGDOX7yLjRKxlQ0byh8gkzW5nRWd+6hJf38LK3ReIZ+Fe3wGeo1ukdW
+jBhZdb0MidvPQfJeRzj43xrgdoC/SMbpTpq5GFTfJ34I5WxTTZLTECfDaa2BMpd6
+O/OsQgscdwIgOTIHb+NNC+r5ZhHzRyMLDhwFEzUcgsDEvT+owSeSCMQ9DHn/t6FI
+wL1bD2btuBCZ801GrGZyNBfGgv2M1W8TmwTXMprQNiKXnP4C3tQdPXg2VHblzy/2
+rOe0Fr4Ca1o/Gwivi3Y9DzD0r1s6+AZzefHcWmIAoER+7Z4WbnT7wowWpEM5MaP5
+47ESCrZt5TfVJlGIl25fnm7tA0kBVGhXztoTjlEzQK/0LgvhkC/lO1QHcm02z/in
+B+S2zVEqmJMUsIWxc+WspqOSqaZ2AfSuYskkVrxiIZ8Fxzb+cha5lG3rdgTyZTM7
++zWnj2me+sqaG8zY4zQW4GjRArENWQ/X3tkPFAXtJtoED+WLseUCAwEAAQKCAYBM
+3eCC20kbdbAnNSWX4AjKEIKr6sgJKlK78yVLgPx9y4uMydbPyxmJOj7PgfeEUSEi
+cB5txj/Up7xvxiErNX7FqqJPj1Zs41jcWtZGCxaHC4AK9JSATpWEaUZhrUbJX6r7
+2jMlfbV0FLyF7U+JJOsB5A1hkT7/0V/Vx/8vfQ6jmnDobym0SxiWZlk1Fbjy+30R
+567M71c8nOCwYFyet0CjaMKh7PkuQCw3uRW3wPfqCW91qw438E3ENnnITFpRnDUI
+iZIXJSj3Sqcx/W7Q6xei+y95U4tksT3/SQ7hVXp+BhfyjXdK/k0vNzxZfWk9nCD8
+h7HeiQuLPENzrlOwuWtI+gLDIdFplXUJ+/piK3okdstdHJcWcNUelW8yr7JSpv1I
+a2KMgHI2F4UVcTYLZrevzxd5a0cpvFW7vmvdw2vFrCb5JsVsmqBu5OLeaVGDIbIA
+2SLfJqq12fi2rxk28VtwXXgaCTttSM+8VY7dlT/mPCqX3Sx2eM7EPt6RVHuri4EC
+gcEA+3q6Vht60YXNaw7m4BFISntVm4Z2gGFNswLlrgPRHOacaQVMKhpqt3HmNKAT
+1MD/a5C60HkUjMB95m2nE4k1Iade8EzUPXD1FvFbE9/+ifNx2OrC8pKrEmRiTmCY
+oel45uoXsksNGJynfuRp2TpAVSZrXaIbGKZiMJZv0QZAilVBurZnZyV0jKQYkSFM
+FOt60PDJJEqZzG01dvDJxsIYQURtjNscO0R2ncloLXm7qu1/fcP7CAawWgFYyer2
+WEdVAoHBAO0WAhxCvFoev348Wf33lQi9c6w7WN/WEkhNOJ5p4PKsJphSZbt2bjCt
+RdRmvahSXeiGrDPuaxoWaQqcXprcu3ndFYBcK2xZpIl/mf0wr1QTEHCkRXzfxRjC
+Mmy+yTeKT4L18xKgg6pJn+wC3hwsv2BQPkp+NPJhD2bmVUWorqXq5fiBV2b7lTg0
+q1HHXYtxk22bw7xtstFENGTqa22KwD5Wd6nj9DamLzKhUhOdcJ7yGVu9se7YcGGh
+pg57muigUQKBwQD5feH96Zdo5UFN9GPTavH4ivH8sWNBrMeEUNyDTuAYtyX3/zx4
+DOtRAhwsm5/xFGSTV+wvReDAX3zIroLym85ti/phlyd9qWJOl7cPOcvzGuYZGZe9
+RwuX3KW3MphbEiFTnm1SAqmEgG6gMoZc8DDBCbO9GkWdp/yETcuzaWuAkmL6lVpy
+97LwkSCaY5lyq8iWIDy915FMQhCn5u2YVhnwLq4s73jLx/mSQy4q57nrM2Kn6FZV
+uSUetnVbJdOu810CgcBNCzbaWjF9E7rk2dXguwD6Wx5o3MxPyPAeAMIicIPCOIE+
+RKB8n8rFFLm5gT2mokWUF5eENLknPBsccJ4pswtVWavwD4Oo7SST7hxrc9O1/Y/9
+GtTd9JXHKuxZ/FHFM7QM+cHozrKattw6ROBKxZvXP5xOdt7b2QC5TqZtQZinoELl
+U5rEg4MFRdBafe//LYRcPR8Jb5iJeqGQHcGVUl6Qo2a1lbc5vx1dVaEncKU1cbUd
+4/IbjMhQYchlsnMvn1ECgcEAxwT/UvLwhYeFK6UHRwJ/z1eKGAC8R2B9tlmgddZx
+T93qbVq4lZXKw3osqdi+pgWvvmg9aK9r/dO1E93S11msnoTI+W9xTr+y5y9dN/hx
+5deQMUK+3woLog6LsGiKE2IamCNQBFkgd4VvhXgG+2pTPYJ9nyuEA+na+tfE6bSa
+foJ8KQT1rmRFQYRboBY/xxqtsl6Nh84JK7kCw27NNdhssyuiipfa8NLM4m+yeA6n
+/oz8xKl5PKwOrvk2DH+FwaAg
+-----END PRIVATE KEY-----
diff --git a/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
new file mode 100644
index 0000000..73aaaab
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAmWgAwIBAgIJAJZqOL69C6nRMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
+BAMTEnNwdGVzdC5leGFtcGxlLmVkdTAeFw0xODEyMjAyMjM4NDhaFw0yODEyMTcy
+MjM4NDhaMB0xGzAZBgNVBAMTEnNwdGVzdC5leGFtcGxlLmVkdTCCAaIwDQYJKoZI
+hvcNAQEBBQADggGPADCCAYoCggGBANJ1OC6Ql4te2/7PArBkuM/EF1NcQILv7bJa
+ecJDGYBVoWgL0a2KQ0XMESusgkVmVjj/jcbtvwIiXI/6BEu815OF6eSZIwxWdQBp
+eKbrWTbt07GiGgdXoXot6oMs5a9YXuWLt8pTXrFVMmwXU+ZfWJtuU8OIgm9esAEI
+QBHvDVOJtdKdBMWJFa5nUzkaVvA0Fr8r+/FHUvSCnlKOMaUIfTgtoS9AQnaRQ1dV
+l39Z2KAh87JYvRIxvbaPaKgar2eGQ+PQD8rqsB5K5wgnADAxYM9Vo0YXSpPH+Fvw
+N3EJgURUSEY2E0Jx8JOx368ERNLXx3kfnRxCiZRDkTZF9WP6lBnDwc1WXRwpVCDT
+RnF+SIh6IC1Bj/qpkpCD3nri7tycejoeAtVj1YZHWarf9iqdcLYOAWmeyGbFl3hj
+v6qcXnIfy1KyHLCAdIrg1TymLovXXKW09pEbVLdsHmLz0h+DxPs4FsinK2AQBMn1
+6u8BJJ/+spCzIQ2QNPcGORh6XemBpQIDAQABo0AwPjAdBgNVHREEFjAUghJzcHRl
+c3QuZXhhbXBsZS5lZHUwHQYDVR0OBBYEFPC8rkASWHQxrtCQ4wwtnsJRy6K5MA0G
+CSqGSIb3DQEBCwUAA4IBgQCks2nY7YzdIKV02NHD9STWD3yPtEwPYZZ3NBno0WW2
+0rS6cU+fxFx37nY8ULve4cFQkLR8fOO44e1qIuTgLGCauSGTx/Ts/tbmZXbpGTwV
+7cjZDCfC7yEFAVrfQFOMNKeQEssuLFj+d4STGLorxsM+2YygdOgohJz0e3xOcmCN
+HqEuC9RbzrnLc/A4/mOHKwnwCCg71zA1/Ew9NUoRm2n8IfaONIUaMg9opNiHxX4e
+u3UFaaPmn/mInuWYYMXzbIbdlU/XhKvXrujWYWj7anTDWvGQmNEecsQH92SrO0pf
++9WwcWUQTQiWUdq8/OxjXfzs1PrQnSlp0eizgcdKHDKbCUaSuK1i2wdxfEsu5sbZ
+AIW0+dXJ2IyzM+0sv2g4DOsXsnSvinGqjr82A54mXGSr7edhPdlQhILFkJfhTwLq
++mjnyQSNe3s24VNeGc76jbHIrkEWuA460QGqz1Fa2CsQo5SH1IkxNIKpBZWt+w2L
+dAza/NzYyDruY5IJCrZa9Qw=
+-----END CERTIFICATE-----
diff --git a/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
new file mode 100644
index 0000000..9e979fe
--- /dev/null
+++ b/demo/complex0/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDSdTgukJeLXtv+
+zwKwZLjPxBdTXECC7+2yWnnCQxmAVaFoC9GtikNFzBErrIJFZlY4/43G7b8CIlyP
++gRLvNeThenkmSMMVnUAaXim61k27dOxohoHV6F6LeqDLOWvWF7li7fKU16xVTJs
+F1PmX1ibblPDiIJvXrABCEAR7w1TibXSnQTFiRWuZ1M5GlbwNBa/K/vxR1L0gp5S
+jjGlCH04LaEvQEJ2kUNXVZd/WdigIfOyWL0SMb22j2ioGq9nhkPj0A/K6rAeSucI
+JwAwMWDPVaNGF0qTx/hb8DdxCYFEVEhGNhNCcfCTsd+vBETS18d5H50cQomUQ5E2
+RfVj+pQZw8HNVl0cKVQg00ZxfkiIeiAtQY/6qZKQg9564u7cnHo6HgLVY9WGR1mq
+3/YqnXC2DgFpnshmxZd4Y7+qnF5yH8tSshywgHSK4NU8pi6L11yltPaRG1S3bB5i
+89Ifg8T7OBbIpytgEATJ9ervASSf/rKQsyENkDT3BjkYel3pgaUCAwEAAQKCAYEA
+kmBxGQH8RTVO8eTtS95iJC+QwavyOp/BxUDkWtbsj7P/NSyzQ25c59jNQIEVgktx
+QOeNpoSJS2S22HTeNAc+MR781MAl/ljLu+OfxQj/3hKAIJZMYDr01tPEvkOl5NUj
++6e3xwNBYzmMfl2jPyGlsUWFAQSbI/bJl44zccXAkQ/A5KHNRc7Yw5qd6aOGQD8a
+axCehOxEqEeI8oZvxQcogMBL0V9yWqEiI0Ymvq6w2n+CzdKmflcWSjloYzNcODbL
+Ef2+8/fBZhHTS0GLCIqQpK+tZxt4K77DK2p2L9dYuHK7vtWn1j0YIwPqD+QVVtuT
+d7BOOmakPj2E7EXq/GvFw8gB/gRLoLuJSq5vvhPrSVuJqWdxDuxSutGgIoN3mQxd
+2AjuBXvqwYaZ3UGHZlBYAQx5ICiAGjxv/1zmKp+9OJHge/a1e6Z8jgQcpS7OWNhU
+dj6qfs+IiWKEaMM7D8dj4ncoArBpE7/BzlVuJ377cqRx35alMcKlawQWF1YqSDrB
+AoHBAPSipCLz4sr3U2jluXehntYsKevWcBtFkEd49Ay5uZTu/aweKWIozjDt7T3L
+mjYi+QGpt28MdNmpoofYOmpt+lrc0HWrv+UB9k/qFxfwgZKaXa1nm/VLfK77L4IB
+8I9dpjvDi724Xg/JJ1jsGM13+jGEfTQTl4Hi0lZwMydUO+O4oWB4kG9qhF8C+yQc
+12CCFH+Da8uwcwM+zCJwRm3qMKceifhEGAuFJ430Rp7cuqlJYfQZ4pVhRxwP6vns
+cLCz+QKBwQDcPB5bCjci/HMe0V19HxPrKh0hGPLIRCPAakT8Mz8N2lVAtWDXFL5q
+eHskl6cf8RQLfrcUiL+jQvD5VV8I7BkolCv0GZT/q36I/Z1QKlQC1O0IGG/hNqwt
+PS85YM6yC84YIKx0rN6O03/nYcslRv19q+MNiR9sZEeN6cScUc6aUINhWjzQ4mb8
+Z9ErguJrq0sCoAVU+t/yRo/YB/d2xdN9XLe+2cgsM6s0TiHo4v2SeFHKewBw+RLp
+yrShY6COzg0CgcEA0EFwt2ylgiGgeSkvhV8qJ6s7GNDZaO4EUEPwhrDJAredbhvT
+IQQZ29+AWl3sbu/AySCgzsFs7CsT+M8jk50CRr26HKJUXvEXrZpbhH6y34nX+5m7
+U8uqXg/ptqROFM4liLUETkMYmBmnDHUY/DmJ3QOrzlxrWyAr7XfgpDd6MHbpsoWQ
+d7jW7UdNYsXGuBqktpS7fJA+qOGZyCuKWWHHf01pKNdXHN+C976fK/g+U4TsBXDP
+ylkgvwvx/kbA/DyJAoHAQxXA/WRYNT0G6B1ISAO+coTKiLlrwtsWtNbqGpSVoWef
+Tm2xiPKVqiL3B8d2LgGmZHX92LBrB5UtiBWcNECOzVCNLvbX7yVTDvGKCNBL9Ozd
+Ivkmo0ifG8ymZOj7LTrxVWImhgfeZ00/icC9O6arMqu4Jvhc7QyCy1SpAiDdOR5L
+Vs1A9zPvwPTyvzlINRnhaHRMC32717XsvRZ4J+LMsEQc6HK4SdaXUQB3zdPO/93M
+tEvRb5g/TZ3kdcC+OKHFAoHAO9R3y6ZjUM8T8/4XcyRD968V4sZIvVQfpSaH86GO
+TrECZp5SqSWUTqAWTJWS0yIctAML60nWF+OPRUlrq0yk2veN9Re6eWfyoyQOFd92
+U+bxh3QEue5LGOwpqrPV/1cJSFdv88eS+F8q7i/dD765Tio6kJjKzXPN3FJqAvNB
+lAnaO4Apbuzob25Qkmm0NVQHap+TJGJMvX2vVX9CjE6haVWq1lJMakkoQOeIlyi5
+iDjt9rDlIwDYeGWk4KFgsKM7
+-----END PRIVATE KEY-----
diff --git a/demo/complex0/directory/Dockerfile b/demo/complex0/directory/Dockerfile
new file mode 100644
index 0000000..06df07b
--- /dev/null
+++ b/demo/complex0/directory/Dockerfile
@@ -0,0 +1,28 @@
+FROM centos:centos7
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+RUN yum install -y epel-release \
+    && yum update -y \
+    && yum install -y 389-ds-base \
+    && yum clean all \
+    && rm -rf /var/cache/yum
+
+COPY container_files/seed-data/ /seed-data/
+
+RUN useradd ldapadmin \
+    && rm -fr /var/lock /usr/lib/systemd/system \
+    # The 389-ds setup will fail because the hostname can't reliable be determined, so we'll bypass it and then install. \
+    && sed -i 's/checkHostname {/checkHostname {\nreturn();/g' /usr/lib64/dirsrv/perl/DSUtil.pm \
+    # Not doing SELinux \
+    && sed -i 's/updateSelinuxPolicy($inf);//g' /usr/lib64/dirsrv/perl/* \
+    # Do not restart at the end \
+    && sed -i '/if (@errs = startServer($inf))/,/}/d' /usr/lib64/dirsrv/perl/* \
+    && setup-ds.pl --silent --file /seed-data/ds-setup.inf \
+    && /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir \
+    && while ! curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to start; sleep 1; done; \
+    ldapadd -H ldap:/// -f /seed-data/users.ldif -x -D "cn=Directory Manager" -w password
+
+EXPOSE 389
+
+CMD rm -rf /var/lock/dirsrv/slapd-dir/server/* && /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir && sleep infinity
diff --git a/demo/complex0/directory/container_files/seed-data/ds-setup.inf b/demo/complex0/directory/container_files/seed-data/ds-setup.inf
new file mode 100644
index 0000000..96c29a1
--- /dev/null
+++ b/demo/complex0/directory/container_files/seed-data/ds-setup.inf
@@ -0,0 +1,28 @@
+[General]
+AdminDomain = internet2.edu
+ConfigDirectoryAdminID = admin
+ConfigDirectoryAdminPwd = admin
+ConfigDirectoryLdapURL = ldap://localhost:389/o=NetscapeRoot
+FullMachineName = localhost
+ServerRoot = /usr/lib64/dirsrv
+SuiteSpotGroup = nobody
+SuiteSpotUserID = nobody
+
+[admin]
+Port = 9830
+ServerAdminID = admin
+ServerAdminPwd = admin
+ServerIpAddress = 0.0.0.0
+SysUser = nobody
+
+[slapd]
+AddOrgEntries = No
+AddSampleEntries = No
+InstallLdifFile = suggest
+RootDN = cn=Directory Manager
+RootDNPwd = password
+ServerIdentifier = dir
+ServerPort = 389
+SlapdConfigForMC = yes
+Suffix = dc=internet2,dc=edu
+UseExistingMC = No
diff --git a/demo/complex0/directory/container_files/seed-data/users.ldif b/demo/complex0/directory/container_files/seed-data/users.ldif
new file mode 100644
index 0000000..383b1b7
--- /dev/null
+++ b/demo/complex0/directory/container_files/seed-data/users.ldif
@@ -0,0 +1,35 @@
+dn: cn=admin,dc=internet2,dc=edu
+objectClass: simpleSecurityObject
+objectClass: organizationalRole
+cn: admin
+userPassword: password
+description: LDAP administrator
+
+dn: cn=users,ou=Groups,dc=internet2,dc=edu
+objectClass: groupOfUniqueNames
+objectClass: top
+uniqueMember: uid=banderson,ou=People,dc=internet2,dc=edu
+uniqueMember: uid=jsmith,ou=People,dc=internet2,dc=edu
+cn: users
+
+dn: ou=Affiliations,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Affiliations
+
+dn: ou=Courses,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Courses
+
+dn: ou=midpoint,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: midpoint
+
+dn: ou=Generic,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Generic
+
+
diff --git a/demo/complex0/docker-compose.yml b/demo/complex0/docker-compose.yml
new file mode 100644
index 0000000..7b30628
--- /dev/null
+++ b/demo/complex0/docker-compose.yml
@@ -0,0 +1,142 @@
+version: "3.3"
+
+services:
+  directory:
+    build: ./directory/
+    ports:
+     - 389:389
+    networks:
+     - net
+    volumes:
+     - ldap:/var/lib/dirsrv
+
+  sources:
+    build: ./sources/
+    ports:
+     - 13306:3306
+    networks:
+     - net
+    volumes:
+     - source_mysql:/var/lib/mysql
+     - source_data:/var/lib/mysqlmounted
+    environment:
+     - CREATE_NEW_DATABASE=if_needed
+
+#  targets:
+#    build: ./targets/
+#    ports:
+#     - 23306:389
+#    networks:
+#     - net
+#    volumes:
+#     - target_data:/var/lib/mysql
+
+  midpoint_data:
+    image: tier/mariadb:mariadb10
+    ports:
+     - 33306:3306
+    networks:
+      net:
+        aliases:
+         - midpoint-data
+    volumes:
+     - midpoint_mysql:/var/lib/mysql
+     - midpoint_data:/var/lib/mysqlmounted
+    environment:
+     - CREATE_NEW_DATABASE=if_needed
+
+  midpoint_server:
+    build: ./midpoint_server/
+    depends_on:
+     - midpoint_data
+    ports:
+     - 8443:443
+    environment:
+     - AUTHENTICATION
+     - ENV
+     - USERTOKEN
+     - REPO_DATABASE_TYPE
+     - REPO_JDBC_URL
+     - REPO_HOST
+     - REPO_PORT
+     - REPO_DATABASE
+     - REPO_USER
+     - REPO_MISSING_SCHEMA_ACTION
+     - REPO_UPGRADEABLE_SCHEMA_ACTION
+     - REPO_SCHEMA_VERSION_IF_MISSING
+     - REPO_SCHEMA_VARIANT
+     - MP_MEM_MAX
+     - MP_MEM_INIT
+     - MP_JAVA_OPTS
+     - SSO_HEADER
+     - TIER_BEACON_OPT_OUT
+     - TIMEZONE
+    networks:
+      net:
+        aliases:
+         - midpoint-server
+    secrets:
+     - mp_database_password.txt
+     - mp_keystore_password.txt
+     - mp_sp-encrypt-key.pem
+     - mp_sp-signing-key.pem
+     - mp_host-key.pem
+    volumes:
+     - midpoint_home:/opt/midpoint/var
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
+       target: /etc/shibboleth/shibboleth2.xml
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
+       target: /etc/shibboleth/idp-metadata.xml
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
+       target: /etc/shibboleth/sp-signing-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
+       target: /etc/shibboleth/sp-encrypt-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  idp:
+    build: ./idp/
+    depends_on:
+     - directory
+    environment:
+     - JETTY_MAX_HEAP=64m
+     - JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=password
+     - JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=password
+    networks:
+     - net
+    ports:
+     - 443:443
+
+networks:
+  net:    
+    driver: bridge
+
+secrets:
+# midPoint
+  mp_host-key.pem:
+    file: ./configs-and-secrets/midpoint/httpd/host-key.pem
+  mp_sp-signing-key.pem:
+    file: ./configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
+  mp_sp-encrypt-key.pem:
+    file: ./configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
+  mp_database_password.txt:
+    file: ./configs-and-secrets/midpoint/application/database_password.txt
+  mp_keystore_password.txt:
+    file: ./configs-and-secrets/midpoint/application/keystore_password.txt    
+    
+volumes:
+  source_data:
+  source_mysql:
+  target_data:
+  ldap:
+  midpoint_data:
+  midpoint_mysql:
+  midpoint_home:
diff --git a/demo/complex0/get-import-sis-persons-status.sh b/demo/complex0/get-import-sis-persons-status.sh
new file mode 100755
index 0000000..26d3fcd
--- /dev/null
+++ b/demo/complex0/get-import-sis-persons-status.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+get_task_execution_status "Import from SIS persons"
diff --git a/demo/complex0/idp/Dockerfile b/demo/complex0/idp/Dockerfile
new file mode 100644
index 0000000..0f6f508
--- /dev/null
+++ b/demo/complex0/idp/Dockerfile
@@ -0,0 +1,5 @@
+FROM tier/shib-idp
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+COPY shibboleth-idp/ /opt/shibboleth-idp/
diff --git a/demo/complex0/idp/shibboleth-idp/conf/attribute-filter.xml b/demo/complex0/idp/shibboleth-idp/conf/attribute-filter.xml
new file mode 100644
index 0000000..21ffdb8
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/conf/attribute-filter.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    This file is an EXAMPLE policy file.  While the policy presented in this 
+    example file is illustrative of some simple cases, it relies on the names of
+    non-existent example services and the example attributes demonstrated in the
+    default attribute-resolver.xml file.
+    
+    Deployers should refer to the documentation for a complete list of components
+    and their options.
+-->
+<afp:AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
+        xmlns:afp="urn:mace:shibboleth:2.0:afp"
+        xmlns:basic="urn:mace:shibboleth:2.0:afp:mf:basic"
+        xmlns:saml="urn:mace:shibboleth:2.0:afp:mf:saml"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd
+                            urn:mace:shibboleth:2.0:afp:mf:basic http://shibboleth.net/schema/idp/shibboleth-afp-mf-basic.xsd
+                            urn:mace:shibboleth:2.0:afp:mf:saml http://shibboleth.net/schema/idp/shibboleth-afp-mf-saml.xsd">
+
+    <!-- Release some attributes to an SP. -->
+    <afp:AttributeFilterPolicy id="example1">
+        <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://grouperdemo/shibboleth" />
+
+        <afp:AttributeRule attributeID="eduPersonPrincipalName">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+        <afp:AttributeRule attributeID="uid">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+        <afp:AttributeRule attributeID="mail">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+    </afp:AttributeFilterPolicy>
+
+    <afp:AttributeFilterPolicy id="midpoint">
+        <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://midpointdemo/shibboleth" />
+
+        <afp:AttributeRule attributeID="uid">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+    </afp:AttributeFilterPolicy>
+
+</afp:AttributeFilterPolicyGroup>
diff --git a/demo/complex0/idp/shibboleth-idp/conf/attribute-resolver.xml b/demo/complex0/idp/shibboleth-idp/conf/attribute-resolver.xml
new file mode 100644
index 0000000..ee9519f
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/conf/attribute-resolver.xml
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    This file is an EXAMPLE configuration file containing lots of commented
+    example attributes, encoders, and a couple of example data connectors.
+    
+    Not all attribute definitions or data connectors are demonstrated, but
+    a variety of LDAP attributes, some common to Shibboleth deployments and
+    many not, are included.
+    
+    Deployers should refer to the Shibboleth 2 documentation for a complete
+    list of components  and their options.
+-->
+<resolver:AttributeResolver
+        xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
+        xmlns:pc="urn:mace:shibboleth:2.0:resolver:pc"
+        xmlns:ad="urn:mace:shibboleth:2.0:resolver:ad"
+        xmlns:dc="urn:mace:shibboleth:2.0:resolver:dc"
+        xmlns:enc="urn:mace:shibboleth:2.0:attribute:encoder"
+        xmlns:sec="urn:mace:shibboleth:2.0:security"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd
+                            urn:mace:shibboleth:2.0:resolver:pc http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-pc.xsd
+                            urn:mace:shibboleth:2.0:resolver:ad http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-ad.xsd
+                            urn:mace:shibboleth:2.0:resolver:dc http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-dc.xsd
+                            urn:mace:shibboleth:2.0:attribute:encoder http://shibboleth.net/schema/idp/shibboleth-attribute-encoder.xsd
+                            urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+
+    <!-- ========================================== -->
+    <!--      Attribute Definitions                 -->
+    <!-- ========================================== -->
+
+    <!-- Schema: Core schema attributes-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="uid" sourceAttributeID="uid">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:uid" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.1" friendlyName="uid" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="mail" sourceAttributeID="mail">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mail" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="homePhone" sourceAttributeID="homePhone">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:homePhone" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.20" friendlyName="homePhone" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="homePostalAddress" sourceAttributeID="homePostalAddress">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:homePostalAddress" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.39" friendlyName="homePostalAddress" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="mobileNumber" sourceAttributeID="mobile">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mobile" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.41" friendlyName="mobile" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="pagerNumber" sourceAttributeID="pager">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:pager" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.42" friendlyName="pager" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="surname" sourceAttributeID="sn">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:sn" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.4" friendlyName="sn" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="locality" sourceAttributeID="l">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:l" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.7" friendlyName="l" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="stateProvince" sourceAttributeID="st">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:st" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.8" friendlyName="st" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="street" sourceAttributeID="street">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:street" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.9" friendlyName="street" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="organizationName" sourceAttributeID="o">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:o" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.10" friendlyName="o" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="organizationalUnit" sourceAttributeID="ou">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:ou" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.11" friendlyName="ou" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="title" sourceAttributeID="title">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:title" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.12" friendlyName="title" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postalAddress" sourceAttributeID="postalAddress">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postalAddress" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.16" friendlyName="postalAddress" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postalCode" sourceAttributeID="postalCode">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postalCode" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.17" friendlyName="postalCode" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postOfficeBox" sourceAttributeID="postOfficeBox">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postOfficeBox" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.18" friendlyName="postOfficeBox" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="telephoneNumber" sourceAttributeID="telephoneNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:telephoneNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.20" friendlyName="telephoneNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="givenName" sourceAttributeID="givenName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:givenName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.42" friendlyName="givenName" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="initials" sourceAttributeID="initials">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:initials" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.43" friendlyName="initials" encodeType="false" />
+    </resolver:AttributeDefinition>
+     -->
+
+    <!-- Schema: inetOrgPerson attributes-->
+    <!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="departmentNumber" sourceAttributeID="departmentNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:departmentNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.2" friendlyName="departmentNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="displayName" sourceAttributeID="displayName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:displayName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.241" friendlyName="displayName" encodeType="false" />
+    </resolver:AttributeDefinition> 
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="employeeNumber" sourceAttributeID="employeeNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.3" friendlyName="employeeNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="employeeType" sourceAttributeID="employeeType">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeType" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.4" friendlyName="employeeType" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="jpegPhoto" sourceAttributeID="jpegPhoto">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:jpegPhoto" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.60" friendlyName="jpegPhoto" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="preferredLanguage" sourceAttributeID="preferredLanguage">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:preferredLanguage" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.39" friendlyName="preferredLanguage" encodeType="false" />
+    </resolver:AttributeDefinition>
+    -->
+
+    <!-- Schema: eduPerson attributes -->
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAffiliation" sourceAttributeID="cn">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonEntitlement" sourceAttributeID="eduPersonEntitlement">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonEntitlement" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" friendlyName="eduPersonEntitlement" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonNickname" sourceAttributeID="eduPersonNickname">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonNickname" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.2" friendlyName="eduPersonNickname" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonPrimaryAffiliation" sourceAttributeID="eduPersonPrimaryAffiliation">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.5" friendlyName="eduPersonPrimaryAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonUniqueId" scope="%{idp.scope}" sourceAttributeID="localUniqueId">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" friendlyName="eduPersonUniqueId" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonPrincipalName" scope="%{idp.scope}" sourceAttributeID="eduPersonPrincipalName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonPrincipalName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Prescoped" id="eduPersonPrincipalNamePrior" sourceAttributeID="eduPersonPrincipalNamePrior">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.12" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.12" friendlyName="eduPersonPrincipalNamePrior" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonScopedAffiliation" scope="%{idp.scope}" sourceAttributeID="eduPersonAffiliation">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" friendlyName="eduPersonScopedAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAssurance" sourceAttributeID="eduPersonAssurance">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAssurance" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" friendlyName="eduPersonAssurance" encodeType="false" />
+    </resolver:AttributeDefinition>
+    -->
+
+    <!-- ========================================== -->
+    <!--      Data Connectors                       -->
+    <!-- ========================================== -->
+
+    <!-- Example Static Connector -->
+    <!--
+    <resolver:DataConnector id="staticAttributes" xsi:type="dc:Static">
+        <dc:Attribute id="eduPersonAffiliation">
+            <dc:Value>member</dc:Value>
+        </dc:Attribute>
+    </resolver:DataConnector>
+    -->
+
+    <!-- Example Relational Database Connector -->
+    <!--
+    <resolver:DataConnector id="mySIS" xsi:type="dc:RelationalDatabase">
+        <dc:ApplicationManagedConnection jdbcDriver="oracle.jdbc.driver.OracleDriver"
+                                         jdbcURL="jdbc:oracle:thin:@db.example.org:1521:SomeDB" 
+                                         jdbcUserName="myid" 
+                                         jdbcPassword="mypassword" />
+        <dc:QueryTemplate>
+            <![CDATA[
+                SELECT * FROM student WHERE gzbtpid = '$requestContext.principalName'
+            ]]>
+        </dc:QueryTemplate>
+
+        <dc:Column columnName="gzbtpid" attributeID="uid" />
+        <dc:Column columnName="fqlft" attributeID="gpa" />
+    </resolver:DataConnector>
+     -->
+
+    <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
+        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
+        baseDN="%{idp.attribute.resolver.LDAP.baseDN}" 
+        principal="%{idp.attribute.resolver.LDAP.bindDN}"
+        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
+        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}">
+        <dc:FilterTemplate>
+            <![CDATA[
+                %{idp.attribute.resolver.LDAP.searchFilter}
+            ]]>
+        </dc:FilterTemplate>
+        <!--
+        <dc:StartTLSTrustCredential id="LDAPtoIdPCredential" xsi:type="sec:X509ResourceBacked">
+            <sec:Certificate>%{idp.attribute.resolver.LDAP.trustCertificates}</sec:Certificate>
+        </dc:StartTLSTrustCredential>
+    -->
+    </resolver:DataConnector>
+
+</resolver:AttributeResolver>
\ No newline at end of file
diff --git a/demo/complex0/idp/shibboleth-idp/conf/idp.properties b/demo/complex0/idp/shibboleth-idp/conf/idp.properties
new file mode 100644
index 0000000..4396f49
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/conf/idp.properties
@@ -0,0 +1,195 @@
+# Load any additional property resources from a comma-delimited list
+idp.additionalProperties= /conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties
+
+# Set the entityID of the IdP
+idp.entityID= https://idptestbed/idp/shibboleth
+
+# Set the scope used in the attribute resolver for scoped attributes
+idp.scope= example.org
+
+# General cookie properties (maxAge only applies to persistent cookies)
+#idp.cookie.secure = false
+#idp.cookie.httpOnly = true
+#idp.cookie.domain =
+#idp.cookie.path =
+#idp.cookie.maxAge = 31536000
+
+# Set the location of user-supplied web flow definitions
+#idp.webflows = %{idp.home}/flows
+
+# Set the location of Velocity view templates
+#idp.views = %{idp.home}/views
+
+# Settings for internal AES encryption key
+#idp.sealer.storeType = JCEKS
+#idp.sealer.updateInterval = PT15M
+#idp.sealer.aliasBase = secret
+idp.sealer.storeResource= %{idp.home}/credentials/sealer.jks
+idp.sealer.versionResource= %{idp.home}/credentials/sealer.kver
+idp.sealer.storePassword= password
+idp.sealer.keyPassword= password
+
+# Settings for public/private signing and encryption key(s)
+# During decryption key rollover, point the ".2" properties at a second
+# keypair, uncomment in credentials.xml, then publish it in your metadata.
+idp.signing.key= %{idp.home}/credentials/idp-signing.key
+idp.signing.cert= %{idp.home}/credentials/idp-signing.crt
+idp.encryption.key= %{idp.home}/credentials/idp-encryption.key
+idp.encryption.cert= %{idp.home}/credentials/idp-encryption.crt
+#idp.encryption.key.2 = %{idp.home}/credentials/idp-encryption-old.key
+#idp.encryption.cert.2 = %{idp.home}/credentials/idp-encryption-old.crt
+
+# Sets the bean ID to use as a default security configuration set
+#idp.security.config = shibboleth.DefaultSecurityConfiguration
+
+# To default to SHA-1, set to shibboleth.SigningConfiguration.SHA1
+#idp.signing.config = shibboleth.SigningConfiguration.SHA256
+
+# Configures trust evaluation of keys used by services at runtime
+# Defaults to supporting both explicit key and PKIX using SAML metadata.
+#idp.trust.signatures = shibboleth.ChainingSignatureTrustEngine
+# To pick only one set to one of:
+#   shibboleth.ExplicitKeySignatureTrustEngine, shibboleth.PKIXSignatureTrustEngine
+#idp.trust.certificates = shibboleth.ChainingX509TrustEngine
+# To pick only one set to one of:
+#   shibboleth.ExplicitKeyX509TrustEngine, shibboleth.PKIXX509TrustEngine
+
+# If true, encryption will happen whenever a key to use can be located, but
+# failure to encrypt won't result in request failure.
+#idp.encryption.optional = false
+
+# Configuration of client- and server-side storage plugins
+#idp.storage.cleanupInterval = PT10M
+#idp.storage.htmlLocalStorage = false
+
+# Set to true to expose more detailed errors in responses to SPs
+#idp.errors.detailed = false
+# Set to false to skip signing of SAML response messages that signal errors
+#idp.errors.signed = true
+# Name of bean containing a list of Java exception classes to ignore
+#idp.errors.excludedExceptions = ExceptionClassListBean
+# Name of bean containing a property set mapping exception names to views
+#idp.errors.exceptionMappings = ExceptionToViewPropertyBean
+# Set if a different default view name for events and exceptions is needed
+#idp.errors.defaultView = error
+
+# Set to false to disable the IdP session layer
+#idp.session.enabled = true
+
+# Set to "shibboleth.StorageService" for server-side storage of user sessions
+#idp.session.StorageService = shibboleth.ClientSessionStorageService
+idp.session.StorageService = shibboleth.StorageService
+
+# Size of session IDs
+#idp.session.idSize = 32
+# Bind sessions to IP addresses
+#idp.session.consistentAddress = true
+# Inactivity timeout
+#idp.session.timeout = PT60M
+# Extra time to store sessions for logout
+#idp.session.slop = PT0S
+# Tolerate storage-related errors
+#idp.session.maskStorageFailure = false
+# Track information about SPs logged into
+#idp.session.trackSPSessions = false
+# Support lookup by SP for SAML logout
+#idp.session.secondaryServiceIndex = false
+# Length of time to track SP sessions
+#idp.session.defaultSPlifetime = PT2H
+
+# Regular expression matching login flows to enable, e.g. IPAddress|Password
+idp.authn.flows= Password
+
+# Regular expression of forced "initial" methods when no session exists,
+# usually in conjunction with the idp.authn.resolveAttribute property below.
+#idp.authn.flows.initial = Password
+
+# Set to an attribute ID to resolve prior to selecting authentication flows;
+# its values are used to filter the flows to allow.
+#idp.authn.resolveAttribute = eduPersonAssurance
+
+# Default lifetime and timeout of various authentication methods
+#idp.authn.defaultLifetime = PT60M
+#idp.authn.defaultTimeout = PT30M
+
+# Whether to prioritize "active" results when an SP requests more than
+# one possible matching login method (V2 behavior was to favor them)
+#idp.authn.favorSSO = true
+
+# Whether to fail requests when a user identity after authentication
+# doesn't match the identity in a pre-existing session.
+#idp.authn.identitySwitchIsError = false
+
+# Set to "shibboleth.StorageService" or custom bean for alternate storage of consent
+#idp.consent.StorageService = shibboleth.ClientPersistentStorageService
+
+# Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute
+# to key user consent storage records (and set the attribute name)
+#idp.consent.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
+#idp.consent.userStorageKeyAttribute = uid
+
+# Flags controlling how built-in attribute consent feature operates
+#idp.consent.allowDoNotRemember = true
+#idp.consent.allowGlobal = true
+#idp.consent.allowPerAttribute = false
+
+# Whether attribute values and terms of use text are compared
+#idp.consent.compareValues = false
+# Maximum number of consent records for space-limited storage (e.g. cookies)
+#idp.consent.maxStoredRecords = 10
+# Maximum number of consent records for larger/server-side storage (0 = no limit)
+#idp.consent.expandedMaxStoredRecords = 0
+
+# Time in milliseconds to expire consent storage records.
+#idp.consent.storageRecordLifetime = P1Y
+
+# Whether to lookup metadata, etc. for every SP involved in a logout
+# for use by user interface logic; adds overhead so off by default.
+#idp.logout.elaboration = false
+
+# Whether to require logout requests be signed/authenticated.
+#idp.logout.authenticated = true
+
+# Message freshness and replay cache tuning
+#idp.policy.messageLifetime = PT3M
+#idp.policy.clockSkew = PT3M
+
+# Set to custom bean for alternate storage of replay cache
+#idp.replayCache.StorageService = shibboleth.StorageService
+
+# Toggles whether to allow outbound messages via SAML artifact
+#idp.artifact.enabled = true
+# Suppresses typical signing/encryption when artifact binding used
+#idp.artifact.secureChannel = true
+# May differ to direct SAML 2 artifact lookups to specific server nodes
+#idp.artifact.endpointIndex = 2
+# Set to custom bean for alternate storage of artifact map state
+#idp.artifact.StorageService = shibboleth.StorageService
+
+# Name of access control policy for various admin flows
+idp.status.accessPolicy= AccessByIPAddress
+idp.resolvertest.accessPolicy= AccessByIPAddress
+idp.reload.accessPolicy= AccessByIPAddress
+
+# Comma-delimited languages to use if not match can be found with the
+# browser-supported languages, defaults to an empty list.
+idp.ui.fallbackLanguages= en,fr,de
+
+# Storage service used by CAS protocol
+# Defaults to shibboleth.StorageService (in-memory)
+# MUST be server-side storage (e.g. in-memory, memcached, database)
+# NOTE that idp.session.StorageService requires server-side storage
+# when CAS protocol is enabled
+idp.cas.StorageService=shibboleth.StorageService
+
+# CAS service registry implementation class
+#idp.cas.serviceRegistryClass=net.shibboleth.idp.cas.service.PatternServiceRegistry
+
+# Profile flows in which the ProfileRequestContext should be exposed
+# in servlet request under the key "opensamlProfileRequestContext"
+#idp.profile.exposeProfileRequestContextInServletRequest = SAML2/POST/SSO,SAML2/Redirect/SSO
+
+# F-TICKS auditing - set salt to include hashed username
+#idp.fticks.federation=MyFederation
+#idp.fticks.algorithm=SHA-256
+#idp.fticks.salt=somethingsecret
diff --git a/demo/complex0/idp/shibboleth-idp/conf/ldap.properties b/demo/complex0/idp/shibboleth-idp/conf/ldap.properties
new file mode 100644
index 0000000..726f145
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/conf/ldap.properties
@@ -0,0 +1,58 @@
+# LDAP authentication configuration, see authn/ldap-authn-config.xml
+
+## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator
+#idp.authn.LDAP.authenticator                   = anonSearchAuthenticator
+
+## Connection properties ##
+idp.authn.LDAP.ldapURL                          = ldap://directory:389
+idp.authn.LDAP.useStartTLS                     = false
+idp.authn.LDAP.useSSL                          = false
+#idp.authn.LDAP.connectTimeout                  = 3000
+
+## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust
+#idp.authn.LDAP.sslConfig                       = certificateTrust
+## If using certificateTrust above, set to the trusted certificate's path
+idp.authn.LDAP.trustCertificates                = %{idp.home}/credentials/ldap-server.crt
+## If using keyStoreTrust above, set to the truststore path
+idp.authn.LDAP.trustStore                       = %{idp.home}/credentials/ldap-server.truststore
+
+## Return attributes during authentication
+## NOTE: this is not used during attribute resolution; configure that directly in the
+## attribute-resolver.xml configuration via a DataConnector's <dc:ReturnAttributes> element
+idp.authn.LDAP.returnAttributes                 = cn,businessCategory,mail
+
+## DN resolution properties ##
+
+# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator
+# for AD: CN=Users,DC=example,DC=org
+idp.authn.LDAP.baseDN                           = ou=people,dc=internet2,dc=edu
+#idp.authn.LDAP.subtreeSearch                   = false
+idp.authn.LDAP.userFilter                       = (uid={user})
+# bind search configuration
+# for AD: idp.authn.LDAP.bindDN=adminuser@domain.com
+idp.authn.LDAP.bindDN                           = cn=admin,dc=internet2,dc=edu
+idp.authn.LDAP.bindDNCredential                 = password
+
+# Format DN resolution, used by directAuthenticator, adAuthenticator
+# for AD use idp.authn.LDAP.dnFormat=%s@domain.com
+idp.authn.LDAP.dnFormat                         = uid=%s,ou=people,dc=internet2,dc=edu
+
+# LDAP attribute configuration, see attribute-resolver.xml
+idp.attribute.resolver.LDAP.ldapURL             = %{idp.authn.LDAP.ldapURL}
+idp.attribute.resolver.LDAP.baseDN              = %{idp.authn.LDAP.baseDN}
+idp.attribute.resolver.LDAP.bindDN              = %{idp.authn.LDAP.bindDN}
+idp.attribute.resolver.LDAP.bindDNCredential    = %{idp.authn.LDAP.bindDNCredential}
+idp.attribute.resolver.LDAP.useStartTLS         = %{idp.authn.LDAP.useStartTLS:true}
+idp.attribute.resolver.LDAP.trustCertificates   = %{idp.authn.LDAP.trustCertificates}
+idp.attribute.resolver.LDAP.searchFilter        = (uid=$requestContext.principalName)
+
+# LDAP pool configuration, used for both authn and DN resolution
+#idp.pool.LDAP.minSize                          = 3
+#idp.pool.LDAP.maxSize                          = 10
+#idp.pool.LDAP.validateOnCheckout               = false
+#idp.pool.LDAP.validatePeriodically             = true
+#idp.pool.LDAP.validatePeriod                   = 300
+#idp.pool.LDAP.prunePeriod                      = 300
+#idp.pool.LDAP.idleTime                         = 600
+#idp.pool.LDAP.blockWaitTime                    = 3000
+#idp.pool.LDAP.failFastInitialize               = false
diff --git a/demo/complex0/idp/shibboleth-idp/conf/metadata-providers.xml b/demo/complex0/idp/shibboleth-idp/conf/metadata-providers.xml
new file mode 100644
index 0000000..f70135e
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/conf/metadata-providers.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This file is an EXAMPLE metadata configuration file. -->
+<MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider"
+    xmlns="urn:mace:shibboleth:2.0:metadata"
+    xmlns:resource="urn:mace:shibboleth:2.0:resource"
+    xmlns:security="urn:mace:shibboleth:2.0:security"
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd
+                        urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd 
+                        urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd
+                        urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd">
+                        
+    <!-- ========================================================================================== -->
+    <!--                             Metadata Configuration                                         -->
+    <!--                                                                                            -->
+    <!--  Below you place the mechanisms which define how to load the metadata for the SP you will  -->
+    <!--  provide a service to.                                                                     -->
+    <!--                                                                                            -->
+    <!--  Two examples are provided.  The Shibboleth Documentation at                               -->
+    <!--  https://wiki.shibboleth.net/confluence/display/IDP30/MetadataConfiguration                -->
+    <!--  provides more details.                                                                    --> 
+    <!--                                                                                            -->
+    <!--  NOTE.  This file SHOULD NOT contain the metadata for this IdP.                            -->
+    <!--                                                                                            -->
+    <!-- ========================================================================================== -->
+
+    <MetadataProvider id="GrouperSP"  xsi:type="FilesystemMetadataProvider" metadataFile="%{idp.home}/metadata/grouper-sp.xml"/>
+    <MetadataProvider id="MidpointSP"  xsi:type="FilesystemMetadataProvider" metadataFile="%{idp.home}/metadata/midpoint-sp.xml"/>
+
+    <!-- Example HTTP metadata provider.  Use this if you want to download
+         the metadata from a remote service.
+         
+         You *MUST*  provider the SignatureValidationFilter in order to function securely.
+         Get the PubLic key, and validate it via some out of band mechanism, from the
+         party publishing the metadata
+         
+         The EntityRoleWhiteList saves memory by only loading metadata from entity types
+         that you will interoperate with. 
+    
+    <MetadataProvider id="HTTPMetadata"
+                      xsi:type="FileBackedHTTPMetadataProvider"
+                      backingFile="%{idp.home}/metadata/localCopyFromXYZHTTP.xml"
+                      metadataURL="http://WHATEVER"> 
+        
+        <MetadataFilter xsi:type="SignatureValidation"
+            requireSignedMetadata="false">
+            <PublicKey>
+                THIS IS AN EXAMPLE
+            
+                MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
+                uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
+                LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
+                NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
+                nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
+                E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
+                4wIDAQAB
+            </PublicKey>
+        </MetadataFilter>
+        <MetadataFilter xsi:type="EntityRoleWhiteList">
+            <RetainedRole>md:SPSSODescriptor</RetainedRole>
+        </MetadataFilter>
+        
+    </MetadataProvider>
+    
+    -->   
+
+    <!-- Example file metadata provider.  Use this if you want to load metadata
+         from a local file.  You might use this if you have some local SPs
+         which are not "federated" but you wish to offer a service to.
+         
+         If you do not provide a SignatureValidation filter then you *have*
+         to know that the file is valid.
+         
+
+    <MetadataProvider id="LocalMetadata"  xsi:type="FilesystemMetadataProvider" metadataFile="PATH_TO_YOUR_METADATA"/>
+
+     -->
+          
+    
+</MetadataProvider>
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-backchannel.crt b/demo/complex0/idp/shibboleth-idp/credentials/idp-backchannel.crt
new file mode 100644
index 0000000..c1f8fab
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/credentials/idp-backchannel.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+-----END CERTIFICATE-----
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-backchannel.p12 b/demo/complex0/idp/shibboleth-idp/credentials/idp-backchannel.p12
new file mode 100644
index 0000000..112540a
Binary files /dev/null and b/demo/complex0/idp/shibboleth-idp/credentials/idp-backchannel.p12 differ
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-browser.p12 b/demo/complex0/idp/shibboleth-idp/credentials/idp-browser.p12
new file mode 100644
index 0000000..032be0b
Binary files /dev/null and b/demo/complex0/idp/shibboleth-idp/credentials/idp-browser.p12 differ
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-encryption.crt b/demo/complex0/idp/shibboleth-idp/credentials/idp-encryption.crt
new file mode 100644
index 0000000..15d764f
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/credentials/idp-encryption.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+-----END CERTIFICATE-----
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-encryption.key b/demo/complex0/idp/shibboleth-idp/credentials/idp-encryption.key
new file mode 100644
index 0000000..8bb5cc6
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/credentials/idp-encryption.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAgV79KN35k/Ipbsi4yeJQQFQlvmUVchFz2ELkYu73w3DuGund
+ZMYiS7GitFvPFTcYxUEa/D4A5Fq9vL8KB9a4JOKS7LMyw+PAwcw/eNqXiZf0uhZ7
+CCY5mh3AYeKWzYVOMqMLut4ipL7ba3GQBG6RK6OmfAs4lhMfLMsKGmBEBonz5K/T
+kVegp97cavvYDAXjxuNRq7Wa1BiLvsa53S9EoYeD6tHqv/TALFZSCFxGvPVnx/Cd
+pBXEzn6FrSHO9G+0y2ULMeGJzXJ6xi0lBHLLRcjy1/l7b+UjWRfPTjiMV1TYzb4B
+OQ2yW/YTDOFABaiPtW6PUKrccE4Y3P7DryMczQIDAQABAoIBAF/IflMllcUtw/Nb
+9USzpIscQh2nJaugtE5nqER/fT1cfU273Mjh0T6NtFMorjec5WAWBe6/0VVAwb3f
+C4QmO4xDnFhXjLxwAaT6nfvSi+O5d93XCxxLgNZUNL3ET7a2feELyoF+OdQT4sy3
+9dLyMdVHgtnQTQMAAVLeuQoyP+s+Zax4Gca6ln8QxIIvDoD7NITnpl8887Hghhzl
+CvKtRiPRtoI2JTXWgWuLI6xXfVsDvFT+Up+ki9TMLWLACcmMU1d+lUBOKIqhhQHG
++np9iKxVausJwYaLwwT3h8SItNon7ltbV6kcqyZxMAA+uN8CVgIb5UaUrlW7Nvze
+1iUNudkCgYEAxpnBg8YxdEHFSMTqjEOYapn18cs3n32EBPtvPaUcvw3mGC1+ZVx1
+9WqnVsgykBOWI0qSBVF7Kke8yOqgqWtYQUFqLiMgCC9e/QcXnrm/bzAmKDgLVcCR
+KzgqU2ECQDkNSS0qeODjLGX4SEabDbLhN59WykHKM0i/RcrbhuvT1BcCgYEApsMD
+TFQBaiaEmLVm252piZf8b5g3DrUHeqGktHkHXTW4Iyyn8zEknoiCosk/Tej73zga
+cTT3zQgEh63DMC9Ag8IbIJiDpYLMkt1QvZYtq95E/94GVEfRRok6/pyagGYB351R
+PXcykrDyy26FSofmtaXU37Wxaj3ow+WROaPgULsCgYEArFoFScG3a2gkuRlDX8TN
+wj2o5lTxCbWY2+YEzR+8icWbGQJqPbb3G6uaW8LTtpt44Vm2zWzAEZo+KLMOCNmC
+tub5Kd8Lzm6l5brA8dvLWcgUZTT2CU5b7YEJomB+3pNkh0vuHwczv3Ui+j5kE4hY
+0bezT0W3H7iTXhNFXprMs7MCgYEAlIZn75l6URLRUjluzPdVQoktei72CpFNgflp
++ps45dmskRd61mzUkqY+w8G+MiPqANu1IVLtyZz0e+tVRxsuuKsvAg8UYVtn3P5k
+pRaWwtaKWeFjfbkhOVOMSa0tJmK0FHfHHZmGX4ReGrXq3YDBCNQUDtOCmn9dSuyy
+NcYxSXUCgYB+yo6dg8nyHDSqKDdrQQiAKv7jNsbecQ/rYrt8l0n9FBiwn5R7v6kp
+afsimCVou5i06L2Cr5Xs+XSf11KVkDh+qM70ZFubWEsHCDrS1KrxUzfFbrQczKof
+qX7ZsBuOT72RwVEa8fpT6IZ6IpOOEPmUid/f2VM2aAcXgaF//vMjxA==
+-----END RSA PRIVATE KEY-----
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-signing.crt b/demo/complex0/idp/shibboleth-idp/credentials/idp-signing.crt
new file mode 100644
index 0000000..6a032c1
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/credentials/idp-signing.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+-----END CERTIFICATE-----
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/idp-signing.key b/demo/complex0/idp/shibboleth-idp/credentials/idp-signing.key
new file mode 100644
index 0000000..011c27c
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/credentials/idp-signing.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7gu6eo4dua
+eLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2Z6dzJsul
+JZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJCb/Q6dYz
+RWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+MNkv6aId
+cHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBsuYlY7lEr
+89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABAoIBAGpInLarQ0+X+ZXK
++aoC+tNO9DUiHq/z2OD4ALGhXSTvr4mgBWNWTkc0F+qJD8MlM8zNkJxaoNGTyLjY
+Z95NQJPXAx2k15HwCENdulvV1oiX0dkTjgmscRmj6FwNAZ0EnWtien45mxZHxEyW
+FkbB9+OHc6JzNvzG9ps1Vk1FtFtO8w4exXuJVATJeArQmMvAUHMJYPb7Qs+/NX9R
+RlDvFfXDzQv5eAzudT1SyFSa5W+Bsw6BtEoeiqdp+xQh4yc733nwN7KG2Z/TpGse
+jVe6akbULuCXOe9uPa7kv8hnQEUH38QVlIw8pK1SsgNq7S0U44WU5uF8gbDBYle/
+OoPBvSECgYEAvCwVEa8ryLzee5FaX4PBxk10lEl/Yp9jC88wPUQ+ZpfniIIQIfwl
+csRE9D3/dJOVAxw/Ac32F72SLVDzLabAhlBRINYLB0ZkVuJi1CIoDHIf9nfh/pOx
+b96VMUe/mpAL4hZnZkmBKjesX5URPEKtBD0aSeCw9aFqhORjRrxCJg0CgYEAuNaD
+LOuTPKsC6nxRtiL9r0CA5gCCdpALxwJA7wHAeh03i5xmy61i4iOMaunxKZhG+nzz
+PhcI8Uhwwk+l3tbYAf1rrtmMKNcyjy+UqWXGt4ZkWFlIyIungyLiH9L32IMhXNF0
+fBgOZNtFTmQBU18a78uIir9xASUbtaakzOtJ2+cCgYAgfawVpZ11x8bSp0Jng6SN
+zQn4IMiyCrtbaqb1rTbpGAmOdIa8l4EP0/vkAGB/jIwKQXJPqXR4nO8EjBmxJD3R
+80RO2yaEVw80QVq3Lj6kB4ClWgXXo0DcBB7Wp4DZ+01R+HRaIQ8AbySATIjxUsH1
+HWfQoc9sWja+Q4Ew0YjKcQKBgGLoPsdBw8b6B5RsM9lPvgoSbScmbKl/CR5TwWVj
+vZhanAd0CLnCrSAvP4tSZf8JAio1xH+cGefrCJOhxTOKKYpfDklBFjQge2iNYHKJ
+CJ3aJ0XzePP/bwLIHtJCtOdBvA+L8VYaFVG418xLzT3MrYBVnFoKeTDQp5Q7eQJC
+gYJPAoGBAKHcuXWzvXoHKnOg8Ljg2xZ6/SfjwNDIIrpXVTAQifmK3q4+Ua2Q+Cjq
+97tPMxF2bVRcbnCSNKpTMOTrsWs8Z3GpMyCh6XgYMSlclXusDVUkRkPpWj8hVTR4
+opm/rxS83hCrTsIX3Il3T8Fpb97kdF+unCiWEaxrPEurjW8lB506
+-----END RSA PRIVATE KEY-----
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/sealer.jks b/demo/complex0/idp/shibboleth-idp/credentials/sealer.jks
new file mode 100644
index 0000000..89957e0
Binary files /dev/null and b/demo/complex0/idp/shibboleth-idp/credentials/sealer.jks differ
diff --git a/demo/complex0/idp/shibboleth-idp/credentials/sealer.kver b/demo/complex0/idp/shibboleth-idp/credentials/sealer.kver
new file mode 100644
index 0000000..d64b0e4
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/credentials/sealer.kver
@@ -0,0 +1,2 @@
+#Fri Dec 11 02:20:32 UTC 2015
+CurrentVersion=1
diff --git a/demo/complex0/idp/shibboleth-idp/metadata/grouper-sp.xml b/demo/complex0/idp/shibboleth-idp/metadata/grouper-sp.xml
new file mode 100644
index 0000000..5b42a7b
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/metadata/grouper-sp.xml
@@ -0,0 +1,78 @@
+<!--
+This is example metadata only. Do *NOT* supply it as is without review,
+and do *NOT* provide it in real time to your partners.
+ -->
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_57114916ca68943103854cb57a3a3b1c7c38bb81" entityID="https://grouperdemo/shibboleth">
+
+  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+  </md:Extensions>
+
+  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://localhost:4443/Shibboleth.sso/Login"/>
+      <idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://localhost:4443/Shibboleth.sso/Login" index="1"/>
+    </md:Extensions>
+    <md:KeyDescriptor>
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:KeyName>sp.example.org</ds:KeyName>
+        <ds:X509Data>
+          <ds:X509SubjectName>CN=sp.example.org,O=Internet2/TIER,L=Ann Arbor,ST=MI,C=US</ds:X509SubjectName>
+          <ds:X509Certificate>MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+</ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
+    </md:KeyDescriptor>
+    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:4443/Shibboleth.sso/Artifact/SOAP" index="1"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:4443/Shibboleth.sso/SLO/SOAP"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:4443/Shibboleth.sso/SLO/Redirect"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:4443/Shibboleth.sso/SLO/POST"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:4443/Shibboleth.sso/SLO/Artifact"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:4443/Shibboleth.sso/SAML2/POST" index="1"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost:4443/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:4443/Shibboleth.sso/SAML2/Artifact" index="3"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://localhost:4443/Shibboleth.sso/SAML2/ECP" index="4"/>
+  </md:SPSSODescriptor>
+
+</md:EntityDescriptor>
diff --git a/demo/complex0/idp/shibboleth-idp/metadata/idp-metadata.xml b/demo/complex0/idp/shibboleth-idp/metadata/idp-metadata.xml
new file mode 100644
index 0000000..84266d4
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/metadata/idp-metadata.xml
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex0/idp/shibboleth-idp/metadata/midpoint-sp-new.xml b/demo/complex0/idp/shibboleth-idp/metadata/midpoint-sp-new.xml
new file mode 100644
index 0000000..a819f4b
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/metadata/midpoint-sp-new.xml
@@ -0,0 +1,37 @@
+<EntityDescriptor entityID="https://midpointdemo/idp/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+  <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <Extensions>
+      <shibmd:Scope regexp="false">midpointdemo</shibmd:Scope>
+    </Extensions>
+    <KeyDescriptor use="signing">
+      <ds:KeyInfo>
+        <ds:X509Data>
+          <ds:X509Certificate>
+MIIDHDCCAgSgAwIBAgIJAPEnL5jgbeVoMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
+BAMMD2lkcC5leGFtcGxlLmVkdTAeFw0xODEwMTAyMDM1NDBaFw0yMzEwMDkyMDM1
+NDBaMBoxGDAWBgNVBAMMD2lkcC5leGFtcGxlLmVkdTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKwTrvQhmFX3SUNgJAhQ/YV0UX56Rt53mwbiKuH+Ez83
+7z6XRynBVsfzHfbWe0IpNKx5mIr84dfbGhQKQBEKzQuek7ihW3J6PIVZN1A3icZZ
+B9i7gow902bT0ZfRG8QW49gl7pk3ASutPcO9Dq5Xc/AqWr3OSO/Pei0yBtTdzG3b
+rm0u0gbj3P2tjt7BN77wIB+yjJsND3ITtP0MFXIJxLTlty8thwqQOAOAYcF+rhC5
+znnBLsRNo0E57PtzZs8i/BpEX2uPTxpEyvlU1vtyxcKUiHtK5ZjOsDEkS2rEualr
++FILYg/Oxw1gi0+mNO1a94Ft+UoLiREztq6MQt8OK98CAwEAAaNlMGMwQgYDVR0R
+BDswOYIPaWRwLmV4YW1wbGUuZWR1hiZodHRwczovL2lkcC5leGFtcGxlLmVkdS9p
+ZHAvc2hpYmJvbGV0aDAdBgNVHQ4EFgQU3ZJ8oHkmlgPtZuZAxnzONccPsb8wDQYJ
+KoZIhvcNAQELBQADggEBAIJ4oZKSMGpF8J3qdfjLZGkc3iVbu/eiE1MD77no0oCz
+nelY0CNUBuFJk1Xv+Bv0fW0cVugtMPz4xi7zv0zkpS2IVxpPZWBosuVabUD9k+V4
+iN5woJdO7e2KRGvhlWmbkmoZUvhygDe0u0vblNfLzDwFQvxHXiWG//P7SanoQrjP
+dE8U21tYz+EFm6s5TvHxVhr9id8c+UacAFCpAtzUB+J8K1abx05XlKsySflkOQV9
+JbM4zOy5gXSI5dY9dGUF77g0muyC+jAhIhLSt/7v3vJgvBurrxPoeBFXOU3D+siT
+VZlKtYzYjJhVqXx1vKrWEE1hkpqm+iYgZe4MvgcdswY=
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </KeyDescriptor>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/ECP"/>
+  </IDPSSODescriptor>
+</EntityDescriptor>
+
diff --git a/demo/complex0/idp/shibboleth-idp/metadata/midpoint-sp.xml b/demo/complex0/idp/shibboleth-idp/metadata/midpoint-sp.xml
new file mode 100644
index 0000000..54f0577
--- /dev/null
+++ b/demo/complex0/idp/shibboleth-idp/metadata/midpoint-sp.xml
@@ -0,0 +1,80 @@
+<!--
+This is example metadata only. Do *NOT* supply it as is without review,
+and do *NOT* provide it in real time to your partners.
+ -->
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_57114916ca68943103854cb57a3a3b1c7c38bb81" entityID="https://midpointdemo/shibboleth">
+
+  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+  </md:Extensions>
+
+  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://localhost:8443/Shibboleth.sso/Login"/>
+      <idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://localhost:8443/Shibboleth.sso/Login" index="1"/>
+    </md:Extensions>
+    <md:KeyDescriptor>
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:KeyName>midpoint.sp.example.org</ds:KeyName>
+        <ds:X509Data>
+          <ds:X509SubjectName>CN=midpoint.sp.example.org,O=Internet2/TIER,L=Ann Arbor,ST=MI,C=US</ds:X509SubjectName>
+          <ds:X509Certificate>MIIDqDCCApCgAwIBAgIJAKUZrfriIt9cMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXZXZvbHZldW0uc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU0NjU3WhcNMTkwOTE0MDU0NjU3WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF2V2b2x2ZXVtLnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw5v1zxlM94yaBssgNNbIUJwW
+XxbGxgSs2AWBeg2aEi/VQd2UE5ivZakNJlqWSJyHo2xE4kxeSyBBxinjSyhmpNao
+xIcqQsgW0gxo4SEHo3kUXWPo+of/pj6CslutsSJZWGTRV0dHITvaWX+NM8eXMfgu
+mJFwy3RMdLaWQhY1Dyi2jNoO+DZnfNgPyPeEZcmORaoeEID9QdZfHtcgTf2QfSHq
++xsTwHB6Ro5t7YD2ma8Krb/XcDTfsq3qJemd7LhPj5lGmhYSMgDbgwEkZgZ1kBOP
+lfsP2BvX5nipv7Vd1C5YXmv+NDR8V3yAWBC7ZAenxGmrnkaSVXnpUplUsGGm1QID
+AQABo1MwUTAdBgNVHQ4EFgQUuxSZwW6V1P/b0tsTM32OU/v/n+UwHwYDVR0jBBgw
+FoAUuxSZwW6V1P/b0tsTM32OU/v/n+UwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAJWLXEfZkPeUyiGvsIUjczzdF3ptqXoP9aETS2pOV9sTri19R
+TsQZW6XQRHGtuEOsqEGH8yiTdGR5hbGC+ynH/xTJnK+tBn/R3KrgxLKyMvoUzAPl
+mhVq1dh+ZEtbsRpQRRubP6nm9kXNma0cXrkJSzuWM0W+l/xSOOYiSRRk3XWJfVjn
+9jQlcJRh5SOkKN08oZHrCYKxToEuOfV8PtRj3T80DhsBTv2SHqhg4cBhzQPb0Kjm
+9m4IkYOz8c5ZtuHDGnqMHw60Nyt+jyik4mMFP2frcOVP0W0sgwcfHllYzHoA/Khq
+Yk3TBVs1BjPuNDJWHct8Eo68YP2/ZvzqfVM87Q==
+</ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
+    </md:KeyDescriptor>
+    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:8443/Shibboleth.sso/Artifact/SOAP" index="1"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:8443/Shibboleth.sso/SLO/SOAP"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:8443/Shibboleth.sso/SLO/Redirect"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:8443/Shibboleth.sso/SLO/POST"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:8443/Shibboleth.sso/SLO/Artifact"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:8443/Shibboleth.sso/SAML2/POST" index="1"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost:8443/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:8443/Shibboleth.sso/SAML2/Artifact" index="3"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://localhost:8443/Shibboleth.sso/SAML2/ECP" index="4"/>
+  </md:SPSSODescriptor>
+
+</md:EntityDescriptor>
diff --git a/demo/complex0/midpoint-objects-manual/tasks/task-async-update-grouper.xml b/demo/complex0/midpoint-objects-manual/tasks/task-async-update-grouper.xml
new file mode 100644
index 0000000..750ddc5
--- /dev/null
+++ b/demo/complex0/midpoint-objects-manual/tasks/task-async-update-grouper.xml
@@ -0,0 +1,43 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="47fc57bd-8c34-4555-9b9f-7087ff179860">
+	<name>Grouper async updates</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<!-- ... -->
+	</extension>
+	<taskIdentifier>1552664339630-0-2</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>AsynchronousUpdate</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/async-update/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex0/midpoint-objects-manual/tasks/task-import-sis-persons.xml b/demo/complex0/midpoint-objects-manual/tasks/task-import-sis-persons.xml
new file mode 100644
index 0000000..ebeb5df
--- /dev/null
+++ b/demo/complex0/midpoint-objects-manual/tasks/task-import-sis-persons.xml
@@ -0,0 +1,31 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+      oid="22c2a3d0-0961-4255-9eec-c550a79aeaaa">
+   <name>Import from SIS persons</name>
+   <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:type="c:ExtensionType">
+      <mext:kind>account</mext:kind>
+      <mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+      <mext:tracing>
+          <interval>500</interval>
+      </mext:tracing>
+   </extension>
+   <taskIdentifier>1535407239440-0-1</taskIdentifier>
+   <ownerRef oid="00000000-0000-0000-0000-000000000002"
+             relation="org:default"
+             type="c:UserType"><!-- administrator --></ownerRef>
+   <executionStatus>runnable</executionStatus>
+   <category>ImportingAccounts</category>
+   <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3</handlerUri>
+   <objectRef oid="4d70a0da-02dd-41cf-b0a1-00e75d3eaa15"
+              relation="org:default"
+              type="c:ResourceType"><!-- SQL SIS persons (sources) --></objectRef>
+   <recurrence>single</recurrence>
+   <binding>loose</binding>
+</task>
diff --git a/demo/complex0/midpoint-objects-manual/tasks/task-recomputation-users.xml b/demo/complex0/midpoint-objects-manual/tasks/task-recomputation-users.xml
new file mode 100644
index 0000000..08bcc01
--- /dev/null
+++ b/demo/complex0/midpoint-objects-manual/tasks/task-recomputation-users.xml
@@ -0,0 +1,25 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" oid="83a737ea-5eb7-4e78-b431-331cccf02354">
+    <name>User recomputing with bucket</name>
+    <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xsi:type="c:ExtensionType">
+        <mext:objectType>c:UserType</mext:objectType>
+        <mext:tracingInterval>200</mext:tracingInterval>
+    </extension>
+    <taskIdentifier>1571729899646-0-1</taskIdentifier>
+    <ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+        <!-- administrator -->
+    </ownerRef>
+    <channel>http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#recompute</channel>
+    <executionStatus>runnable</executionStatus>
+    <category>Recomputation</category>
+    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/recompute/handler-3</handlerUri>
+    <workManagement>
+        <taskKind>standalone</taskKind>
+        <buckets>
+            <oidSegmentation>
+                <depth>2</depth>
+            </oidSegmentation>
+        </buckets>
+    </workManagement>
+    <recurrence>single</recurrence>
+    <binding>tight</binding>
+</task>
diff --git a/demo/complex0/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml b/demo/complex0/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
new file mode 100644
index 0000000..b59f5d7
--- /dev/null
+++ b/demo/complex0/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
@@ -0,0 +1,43 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="605a0127-a313-442a-9d5e-151eac8b0745">
+	<name>Grouper reconciliation (groups)</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<mext:objectclass>ri:CustomPlainGroupObjectClass</mext:objectclass>
+	</extension>
+	<taskIdentifier>605a0127-a313-442a-9d5e-151eac8b0745</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>Reconciliation</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/reconciliation/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex0/midpoint-objects/archetypes/archetype-affiliation.xml b/demo/complex0/midpoint-objects/archetypes/archetype-affiliation.xml
new file mode 100644
index 0000000..0064575
--- /dev/null
+++ b/demo/complex0/midpoint-objects/archetypes/archetype-affiliation.xml
@@ -0,0 +1,42 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="56f53812-047d-4b69-83e8-519a73d161e1">
+    <name>affiliation</name>
+    <extension>
+        <ext:grouperNamePrefix>ref:affiliation:</ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=Affiliations,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+        <ext:midPointNamePrefix>affiliation_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Affiliation: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="1d7c0e3a-4456-409c-9f50-95407b2eb785" relation="org:default" type="c:OrgType" />     <!-- affiliations -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <resourceRef oid="e417225d-8a08-46f3-9b5d-624990b52386" relation="org:default" type="c:ResourceType" />     <!-- Faculty CSV -->
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier == 'faculty'</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</archetype>
diff --git a/demo/complex0/midpoint-objects/archetypes/archetype-course.xml b/demo/complex0/midpoint-objects/archetypes/archetype-course.xml
new file mode 100644
index 0000000..5a906e1
--- /dev/null
+++ b/demo/complex0/midpoint-objects/archetypes/archetype-course.xml
@@ -0,0 +1,54 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="3dab9a72-118b-4e40-a138-bb691c335eca">
+    <name>course</name>
+    <extension>
+        <ext:grouperNamePrefix>ref:course:</ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=Courses,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+        <ext:midPointNamePrefix>course_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Course: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="225e9360-0639-40ba-8a31-7f31bef067be" relation="org:default" type="c:OrgType" />     <!-- courses -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <strength>weak</strength>
+            <resourceRef oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" relation="org:default" type="c:ResourceType" />     <!-- CS CSV -->
+            <attribute>
+                <c:ref>ri:courses</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier?.startsWith('CS')</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</archetype>
diff --git a/demo/complex0/midpoint-objects/archetypes/archetype-department.xml b/demo/complex0/midpoint-objects/archetypes/archetype-department.xml
new file mode 100644
index 0000000..c8cf8b4
--- /dev/null
+++ b/demo/complex0/midpoint-objects/archetypes/archetype-department.xml
@@ -0,0 +1,43 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="1cec5f78-8fba-459b-9547-ef7485009f40">
+    <name>department</name>
+    <extension>
+        <ext:grouperNamePrefix>ref:dept:</ext:grouperNamePrefix>
+        <ext:midPointNamePrefix>department_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Department: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <!--  No LDAP metarole here: we deal with LDAP ourselves -->
+    <inducement>
+        <targetRef oid="bee44c51-2469-411d-bac7-695728e9c241" relation="org:default" type="c:OrgType" />     <!-- departments -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- LDAP -->
+            <attribute>
+                <ref>ri:businessCategory</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</archetype>
diff --git a/demo/complex0/midpoint-objects/archetypes/archetype-mailing-list.xml b/demo/complex0/midpoint-objects/archetypes/archetype-mailing-list.xml
new file mode 100644
index 0000000..c5ed3a8
--- /dev/null
+++ b/demo/complex0/midpoint-objects/archetypes/archetype-mailing-list.xml
@@ -0,0 +1,46 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="1645d1dc-1f7c-4508-b50b-97b501ccdee3">
+    <name>mailing-list</name>
+    <extension>
+        <ext:grouperNamePrefix>app:mailinglist:</ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=generic,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>       <!--  could be also something specific e.g. ou=lists,ou=Groups,dc=internet2,dc=edu -->
+        <ext:midPointNamePrefix>mailinglist_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Mailing list: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="d81fb46c-20c7-44d3-8402-fef404ea1264" relation="org:default" type="c:OrgType" />     <!-- generic-groups -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <resourceRef oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" relation="org:default" type="c:ResourceType" />     <!-- Mailing lists CSV -->
+            <attribute>
+                <c:ref>ri:lists</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</archetype>
diff --git a/demo/complex0/midpoint-objects/archetypes/archetype-midpoint-group.xml b/demo/complex0/midpoint-objects/archetypes/archetype-midpoint-group.xml
new file mode 100644
index 0000000..eb94ab2
--- /dev/null
+++ b/demo/complex0/midpoint-objects/archetypes/archetype-midpoint-group.xml
@@ -0,0 +1,22 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="2be36917-71ad-4c3e-8789-89cadea2d5d6">
+    <name>midpoint-group</name>
+    <extension>
+        <ext:ldapRootDn>ou=midpoint,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+    </extension>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="4790ab69-7ef0-41a4-8992-78877f3beb23" relation="org:default" type="c:OrgType" />     <!-- midpoint-groups -->
+    </inducement>
+</archetype>
diff --git a/demo/complex0/midpoint-objects/functionLibraries/function-library-grouper.xml b/demo/complex0/midpoint-objects/functionLibraries/function-library-grouper.xml
new file mode 100644
index 0000000..6219eb0
--- /dev/null
+++ b/demo/complex0/midpoint-objects/functionLibraries/function-library-grouper.xml
@@ -0,0 +1,184 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<functionLibrary oid="2eef4181-25fa-420f-909d-846a36ca90f3"
+				 xmlns='http://midpoint.evolveum.com/xml/ns/public/common/common-3'
+				 xmlns:c='http://midpoint.evolveum.com/xml/ns/public/common/common-3'
+				 xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3'
+				 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+				 xmlns:xsd='http://www.w3.org/2001/XMLSchema'
+				 xmlns:piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'>
+	<name>grouper</name>
+	<description>Functions for Grouper AMQP connector</description>
+	<function>
+
+		<!-- Some examples:
+	{
+	  encrypted=false,
+	  esbEvent=[
+	  {
+		sourceId=ldap,
+		membershipType=flattened,
+		fieldName=members,
+		groupId=00000000000000000000000000000001,
+		changeOccurred=false,
+		createdOnMicros=1551884863420000,
+		subjectId=banderson,
+		id=94320942304930294023940329403294,
+		sequenceNumber=1000,
+		eventType=MEMBERSHIP_ADD,
+		groupName=etc:midpointGroups
+	  }
+	]}
+
+
+	 {
+	  "encrypted": false,
+	  "esbEvent": [
+		{
+		  "displayName": "ref:affiliation:alumni",
+		  "changeOccurred": false,
+		  "createdOnMicros": 1551884850499000,
+		  "parentStemId": "9a7ce40af6c546148b41eec81b8ca18d",
+		  "id": "00000000000000000000000000000002",
+		  "sequenceNumber": "110",
+		  "eventType": "GROUP_ADD",
+		  "name": "ref:affiliation:alumni"
+		}
+	  ]
+	}
+	 -->
+
+
+		<name>createUcfChange</name>
+		<parameter>
+			<name>message</name>
+			<type>c:AsyncUpdateMessageType</type>
+		</parameter>
+		<parameter>
+			<name>superGroup</name>
+			<type>xsd:string</type>
+		</parameter>
+		<parameter>
+			<name>groupIncludePattern</name>
+			<type>xsd:anyType</type>
+		</parameter>
+		<parameter>
+			<name>groupExcludePattern</name>
+			<type>xsd:anyType</type>
+		</parameter>
+		<parameter>
+			<name>relevantSourceId</name>
+			<type>xsd:string</type>
+		</parameter>
+		<script>
+			<code>
+				import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+				import com.evolveum.prism.xml.ns._public.types_3.*
+				import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
+				import com.evolveum.midpoint.schema.util.*
+				import com.evolveum.midpoint.prism.path.*
+                import com.evolveum.midpoint.schema.constants.*
+                import com.evolveum.midpoint.prism.delta.*
+                
+                PLAIN_GROUP_OBJECT_CLASS = new ItemName(MidPointConstants.NS_RI, 'CustomPlainGroupObjectClass')
+                TRIGGER_FIRE_AFTER = 60000
+                TRIGGER_SAFETY_MARGIN = 10000
+
+				esbEvent = midpoint.getMessageBodyAsMap(message)['esbEvent'][0]
+				log.info('esbEvent = {}', esbEvent)
+				eventType = esbEvent['eventType']
+				if (eventType == 'MEMBERSHIP_ADD' || eventType == 'MEMBERSHIP_DELETE') {
+					groupName = esbEvent['groupName']
+					if (groupName == null) {
+						log.warn('No group name in membership change message, ignoring it: {}', esbEvent)
+						return null
+					}
+                    groupId = esbEvent['groupId']
+                    if (groupId == null) {
+                        log.warn('No group ID in membership change message, ignoring it: {}', esbEvent)
+                        return null
+                    }
+					isExported = matches(groupName, groupIncludePattern, groupExcludePattern)
+					if (!isExported) {
+						log.info('Irrelevant group membership change, ignoring it: {}', groupName)
+						return null
+					}
+					sourceId = esbEvent['sourceId']
+					if (sourceId != relevantSourceId) {
+						log.info('Irrelevant subject source ID in membership change message, ignoring it: {}', sourceId)
+						return null
+					}
+					subjectId = esbEvent['subjectId']
+                    if (subjectId == null) {
+                        log.info('Null subject ID in membership change message, ignoring it: {}', sourceId)
+                        return null
+                    }
+					log.info('### {} - {} - {}', subjectId, eventType, groupName)
+					identifiers = new HashMap()
+					identifiers.put(ICFS_NAME, groupName)
+					identifiers.put(ICFS_UID, groupId)
+					ObjectDeltaType delta
+					itemDelta = new ItemDeltaType()
+					itemDelta.modificationType = eventType == 'MEMBERSHIP_ADD' ? ModificationTypeType.ADD : ModificationTypeType.DELETE
+					itemDelta.path = new ItemPathType(ItemPath.create(ShadowType.F_ATTRIBUTES, 'member'))
+					itemDelta.value.add(RawType.fromPropertyRealValue(subjectId, null, prismContext))
+					delta = new ObjectDeltaType()
+					delta.changeType = ChangeTypeType.MODIFY
+					delta.itemDelta.add(itemDelta)
+                    
+                    added = midpoint
+                            .getOptimizingTriggerCreator(TRIGGER_FIRE_AFTER, TRIGGER_SAFETY_MARGIN)
+                            .createForNamedUser(subjectId)
+                    log.info('Recompute trigger for {}: {}', subjectId, added ? 'added' : 'not added (already present or user not found)')
+                    
+					return UcfChangeUtil.create(PLAIN_GROUP_OBJECT_CLASS, identifiers, delta, prismContext)
+				} else if (eventType == 'GROUP_ADD' || eventType == 'GROUP_DELETE') {
+					groupName = esbEvent['name']
+					groupId = esbEvent['id']
+					isExported = matches(groupName, groupIncludePattern, groupExcludePattern)
+					if (!isExported) {
+						log.info('Irrelevant group add/delete event, ignoring it: {}', groupName)
+						return null
+					}
+					identifiers = new HashMap()
+					identifiers.put(ICFS_NAME, groupName)
+					identifiers.put(ICFS_UID, groupId)
+					ObjectDeltaType delta
+					if (eventType == 'GROUP_DELETE') {
+						delta = new ObjectDeltaType()
+						delta.changeType = ChangeTypeType.DELETE
+					} else {
+						delta = null
+					}
+					return UcfChangeUtil.create(PLAIN_GROUP_OBJECT_CLASS, identifiers, delta, prismContext)
+				} else {
+					log.warn('Unsupported event type: {} -> {}', eventType, esbEvent)
+					return null
+				}
+
+				def matches(String name, Collection includes, Collection excludes) {
+					matches(name, includes) &amp;&amp; !matches(name, excludes)
+				}
+
+				def matches(String name, Collection patterns) {
+					if (name == null || patterns == null) {
+						false
+					} else {
+						for (pattern in patterns) {
+							if (name ==~ pattern) {
+								return true
+							}
+						}
+						false
+					}
+				}
+			</code>
+		</script>
+		<returnType>c:UcfChangeType</returnType>
+	</function>
+</functionLibrary>
diff --git a/demo/complex0/midpoint-objects/objectTemplates/template-user.xml b/demo/complex0/midpoint-objects/objectTemplates/template-user.xml
new file mode 100644
index 0000000..9442803
--- /dev/null
+++ b/demo/complex0/midpoint-objects/objectTemplates/template-user.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" oid="8098b124-c20c-4965-8adf-e528abedf7a4">
+    <name>User Template</name>
+    <mapping>
+        <strength>strong</strength>
+        <source>
+            <path>name</path>
+        </source>
+        <expression>
+            <script>
+                <code>
+                    import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+                    import com.evolveum.midpoint.schema.constants.*
+                    import com.evolveum.midpoint.schema.* 
+                    import javax.xml.namespace.*
+                    import com.evolveum.midpoint.util.*
+                    import com.evolveum.midpoint.prism.path.*
+                    
+                    GROUPER_RESOURCE_OID = '1eff65de-5bb6-483d-9edf-8cc2c2ee0233'
+                    MEMBER_NAME = new QName(MidPointConstants.NS_RI, 'member')
+                    
+                    memberDef = prismContext.definitionFactory().createPropertyDefinition(MEMBER_NAME, DOMUtil.XSD_STRING)
+                    memberDef.setMaxOccurs(-1)
+
+                    shadowQuery = prismContext.queryFor(ShadowType.class)
+                        .item(ShadowType.F_RESOURCE_REF).ref(GROUPER_RESOURCE_OID)
+                        .and().item(ShadowType.F_SYNCHRONIZATION_SITUATION).eq(SynchronizationSituationType.LINKED)
+                        .and().item(ShadowType.F_KIND).eq(ShadowKindType.ENTITLEMENT)
+                        .and().item(ShadowType.F_INTENT).eq('group')
+                        .and().block().item(ShadowType.F_DEAD).isNull().or().item(ShadowType.F_DEAD).eq(false).endBlock()
+                        .and().item(ItemPath.create(ShadowType.F_ATTRIBUTES, MEMBER_NAME), memberDef).eq(basic.stringify(name))
+                        .build()
+                        
+                    //log.info('shadowQuery = {}\n{}', shadowQuery, shadowQuery.debugDump())
+                    options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch())
+                    shadows = midpoint.searchObjects(ShadowType.class, shadowQuery, options)
+                    //log.info('shadows found for {}: {}', name, shadows)
+                    
+                    orgNames = shadows.collect { basic.stringify(it.name) }            // todo - use attributes
+                    log.info('org names = {}', orgNames)
+                    
+                    if (!orgNames.isEmpty()) { 
+                        orgQueryBuilder = prismContext.queryFor(OrgType.class)
+                        
+                        first = true
+                        for (orgName in orgNames) {
+                            if (first) {
+                                first = false
+                            } else {
+                                orgQueryBuilder = orgQueryBuilder.or()
+                            }
+                            orgQueryBuilder = orgQueryBuilder.item(ItemPath.create(OrgType.F_EXTENSION, 'grouperName')).eq(orgName)
+                        }
+                            
+                        orgQuery = orgQueryBuilder.build()
+                        //log.info('org query:\n', orgQuery.debugDump())
+                        
+                        orgs = midpoint.searchObjects(OrgType.class, orgQuery, null)
+                        log.info('orgs found: {}', orgs)
+                        
+                        orgs.collect {
+                            new AssignmentType(prismContext)
+                                .subtype('grouper-group')
+                                .targetRef(it.oid, OrgType.COMPLEX_TYPE)
+                        }
+                    } else {
+                        null
+                    }
+                </code>
+            </script>
+        </expression>
+        <target>
+            <path>assignment</path>
+            <set>
+                <condition>
+                    <script>
+                        <code>
+                            assignment?.subtype.contains('grouper-group')
+                        </code>
+                    </script>
+                </condition>
+            </set>
+        </target>
+    </mapping>
+</objectTemplate>
diff --git a/demo/complex0/midpoint-objects/orgs/org-affiliations.xml b/demo/complex0/midpoint-objects/orgs/org-affiliations.xml
new file mode 100644
index 0000000..577c894
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-affiliations.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1d7c0e3a-4456-409c-9f50-95407b2eb785">
+    <name>affiliations</name>
+    <displayName>Affiliations</displayName>
+</org>
diff --git a/demo/complex0/midpoint-objects/orgs/org-courses.xml b/demo/complex0/midpoint-objects/orgs/org-courses.xml
new file mode 100644
index 0000000..47147d5
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-courses.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="225e9360-0639-40ba-8a31-7f31bef067be">
+    <name>courses</name>
+    <displayName>Courses</displayName>
+</org>
\ No newline at end of file
diff --git a/demo/complex0/midpoint-objects/orgs/org-departments.xml b/demo/complex0/midpoint-objects/orgs/org-departments.xml
new file mode 100644
index 0000000..b5638d4
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-departments.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="bee44c51-2469-411d-bac7-695728e9c241">
+    <name>departments</name>
+    <displayName>Departments</displayName>
+</org>
\ No newline at end of file
diff --git a/demo/complex0/midpoint-objects/orgs/org-generic-groups.xml b/demo/complex0/midpoint-objects/orgs/org-generic-groups.xml
new file mode 100644
index 0000000..baa2c79
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-generic-groups.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d">
+    <name>generic-groups</name>
+    <displayName>Generic groups</displayName>
+</org>
diff --git a/demo/complex0/midpoint-objects/orgs/org-grouper-sysadmin.xml b/demo/complex0/midpoint-objects/orgs/org-grouper-sysadmin.xml
new file mode 100644
index 0000000..201777a
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-grouper-sysadmin.xml
@@ -0,0 +1,16 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      oid="d48ec05b-fffd-4262-acd3-d9ff63365b62">
+    <name>org-grouper-sysadmin</name>
+    <displayName>Grouper Administrators</displayName>
+    <assignment id="1">
+        <targetRef oid="2be36917-71ad-4c3e-8789-89cadea2d5d6" type="ArchetypeType"/>         <!--  archetype midpoint-group -->
+    </assignment>
+    <identifier>sysadmingroup</identifier>
+</org>
diff --git a/demo/complex0/midpoint-objects/orgs/org-mailing-lists.xml b/demo/complex0/midpoint-objects/orgs/org-mailing-lists.xml
new file mode 100644
index 0000000..6674745
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-mailing-lists.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d81fb46c-20c7-44d3-8402-fef404ea1264">
+    <name>mailing-lists</name>
+    <displayName>Mailing lists</displayName>
+</org>
diff --git a/demo/complex0/midpoint-objects/orgs/org-midpoint-groups.xml b/demo/complex0/midpoint-objects/orgs/org-midpoint-groups.xml
new file mode 100644
index 0000000..9c0658d
--- /dev/null
+++ b/demo/complex0/midpoint-objects/orgs/org-midpoint-groups.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="4790ab69-7ef0-41a4-8992-78877f3beb23">
+    <name>midpoint-groups</name>
+    <displayName>midPoint groups</displayName>
+</org>
diff --git a/demo/complex0/midpoint-objects/resources/ldap-main.xml b/demo/complex0/midpoint-objects/resources/ldap-main.xml
new file mode 100644
index 0000000..09934db
--- /dev/null
+++ b/demo/complex0/midpoint-objects/resources/ldap-main.xml
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<resource oid="0a37121f-d515-4a23-9b6d-554c5ef61272"
+        xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3' xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+	xmlns:my="http://whatever.com/my" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
+	xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+
+	<name>LDAP (directory)</name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.ldap.LdapConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration
+		xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+		xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
+		<icfc:configurationProperties
+			xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
+            <icfcldap:port>389</icfcldap:port>
+            <icfcldap:host>directory</icfcldap:host>
+            <!-- <icfcldap:host>192.168.56.101</icfcldap:host>  -->
+			<icfcldap:baseContext>dc=internet2,dc=edu</icfcldap:baseContext>
+			<icfcldap:bindDn>cn=Directory Manager</icfcldap:bindDn>
+			<icfcldap:bindPassword>
+				<t:clearValue>password</t:clearValue>
+			</icfcldap:bindPassword>
+			<icfcldap:uidAttribute>nsUniqueId</icfcldap:uidAttribute>
+			<icfcldap:pagingStrategy>spr</icfcldap:pagingStrategy> <!-- spr? -->
+			<!--  <icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute>  -->
+			<icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes>
+			<icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
+			<icfcldap:operationalAttributes>nsAccountLock</icfcldap:operationalAttributes>
+			<!-- >icfcldap:usePermissiveModify>always</icfcldap:usePermissiveModify>
+			<icfcldap:passwordHashAlgorithm>SSHA</icfcldap:passwordHashAlgorithm  -->
+			<!-- >icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute> <icfcldap:vlvSortOrderingRule>2.5.13.3</icfcldap:vlvSortOrderingRule -->
+		</icfc:configurationProperties>
+		<icfc:resultsHandlerConfiguration>
+			<icfc:enableNormalizingResultsHandler>false</icfc:enableNormalizingResultsHandler>
+			<icfc:enableFilteredResultsHandler>false</icfc:enableFilteredResultsHandler>
+			<icfc:enableAttributesToGetSearchResultsHandler>false</icfc:enableAttributesToGetSearchResultsHandler>
+		</icfc:resultsHandlerConfiguration>
+	</connectorConfiguration>
+
+	<schema>
+		<generationConstraints>
+			<generateObjectClass>ri:inetOrgPerson</generateObjectClass>
+			<generateObjectClass>ri:eduPerson</generateObjectClass>
+			<generateObjectClass>ri:groupOfUniqueNames</generateObjectClass>
+			<generateObjectClass>ri:groupOfNames</generateObjectClass>
+			<generateObjectClass>ri:organizationalUnit</generateObjectClass>
+		</generationConstraints>
+	</schema>
+
+	<schemaHandling>
+		<objectType>
+			<kind>account</kind>
+			<displayName>Normal Account</displayName>
+			<default>true</default>
+			<objectClass>ri:inetOrgPerson</objectClass>
+			<auxiliaryObjectClass>ri:eduPerson</auxiliaryObjectClass>
+			<attribute>
+				<ref>ri:dn</ref>
+				<displayName>Distinguished Name</displayName>
+                <limitations>
+                    <minOccurs>0</minOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+				<matchingRule>mr:distinguishedName</matchingRule>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>name</path>
+                    </source>
+                    <expression>
+                        <script>
+                            <code>
+                                'uid=' + name + ',ou=People,dc=internet2,dc=edu'
+                            </code>
+                        </script>
+                    </expression>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:cn</ref>
+				<displayName>Common Name</displayName>
+				<limitations>
+					<minOccurs>0</minOccurs>
+				</limitations>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>fullName</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:sn</ref>
+				<displayName>Surname</displayName>
+                <limitations>
+                    <minOccurs>0</minOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>familyName</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:givenName</ref>
+				<displayName>Given Name</displayName>
+                <limitations>
+                    <minOccurs>0</minOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>givenName</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:uid</ref>
+				<displayName>Login Name</displayName>
+                <tolerant>false</tolerant>
+				<matchingRule>mr:stringIgnoreCase</matchingRule>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>name</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<displayName>Mail</displayName>
+				<matchingRule>mr:stringIgnoreCase</matchingRule>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>emailAddress</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:employeeNumber</ref>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>employeeNumber</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:businessCategory</ref>
+                <tolerant>false</tolerant>
+			</attribute>
+<!-- 				<attribute>
+				<ref>ri:eduPersonAffiliation</ref>
+				<outbound>
+					<strength>strong</strength>
+					<source>
+						<path>extension/rawAffiliation</path>
+					</source>
+				</outbound>
+                <tolerant>false</tolerant>
+			</attribute> -->
+            <association>
+                <tolerant>false</tolerant>
+                <ref>ri:group</ref>
+                <kind>entitlement</kind>
+                <intent>group</intent>
+                <direction>objectToSubject</direction>
+                <associationAttribute>ri:uniqueMember</associationAttribute>
+                <valueAttribute>ri:dn</valueAttribute>
+            </association>
+			<protected>
+				<filter>
+					<q:equal>
+						<q:matching>http://prism.evolveum.com/xml/ns/public/matching-rule-3#distinguishedName</q:matching>
+						<q:path>attributes/ri:dn</q:path>
+						<q:value>cn=root,dc=internet2,dc=edu</q:value>
+					</q:equal>
+				</filter>
+			</protected>
+            <credentials>
+                <password>
+                    <outbound/>
+                </password>
+            </credentials>
+		</objectType>
+        
+        <objectType>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <displayName>LDAP Group</displayName>
+            <objectClass>ri:groupOfUniqueNames</objectClass>
+            <attribute>
+                <ref>ri:uniqueMember</ref>
+                <matchingRule>mr:distinguishedName</matchingRule>
+                <fetchStrategy>minimal</fetchStrategy>
+            </attribute>
+            <attribute>
+                <ref>ri:dn</ref>
+                <matchingRule>mr:distinguishedName</matchingRule>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>extension/ldapDn</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:cn</ref>
+                <matchingRule>mr:stringIgnoreCase</matchingRule>
+                <outbound>
+                    <strength>weak</strength>
+                    <source>
+                        <path>identifier</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:uniqueMember</ref>
+                <matchingRule>mr:distinguishedName</matchingRule>
+				<fetchStrategy>minimal</fetchStrategy>
+            </attribute>
+        </objectType>
+	</schemaHandling>
+
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
+							$account/attributes/ri:uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+        <objectSynchronization>
+            <name>group sync</name>
+            <objectClass>ri:groupOfUniqueNames</objectClass>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <focusType>OrgType</focusType>
+            <enabled>true</enabled>
+            <condition>
+                <script>
+                    <code>
+                        import javax.naming.ldap.*
+                        dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                        dn.startsWith(new LdapName('ou=Affiliations,ou=Groups,dc=internet2,dc=edu')) ||
+                            dn.startsWith(new LdapName('ou=Courses,ou=Groups,dc=internet2,dc=edu')) ||
+                            dn.startsWith(new LdapName('ou=generic,ou=Groups,dc=internet2,dc=edu')) ||
+                            dn.startsWith(new LdapName('ou=midpoint,ou=Groups,dc=internet2,dc=edu'))
+                    </code>
+                </script>
+            </condition>
+            <correlation>
+                <q:equal>
+                    <q:path>extension/ldapDn</q:path>
+                    <expression>
+                        <path>$shadow/attributes/ri:dn</path>
+                    </expression>
+                </q:equal>
+            </correlation>
+            <reaction>
+                <situation>linked</situation>
+                <synchronize>true</synchronize>
+            </reaction>
+            <reaction>
+                <situation>deleted</situation>
+                <synchronize>true</synchronize>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                </action>
+            </reaction>
+            <reaction>
+                <situation>unlinked</situation>
+                <synchronize>true</synchronize>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                </action>
+            </reaction>
+            <reaction>
+                <situation>unmatched</situation>
+            </reaction>
+        </objectSynchronization>
+	</synchronization>
+    <consistency>
+        <avoidDuplicateValues>true</avoidDuplicateValues>
+    </consistency>
+</resource>
diff --git a/demo/complex0/midpoint-objects/resources/resource-grouper.xml b/demo/complex0/midpoint-objects/resources/resource-grouper.xml
new file mode 100644
index 0000000..0e0f802
--- /dev/null
+++ b/demo/complex0/midpoint-objects/resources/resource-grouper.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<resource oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233"
+		  xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+          xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+          xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+          xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+          xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+		  xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+		  xmlns:rest="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-grouper-rest/com.evolveum.polygon.connector.grouper.rest.GrouperConnector"
+		  xmlns:conf="http://midpoint.evolveum.com/xml/ns/public/connector/builtin-1/bundle/com.evolveum.midpoint.provisioning.ucf.impl.builtin.async/AsyncUpdateConnector"
+          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+    <name>Grouper Resource</name>
+    <connectorRef type="c:ConnectorType">
+        <filter>
+            <q:equal>
+                <q:path>connectorType</q:path>
+                <q:value>com.evolveum.polygon.connector.grouper.rest.GrouperConnector</q:value>
+            </q:equal>
+        </filter>
+    </connectorRef>
+    <connectorConfiguration>
+        <icfc:configurationProperties>
+            <rest:baseUrl>https://grouper-ws:443</rest:baseUrl>
+            <rest:username>banderson</rest:username>
+            <rest:password>password</rest:password>
+            <rest:superGroup>etc:midpointGroups</rest:superGroup>
+            <rest:groupIncludePattern>midpoint:.*</rest:groupIncludePattern>
+            <rest:groupIncludePattern>app:.*</rest:groupIncludePattern>
+            <rest:groupIncludePattern>test:.*</rest:groupIncludePattern>
+            <rest:groupIncludePattern>ref:.*</rest:groupIncludePattern>
+            <rest:groupExcludePattern>.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)</rest:groupExcludePattern>
+            <rest:subjectSource>ldap</rest:subjectSource>
+            <rest:groupSource>g:gsa</rest:groupSource>
+            <rest:ignoreSslValidation>true</rest:ignoreSslValidation>
+            <rest:exportStem>:</rest:exportStem>
+        </icfc:configurationProperties>
+    </connectorConfiguration>
+        <additionalConnector>
+        <name>AMQP async update connector</name>
+        <connectorRef type="c:ConnectorType">
+            <filter>
+                <q:equal>
+                    <q:path>connectorType</q:path>
+                    <q:value>AsyncUpdateConnector</q:value>
+                </q:equal>
+            </filter>
+        </connectorRef>
+        <connectorConfiguration>
+            <conf:sources>
+                <amqp091>
+                    <uri>amqp://mq:5672</uri>
+                    <username>guest</username>
+                    <password>guest</password>
+                    <queue>sampleQueue</queue>
+                </amqp091>
+            </conf:sources>
+            <conf:transformExpression>
+                <script>
+                    <code>
+                        // ------------------ START OF CONFIGURATION ------------------
+
+                        parameters = [
+                            superGroup: 'etc:midpointGroups',
+                            groupIncludePattern: [ 'midpoint:.*', 'app:.*', 'test:.*', 'ref:.*' ],
+                            groupExcludePattern: [ '.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)' ],
+                            relevantSourceId: 'ldap'
+                        ]
+
+                        // ------------------ END OF CONFIGURATION ------------------
+
+                        parameters.put('message', message)
+                        grouper.execute('createUcfChange', parameters)
+                    </code>
+                </script>
+            </conf:transformExpression>
+        </connectorConfiguration>
+    </additionalConnector>
+    <schemaHandling>
+        <objectType>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <objectClass>ri:CustomPlainGroupObjectClass</objectClass>
+            <default>true</default>
+            <attribute>
+                <ref>icfs:name</ref>
+                <inbound>
+                    <strength>strong</strength>
+                    <target>
+                        <path>extension/grouperName</path>
+                    </target>
+                </inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>
+                                import com.evolveum.midpoint.schema.util.*
+                                import com.evolveum.midpoint.schema.constants.*
+                                
+                                if (input == null) {
+                                    null
+                                } else {
+                                    archetypeOid = '5f2b96d2-49b5-4a8a-9601-14457309a69b'       // generic-grouper-group archetype
+                                    switch (input) {
+                                        case ~/ref:affiliation:.*/: archetypeOid = '56f53812-047d-4b69-83e8-519a73d161e1'; break;   // affiliation archetype
+                                        case ~/ref:dept:.*/: archetypeOid = '1cec5f78-8fba-459b-9547-ef7485009f40'; break;          // department archetype
+                                        case ~/ref:course:.*/: archetypeOid = '3dab9a72-118b-4e40-a138-bb691c335eca'; break;        // course archetype
+                                        case ~/app:mailinglist:.*/: archetypeOid = '1645d1dc-1f7c-4508-b50b-97b501ccdee3'; break;   // mailing-list archetype
+                                    }
+                                    ObjectTypeUtil.createAssignmentTo(archetypeOid, ObjectTypes.ARCHETYPE, prismContext)
+                                }
+                            </code>
+                        </script>
+                    </expression>
+                    <target>
+                        <path>assignment</path>
+                        <set>
+                            <predefined>all</predefined>    <!--  we tolerate no other assignments -->
+                        </set>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:member</ref>
+                <fetchStrategy>explicit</fetchStrategy>
+                <storageStrategy>indexOnly</storageStrategy>
+            </attribute>
+        </objectType>
+    </schemaHandling>
+    <synchronization>
+        <objectSynchronization>
+            <enabled>true</enabled>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <objectClass>ri:CustomPlainGroupObjectClass</objectClass>
+            <focusType>OrgType</focusType>
+            <correlation>
+                <q:equal>
+                    <q:path>extension/grouperName</q:path>
+                    <expression>
+                        <path>
+                            $account/attributes/name
+                        </path>
+                    </expression>
+                </q:equal>
+            </correlation>
+            <reaction>
+                <situation>linked</situation>
+                <channel>http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#asyncUpdate</channel>
+                <synchronize>false</synchronize>
+            </reaction>
+            <reaction>
+                <situation>linked</situation>
+                <synchronize>true</synchronize>
+            </reaction>
+            <reaction>
+                <situation>deleted</situation>
+                <!-- a separate task will take care of deleted groups -->
+                <!-- we don't even need to unlink the shadow -->
+                <synchronize>true</synchronize>
+            </reaction>
+            <reaction>
+                <situation>unlinked</situation>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                </action>
+            </reaction>
+            <reaction>
+                <situation>unmatched</situation>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+                </action>
+            </reaction>
+        </objectSynchronization>
+    </synchronization>
+    <caching>
+        <cachingStategy>passive</cachingStategy>
+    </caching>
+</resource>
diff --git a/demo/complex0/midpoint-objects/resources/scriptedsql-sis-persons.xml b/demo/complex0/midpoint-objects/resources/scriptedsql-sis-persons.xml
new file mode 100644
index 0000000..e47a0a7
--- /dev/null
+++ b/demo/complex0/midpoint-objects/resources/scriptedsql-sis-persons.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="4d70a0da-02dd-41cf-b0a1-00e75d3eaa15"
+    xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+    xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+    xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+    xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
+    xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+
+	<c:name>SQL SIS persons (sources)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>connectorType</q:path>
+				<q:value>net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<c:connectorConfiguration>
+
+		<icfc:configurationProperties 
+			xmlns:icscscriptedsql="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/net.tirasa.connid.bundles.db.scriptedsql/net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector">
+			<icscscriptedsql:host>sources</icscscriptedsql:host>
+			<icscscriptedsql:port>3306</icscscriptedsql:port>
+			<icscscriptedsql:quoting></icscscriptedsql:quoting>
+			<icscscriptedsql:user>root</icscscriptedsql:user>
+			<icscscriptedsql:password>
+				<clearValue>123321</clearValue>
+			</icscscriptedsql:password>
+			<icscscriptedsql:database>sis</icscscriptedsql:database>
+			<!-- >icscscriptedsql:clearTextPasswordToScript>true</icscscriptedsql:clearTextPasswordToScript -->
+			<icscscriptedsql:scriptingLanguage>GROOVY</icscscriptedsql:scriptingLanguage>
+
+			<icscscriptedsql:searchScriptFileName>/opt/midpoint/var/res/sis-persons/SearchScript.groovy</icscscriptedsql:searchScriptFileName>
+			<icscscriptedsql:testScriptFileName>/opt/midpoint/var/res/sis-persons/TestScript.groovy</icscscriptedsql:testScriptFileName>
+			<icscscriptedsql:schemaScriptFileName>/opt/midpoint/var/res/sis-persons/SchemaScript.groovy</icscscriptedsql:schemaScriptFileName>
+			
+			<icscscriptedsql:reloadScriptOnExecution>false</icscscriptedsql:reloadScriptOnExecution>
+			<!-- >icscscriptedsql:syncScriptFileName>/opt/midpoint/var/res/SyncScript.groovy</icscscriptedsql:syncScriptFileName -->
+
+			<icscscriptedsql:validConnectionQuery></icscscriptedsql:validConnectionQuery>
+			<icscscriptedsql:jndiProperties></icscscriptedsql:jndiProperties>
+
+			<icscscriptedsql:jdbcDriver>org.mariadb.jdbc.Driver</icscscriptedsql:jdbcDriver>
+			<icscscriptedsql:jdbcUrlTemplate>jdbc:mysql://%h:%p/%d?useUnicode=true&amp;characterEncoding=utf8&amp;connectionCollation=utf8_bin</icscscriptedsql:jdbcUrlTemplate>
+			<icscscriptedsql:enableEmptyString>true</icscscriptedsql:enableEmptyString>
+			<icscscriptedsql:rethrowAllSQLExceptions>true</icscscriptedsql:rethrowAllSQLExceptions>
+			<icscscriptedsql:nativeTimestamps>false</icscscriptedsql:nativeTimestamps>
+			<icscscriptedsql:allNative>false</icscscriptedsql:allNative>
+			<!--<icscscriptedsql:changeLogColumn>timestamp</icscscriptedsql:changeLogColumn> -->
+			<icscscriptedsql:datasource></icscscriptedsql:datasource>
+		</icfc:configurationProperties>
+
+		<!-- Generic ICF configuration -->
+
+	</c:connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<kind>account</kind>
+			<displayName>Normal Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<displayName>UID</displayName>
+                <inbound>
+                    <target>
+                        <path>name</path>
+                    </target>
+                </inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <assignmentTargetSearch>
+                            <targetType>RoleType</targetType>
+                            <oid>c89f31dd-8d4f-4e0a-82cb-58ff9d8c1b2f</oid>     <!--  role-ldap-basic -->
+                            <assignmentProperties>
+                                <subtype>grouper-basic</subtype>
+                            </assignmentProperties>
+                        </assignmentTargetSearch>
+                    </expression>                            
+                    <target>
+                        <path>assignment</path>
+                        <set>
+                            <condition>
+                                <script>
+                                    <code>
+                                        assignment.subtype.contains('grouper-basic')
+                                    </code>
+                                </script>
+                            </condition>
+                        </set>
+                    </target>
+                </inbound>
+			</attribute>
+            <attribute>
+                <ref>ri:fullName</ref>
+                <displayName>Full Name</displayName>
+                <inbound>
+                    <target>
+                        <path>fullName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:surname</ref>
+                <displayName>Surname</displayName>
+                <inbound>
+                    <target>
+                        <path>familyName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <displayName>Given Name</displayName>
+                <inbound>
+                    <target>
+                        <path>givenName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:mail</ref>
+                <displayName>Mail</displayName>
+                <matchingRule>mr:stringIgnoreCase</matchingRule>
+                <inbound>
+                    <target>
+                        <path>emailAddress</path>
+                    </target>
+                </inbound>
+            </attribute>
+		</objectType>
+	</schemaHandling>
+
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
+							$account/attributes/ri:uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+				</action>
+			</reaction>
+
+			<reaction>
+				<situation>unlinked</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+
+</c:resource>
+
diff --git a/demo/complex0/midpoint-objects/resources/target-cs-portal.xml b/demo/complex0/midpoint-objects/resources/target-cs-portal.xml
new file mode 100644
index 0000000..2a4f239
--- /dev/null
+++ b/demo/complex0/midpoint-objects/resources/target-cs-portal.xml
@@ -0,0 +1,118 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Computer science portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/cs-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>identifier</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:identifier</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:name</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:courses</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-course -->
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/identifier
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex0/midpoint-objects/resources/target-faculty-portal.xml b/demo/complex0/midpoint-objects/resources/target-faculty-portal.xml
new file mode 100644
index 0000000..94d54d0
--- /dev/null
+++ b/demo/complex0/midpoint-objects/resources/target-faculty-portal.xml
@@ -0,0 +1,127 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="e417225d-8a08-46f3-9b5d-624990b52386" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Faculty portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/faculty-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>givenName</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:familyName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>familyName</path>
+                    </source>
+                </outbound>
+            </attribute>
+			<attribute>
+				<ref>ri:fullName</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex0/midpoint-objects/resources/target-mailing-lists.xml b/demo/complex0/midpoint-objects/resources/target-mailing-lists.xml
new file mode 100644
index 0000000..19f5460
--- /dev/null
+++ b/demo/complex0/midpoint-objects/resources/target-mailing-lists.xml
@@ -0,0 +1,108 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Mailing lists (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/mailing-lists.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:lists</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-mailing-list -->
+            </attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex0/midpoint-objects/roles/metarole-grouper-provided-group.xml b/demo/complex0/midpoint-objects/roles/metarole-grouper-provided-group.xml
new file mode 100644
index 0000000..1274be7
--- /dev/null
+++ b/demo/complex0/midpoint-objects/roles/metarole-grouper-provided-group.xml
@@ -0,0 +1,192 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90">
+    <name>metarole-grouper-provided-group</name>
+    <description>A metarole for archetyped Grouper-provided groups</description>
+    <!-- 
+        This metarole arranges everything that is needed for a Grouper group to live in midPoint.
+        The schema is the following:
+        
+        Grouper group -> shadow -> org -> archetype -> this metarole
+        
+        e.g.
+        
+        ref:affiliation:member -> shadow -> affiliation_member -> affiliation (archetype) -> metarole-grouper-provided-group 
+            
+        1) Grouper group (e.g. ref:affiliation:member) has a shadow object.
+        
+        2) An org object (affiliation_member) is created and linked to this shadow.
+        
+        3) At the same time, appropriate archetype is assigned to the org, based on the Grouper name 
+        (e.g. ref:affiliation:* leads to archetype affiliation).
+        
+        4) This archetype defines basic parameters for the particular class of Grouper groups; e.g. where in midPoint
+        org tree they belong (e.g. under Affiliations org), where in LDAP tree they belong (e.g. under 
+        ou=Affiliations,ou=Groups,dc=internet2,dc=edu), what's the schema for their midPoint name
+        (e.g. affiliation_...) and displayName (e.g. Affiliation: ...).
+        
+        5) To avoid code duplication, these archetypes delegate specific processing
+        (i.e. filling-in appropriate properties of org objects) to metaroles:
+        to this one as well as to metarole-ldap-group.
+        
+        This metarole is devoted to process Grouper-specific information for Grouper groups.
+        As a source it needs only two pieces of information: extension/grouperName (e.g. ref:affiliation:member)
+        and particular archetype (e.g. affiliation) with its configuration data.
+        
+        It fills-in the following items: extension/grouperName -> identifier -> name and displayName
+        by inducing appropriate focus mappings to the org object.    
+         -->
+    <inducement>
+        <focusMappings>
+            <mapping>
+                <name>identifier</name>
+                <description>This mapping fills-in org identifier (e.g. 'member') from extension/grouperName (e.g. 'ref:affiliation:member').
+                It uses extension/grouperNamePrefix information from the archetype (e.g. 'ref:affiliation:' defined in affiliation archetype)</description>
+                <strength>strong</strength>
+                <source>
+                    <path>extension/grouperName</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (grouperName == null) {
+                                null
+                            } else {
+                                archetype = assignmentPath[-2].source       // e.g. archetype affiliation
+                                log.info('archetype = {}', archetype)
+                                if (archetype == null) {
+                                    throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
+                                }
+                                grouperNamePrefix = basic.getExtensionPropertyValue(archetype, 'grouperNamePrefix')      // e.g. 'ref:affiliation:'
+                                if (grouperNamePrefix == null) {
+                                    throw new IllegalStateException('No grouper name prefix in archetype ' + archetype)
+                                }
+                                // grouperName is e.g. 'ref:affiliation:member'
+                                if (grouperName.startsWith(grouperNamePrefix)) {
+                                    grouperName.substring(grouperNamePrefix.length())       // returning e.g. 'member'                                
+                                } else {
+                                    throw new IllegalStateException('Grouper name ' + grouperName + ' does not match the expected prefix: ' + grouperNamePrefix)
+                                }
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>identifier</path>
+                </target>
+            </mapping>
+
+            <mapping>
+                <name>name</name>
+                <description>This mapping fills-in org name (e.g. 'affiliation_member') from identifier (e.g. 'member').
+                It uses extension/midPointNamePrefix information from the archetype (e.g. 'affiliation_' defined in affiliation archetype)</description>
+                <strength>strong</strength>
+                <source>
+                    <path>identifier</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (identifier == null) {
+                                null
+                            } else {
+                                // e.g. identifier = 'member'
+                                archetype = assignmentPath[-2].source         // e.g. affiliation archetype
+                                if (archetype == null) {
+                                    throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
+                                }
+                                prefix = basic.getExtensionPropertyValue(archetype, 'midPointNamePrefix')        // e.g. 'affiliation_'
+                                prefix + identifier                                                             // e.g. 'affiliation_member'
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>name</path>
+                </target>
+            </mapping>
+            
+            <mapping>
+                <name>displayName</name>
+                <description>This mapping fills-in org displayName (e.g. 'Affiliation: member') from identifier (e.g. 'member').
+                It uses extension/midPointDisplayNamePrefix information from the archetype (e.g. 'Affiliation: ' defined in affiliation archetype)</description>
+                <strength>strong</strength>
+                <source>
+                    <path>identifier</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (identifier == null) {
+                                null
+                            } else {
+                                archetype = assignmentPath[-2].source                                                        // e.g. affiliation archetype
+                                if (archetype == null) {
+                                    throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
+                                }
+                                prefix = basic.getExtensionPropertyValue(archetype, 'midPointDisplayNamePrefix')         // e.g. 'Affiliation: '
+                                prefix + identifier                                                                     // e.g. 'Affiliation: member'
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>displayName</path>
+                </target>
+            </mapping>
+
+            <mapping>
+                <name>lifecycle state</name>
+                <description>This mapping sets org lifecycle state to be either "active" or "retired", depending on
+                    whether Grouper group for this org still exists. Orgs in the latter state are on the way to deletion:
+                    their members are unassigned and after no members are there, the org is automatically deleted.</description>
+                <strength>strong</strength>
+                <expression>
+                    <script>
+                        <code>
+                            import com.evolveum.midpoint.model.impl.expr.*
+                            import com.evolveum.midpoint.schema.*
+                            import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+
+                            GROUPER_RESOURCE_OID = '1eff65de-5bb6-483d-9edf-8cc2c2ee0233'
+
+                            modelContext = ModelExpressionThreadLocalHolder.lensContext
+                            rsd = new ResourceShadowDiscriminator(GROUPER_RESOURCE_OID, ShadowKindType.ENTITLEMENT, 'group', null, false)
+                            if (modelContext.findProjectionContext(rsd) != null) {
+                                log.info('Projection context for Grouper group found, marking as "active"')
+                                'active'
+                            } else {
+                                log.info('No projection context for Grouper group, marking as "retired"')
+                                'retired'
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>lifecycleState</path>
+                </target>
+            </mapping>
+        </focusMappings>
+        
+        <!-- 
+            Inducement order of 2 means these mappings are to be applied on org object, because the assignment structure is like this:
+            
+                org -> archetype -> this-metarole
+         -->
+        <order>2</order>
+    </inducement>
+</role>
\ No newline at end of file
diff --git a/demo/complex0/midpoint-objects/roles/metarole-ldap-group.xml b/demo/complex0/midpoint-objects/roles/metarole-ldap-group.xml
new file mode 100644
index 0000000..91bf370
--- /dev/null
+++ b/demo/complex0/midpoint-objects/roles/metarole-ldap-group.xml
@@ -0,0 +1,128 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a">
+    <name>metarole-ldap-group</name>
+    <description>A metarole for archetyped LDAP groups</description>
+    <!--
+        This metarole supports LDAP groups that correspond to appropriately archetyped
+        org objects.
+        
+        The schema is the following:
+        
+        org -> archetype -> this metarole
+        
+        e.g.
+        
+        affiliation_member -> archetype affiliation -> metarole-ldap-group
+        or org-grouper-sysadmin -> archetype midpoint-group -> metarole-ldap-group   
+            
+        1) An org has appropriate archetype e.g. affiliation_member has an archetype of affiliation;
+        org-grouper-sysadmin has an archetype of midpoint-group.
+        
+        2) This archetype defines LDAP root the particular class of orgs e.g.  
+        ou=Affiliations,ou=Groups,dc=internet2,dc=edu for affiliations or
+        ou=midpoint,ou=Groups,dc=internet2,dc=edu for midPoint-defined groups.
+        
+        3) To avoid code duplication, these archetypes delegate everything related
+        to LDAP to this metarole.
+        
+        This metarole does the three things:
+        
+        1) It ensures that extension/ldapDn is filled in for particular org object.
+        This property is then used by LDAP resource outbound mappings to provide
+        a value for ri:dn attribute.
+        
+        The value of extension/ldapDn is determined as 
+        
+        cn=identifier (in org) + ldapRootDn (in archetype)
+        
+        2) It ensures that appropriate group object is created in LDAP.
+        This is done by inducing a construction with kind=entitlement,
+        intent=group to the org object (i.e. inducement order=2).
+        
+        3) It ensures that appropriate group membership is created in LDAP
+        for any user that has an assignment to the org object. This is done
+        by inducing a construction with default kind and intent (i.e. regular
+        account) to the user that has assigned the org object (i.e. inducement order=3).
+     --> 
+
+    <!--  Fills-in extension/ldapDn in org object -->
+    <inducement>
+        <focusMappings>
+            <mapping>
+                <name>ldapDn</name>
+                <strength>strong</strength>
+                <source>
+                    <path>identifier</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (identifier == null) {
+                                null
+                            } else {
+                                // identifier = e.g. 'member'
+                                metarole = assignmentPath[-2].source        // e.g. metarole-affiliation
+                                log.info('metarole = {}', metarole)
+                                if (metarole == null) {
+                                    throw new IllegalStateException('No metarole in assignment path: ' + assignmentPath)
+                                }
+                                'cn=' + identifier + ',' + basic.getExtensionPropertyValue(metarole, 'ldapRootDn')
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>extension/ldapDn</path>
+                </target>
+            </mapping>
+        </focusMappings>
+        <order>2</order>        <!--  order=2 means the org object: org->archetype->metarole -->
+    </inducement>
+     
+    <!--  Provides LDAP group for the org object -->
+    <inducement>
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />    
+            <kind>entitlement</kind>
+            <intent>group</intent>
+        </construction>
+        <order>2</order>        <!--  order=2 means the org object: org->archetype->metarole -->
+    </inducement>
+    
+    <!--  Provides LDAP group membership for the org object members (users) -->
+    <inducement>
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />    
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>group</intent>
+                            </projectionDiscriminator>
+                            <assignmentPathIndex>1</assignmentPathIndex>        <!--  derive from the immediately assigned org -->
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>3</order>        <!--  order=3 means the user object; user has an assignment to the org: user->org->archetype->metarole -->
+    </inducement>
+</role>
diff --git a/demo/complex0/midpoint-objects/roles/role-ldap-basic.xml b/demo/complex0/midpoint-objects/roles/role-ldap-basic.xml
new file mode 100644
index 0000000..731f024
--- /dev/null
+++ b/demo/complex0/midpoint-objects/roles/role-ldap-basic.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="c89f31dd-8d4f-4e0a-82cb-58ff9d8c1b2f">
+    <name>role-ldap-basic</name>
+    <inducement id="1">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- LDAP -->
+        </construction>
+        <order>1</order>
+    </inducement>
+</role>
diff --git a/demo/complex0/midpoint-objects/systemConfigurations/SystemConfiguration.xml b/demo/complex0/midpoint-objects/systemConfigurations/SystemConfiguration.xml
new file mode 100644
index 0000000..de75d62
--- /dev/null
+++ b/demo/complex0/midpoint-objects/systemConfigurations/SystemConfiguration.xml
@@ -0,0 +1,257 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<systemConfiguration xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oid="00000000-0000-0000-0000-000000000001" version="2">
+    <name>SystemConfiguration</name>
+    <globalSecurityPolicyRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="00000000-0000-0000-0000-000000000120" relation="org:default" type="tns:SecurityPolicyType"/>
+    <logging>
+        <classLogger id="1">
+            <level>ERROR</level>
+            <package>ro.isdc.wro.extensions.processor.css.Less4jProcessor</package>
+        </classLogger>
+        <classLogger id="2">
+            <level>OFF</level>
+            <package>org.hibernate.engine.jdbc.spi.SqlExceptionHelper</package>
+        </classLogger>
+        <classLogger id="3">
+            <level>OFF</level>
+            <package>org.hibernate.engine.jdbc.batch.internal.BatchingBatch</package>
+        </classLogger>
+        <classLogger id="4">
+            <level>WARN</level>
+            <package>org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl</package>
+        </classLogger>
+        <classLogger id="5">
+            <level>OFF</level>
+            <package>org.hibernate.internal.ExceptionMapperStandardImpl</package>
+        </classLogger>
+        <classLogger id="6">
+            <level>OFF</level>
+            <package>net.sf.jasperreports.engine.fill.JRFillDataset</package>
+        </classLogger>
+        <classLogger id="7">
+            <level>WARN</level>
+            <package>org.apache.wicket.resource.PropertiesFactory</package>
+        </classLogger>
+        <classLogger id="8">
+            <level>ERROR</level>
+            <package>org.springframework.context.support.ResourceBundleMessageSource</package>
+        </classLogger>
+        <classLogger id="9">
+            <level>INFO</level>
+            <package>com.evolveum.midpoint.model.impl.lens.projector.Projector</package>
+        </classLogger>
+        <classLogger id="10">
+            <level>INFO</level>
+            <package>com.evolveum.midpoint.model.impl.lens.Clockwork</package>
+        </classLogger>
+        <appender id="11" xsi:type="c:FileAppenderConfigurationType">
+            <pattern>%date [%X{subsystem}] [%thread] %level \(%logger\): %msg%n</pattern>
+            <name>MIDPOINT_LOG</name>
+            <fileName>${midpoint.home}/log/midpoint.log</fileName>
+            <filePattern>${midpoint.home}/log/midpoint-%d{yyyy-MM-dd}.%i.log</filePattern>
+            <maxHistory>10</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <append>true</append>
+        </appender>
+        <appender id="12" xsi:type="c:FileAppenderConfigurationType">
+            <pattern>%date %level: %msg%n</pattern>
+            <name>MIDPOINT_PROFILE_LOG</name>
+            <fileName>${midpoint.home}/log/midpoint-profile.log</fileName>
+            <filePattern>${midpoint.home}/log/midpoint-profile-%d{yyyy-MM-dd}.%i.log</filePattern>
+            <maxHistory>10</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <append>true</append>
+        </appender>
+        <rootLoggerAppender>MIDPOINT_LOG</rootLoggerAppender>
+        <rootLoggerLevel>INFO</rootLoggerLevel>
+        <auditing>
+            <enabled>false</enabled>
+            <details>false</details>
+        </auditing>
+    </logging>
+    <defaultObjectPolicyConfiguration id="101">
+        <type>UserType</type>
+        <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="8098b124-c20c-4965-8adf-e528abedf7a4" relation="org:default" type="tns:ObjectTemplateType"/>
+    </defaultObjectPolicyConfiguration>
+    <defaultObjectPolicyConfiguration>
+        <type>OrgType</type>
+        <lifecycleStateModel>
+            <state>
+                <name>retired</name>
+                <!-- object in this model is active but on its way to deletion -->
+            </state>
+        </lifecycleStateModel>
+    </defaultObjectPolicyConfiguration>
+    <cleanupPolicy>
+        <auditRecords>
+            <maxAge>P3M</maxAge>
+        </auditRecords>
+        <closedTasks>
+            <maxAge>P1M</maxAge>
+        </closedTasks>
+    </cleanupPolicy>
+    <internals>
+        <enableExperimentalCode>true</enableExperimentalCode>
+        <operationExecutionRecording>
+            <skipWhenSuccess>true</skipWhenSuccess>
+        </operationExecutionRecording>
+        <focusConstraintsChecking>
+            <skipWhenNoChange>true</skipWhenNoChange>
+            <skipWhenNoIteration>true</skipWhenNoIteration>
+        </focusConstraintsChecking>
+        <projectionConstraintsChecking>
+            <skipWhenNoChange>true</skipWhenNoChange>
+            <skipWhenNoIteration>true</skipWhenNoIteration>
+        </projectionConstraintsChecking>
+        <synchronizationSituationUpdating>
+            <skipWhenNoChange>true</skipWhenNoChange>
+        </synchronizationSituationUpdating>
+        <caching>
+            <profile>
+                <global>true</global>
+                <localRepoCache>
+                    <statistics>
+                        <classification>perCacheAndObjectType</classification>
+                    </statistics>
+                </localRepoCache>
+                <globalRepoCache>
+                    <timeToLive>60</timeToLive>
+                    <objectTypeSettings>
+                        <objectType>SystemConfigurationType</objectType>
+                        <objectType>ArchetypeType</objectType>
+                        <objectType>ObjectTemplateType</objectType>
+                        <objectType>SecurityPolicyType</objectType>
+                        <objectType>ValuePolicyType</objectType>
+                        <objectType>ResourceType</objectType>
+                        <objectType>RoleType</objectType>
+                        <objectType>OrgType</objectType>
+                        <objectType>ServiceType</objectType>
+                        <objectType>ShadowType</objectType>
+                    </objectTypeSettings>
+                    <statistics>
+                        <classification>perCacheAndObjectType</classification>
+                    </statistics>
+                </globalRepoCache>
+            </profile>
+        </caching>
+        <repository>
+            <statistics>
+                <classification>perOperationAndObjectType</classification>
+            </statistics>
+        </repository>
+        <tracing>
+            <profile>
+                <name>performance</name>
+                <displayName>Performance tracing</displayName>
+                <visible>true</visible>
+                <default>true</default>
+                <fileNamePattern>performance-trace %{timestamp} %{focusName} %{milliseconds}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+            </profile>
+            <profile>
+                <name>functional</name>
+                <displayName>Functional tracing</displayName>
+                <visible>true</visible>
+                <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+                <collectLogEntries>true</collectLogEntries>
+                <tracingTypeProfile>
+                    <level>normal</level>
+                </tracingTypeProfile>
+            </profile>
+            <profile>
+                <name>functional-model-logging</name>
+                <displayName>Functional tracing (with model logging)</displayName>
+                <visible>true</visible>
+                <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+                <collectLogEntries>true</collectLogEntries>
+                <loggingOverride>
+                    <levelOverride>
+                        <logger>com.evolveum.midpoint.model</logger>
+                        <level>TRACE</level>
+                    </levelOverride>
+                </loggingOverride>
+                <tracingTypeProfile>
+                    <level>normal</level>
+                </tracingTypeProfile>
+            </profile>
+            <profile>
+                <name>functional-sql-logging</name>
+                <displayName>Functional tracing (with SQL logging)</displayName>
+                <visible>true</visible>
+                <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+                <collectLogEntries>true</collectLogEntries>
+                <loggingOverride>
+                    <levelOverride>
+                        <logger>org.hibernate.SQL</logger>
+                        <level>TRACE</level>
+                    </levelOverride>
+                </loggingOverride>
+                <tracingTypeProfile>
+                    <level>normal</level>
+                </tracingTypeProfile>
+            </profile>
+        </tracing>
+    </internals>
+    <deploymentInformation>
+        <name>demo/complex2s</name>
+    </deploymentInformation>
+    <adminGuiConfiguration>
+        <userDashboardLink id="13">
+            <targetUrl>/self/profile</targetUrl>
+            <label>Profile</label>
+            <description>View/edit your profile</description>
+            <icon>
+                <cssClass>fa fa-user</cssClass>
+            </icon>
+            <color>green</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfProfile</authorization>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll</authorization>
+        </userDashboardLink>
+        <userDashboardLink id="14">
+            <targetUrl>/self/credentials</targetUrl>
+            <label>Credentials</label>
+            <description>View/edit your credentials</description>
+            <icon>
+                <cssClass>fa fa-shield</cssClass>
+            </icon>
+            <color>blue</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfCredentials</authorization>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll</authorization>
+        </userDashboardLink>
+        <userDashboardLink id="15">
+            <targetUrl>/admin/users</targetUrl>
+            <label>List users</label>
+            <icon>
+                <cssClass>fa fa-users</cssClass>
+            </icon>
+            <color>red</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#users</authorization>
+        </userDashboardLink>
+        <userDashboardLink id="16">
+            <targetUrl>/admin/resources</targetUrl>
+            <label>List resources</label>
+            <icon>
+                <cssClass>fa fa-database</cssClass>
+            </icon>
+            <color>purple</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#resources</authorization>
+        </userDashboardLink>
+        <enableExperimentalFeatures>true</enableExperimentalFeatures>
+    </adminGuiConfiguration>
+    <workflowConfiguration>
+        <useLegacyApproversSpecification>never</useLegacyApproversSpecification>
+        <useDefaultApprovalPolicyRules>never</useDefaultApprovalPolicyRules>
+    </workflowConfiguration>
+</systemConfiguration>
diff --git a/demo/complex0/midpoint-objects/tasks/task-group-scavenger.xml b/demo/complex0/midpoint-objects/tasks/task-group-scavenger.xml
new file mode 100644
index 0000000..60f9852
--- /dev/null
+++ b/demo/complex0/midpoint-objects/tasks/task-group-scavenger.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<!--
+
+Looks for groups with the lifecycleState of 'retired' and completes their deletion:
+ - unassigns all the users (simply by recomputing them)
+
+-->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	  xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+	  xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3"
+	  oid="1d7bef40-953e-443e-8e9a-ec6e313668c4">
+	<name>Group Scavenger</name>
+	<extension>
+		<scext:executeScript>
+			<s:action>
+				<s:type>execute-script</s:type>
+				<s:parameter>
+					<s:name>script</s:name>
+					<c:value xsi:type="c:ScriptExpressionEvaluatorType">
+						<c:code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+
+						result = midpoint.currentResult
+						log.info('Processing dead group: {}', input)
+						query = prismContext.queryFor(UserType.class)
+								.item(UserType.F_ROLE_MEMBERSHIP_REF).ref(input.oid)
+								.build()
+						members = midpoint.repositoryService.searchObjects(UserType.class, query, null, result)
+						log.info('Found {} members: {}', members.size(), members)
+
+						for (member in members) {
+							log.info('Going to recompute {}', member)
+							try {
+								midpoint.recompute(UserType.class, member.oid)
+							} catch (Throwable t) {
+								log.error('Couldn\'t recompute {}: {}', member, t.message, t)
+							}
+						}
+						log.info('Members recomputed; checking if the org is still in "retired" state')
+						orgAfter = midpoint.repositoryService.getObject(OrgType.class, input.oid, null, result)
+						currentState = orgAfter.asObjectable().lifecycleState
+						log.info('Current state = {}', currentState)
+						if (currentState == 'retired') {
+							log.info('Deleting the org: {}', orgAfter)
+							midpoint.deleteObject(OrgType.class, orgAfter.oid, null)
+						} else {
+							log.info('State has changed, not deleting the org: {}', orgAfter)
+						}
+						log.info('Dead group processing done: {}', input)
+						</c:code>
+					</c:value>
+				</s:parameter>
+			</s:action>
+		</scext:executeScript>
+		<mext:objectType>OrgType</mext:objectType>
+		<mext:objectQuery>
+			<q:filter>
+				<q:equal>
+					<q:path>lifecycleState</q:path>
+					<q:value>retired</q:value>
+				</q:equal>
+			</q:filter>
+		</mext:objectQuery>
+	</extension>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002"/>
+	<executionStatus>runnable</executionStatus>
+	<category>BulkActions</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/iterative-scripting/handler-3</handlerUri>
+	<recurrence>recurring</recurrence>
+	<schedule>
+		<interval>60</interval>
+	</schedule>
+</task>
diff --git a/demo/complex0/midpoint-objects/users/user-banderson.xml b/demo/complex0/midpoint-objects/users/user-banderson.xml
new file mode 100644
index 0000000..10197ea
--- /dev/null
+++ b/demo/complex0/midpoint-objects/users/user-banderson.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      oid="e897468f-20bd-419c-8fc5-1fe60e2600de">
+    <name>banderson</name>
+    <assignment id="1">
+        <targetRef oid="d48ec05b-fffd-4262-acd3-d9ff63365b62" relation="org:default" type="c:OrgType">
+            <!-- org-grouper-sysadmin -->
+        </targetRef>
+    </assignment>
+    <fullName>Bob Anderson</fullName>
+    <givenName>Bob</givenName>
+    <familyName>Anderson</familyName>
+    <credentials>
+        <password>
+            <value>password</value>
+        </password>
+    </credentials>
+</user>
+	
diff --git a/demo/complex0/midpoint_server/Dockerfile b/demo/complex0/midpoint_server/Dockerfile
new file mode 100644
index 0000000..43dac56
--- /dev/null
+++ b/demo/complex0/midpoint_server/Dockerfile
@@ -0,0 +1,9 @@
+FROM tier/midpoint:laboratory
+
+MAINTAINER info@evolveum.com
+
+ENV MP_DIR /opt/midpoint
+
+VOLUME ${MP_DIR}/var
+
+COPY container_files/mp-home/ ${MP_DIR}/var/
diff --git a/demo/complex0/midpoint_server/container_files/httpd/host-cert.pem b/demo/complex0/midpoint_server/container_files/httpd/host-cert.pem
new file mode 100644
index 0000000..9b1021b
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/httpd/host-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAMOSkn4oS2aAMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXbWlkcG9pbnQuc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU1OTQ1WhcNMTkwOTE0MDU1OTQ1WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF21pZHBvaW50LnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApj/b7MEUSfu3oXMfNgRwTse7
+a5UV7Jswf1M/ZN/ZZkAkIxNBevZgozjesvLPWrmsTgONi7XigJUJvCjdjmlW9eDM
+lri/rkD8HuOR1DQCVKL9nvoS2c3D7sq5Emda3V8Tlj82VqfEmePd3sajx7mcTfbH
+8jwAL9NhkC+WMib5IpjLGpG0FEAC0ha7Lxb+7jIiqHVJaqLXJGCyGN4mh6c1Q9S1
+f8RVTiW2a8x22G+9wnZYbkiA2Kxls177imHlhSz8EdvV4IpGw1amrEWhhuDEum7B
+vZ1xQDLatgRqh4qAKLIVYeRnJ8H1FelMa90qB4G08MIPifmTsQwqJyBYaEdgWQID
+AQABo1MwUTAdBgNVHQ4EFgQUqb9BteODF6wv5R57aEON/wGXMiowHwYDVR0jBBgw
+FoAUqb9BteODF6wv5R57aEON/wGXMiowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAAcKhxI+tSItrXmqC0PSmgWyAYpqbkz6W/cefTutXqhIgY09f
+h0LSv7ogTahoGpyiZk9vy6u3OE9bYwxapEfa4KBjO6HxBMIVBBb3RegVjoPzjElN
+BDwAx0VGFcZTXwMxDWycWdG8ql7rCZBvS50w04uTaIgnGmqXAdWWmBgfJ9cRbxW+
+JwO/mOl1QM1lR/5142NpvuUVWlmZSKEGydE5A1qPz2wpDbBR1ym1BQNS4NEqw6Kp
+GSB8jKyCS1Ve0v2wVze2038Wukz02dq9uKPTIO3T+B+ibZmxn6Op/kFCc1/kK5NS
+Q6JdO1B6KquGAYdGmKAcQ19mv+jqGktqWEEf0g==
+-----END CERTIFICATE-----
diff --git a/demo/complex0/midpoint_server/container_files/httpd/host-key.pem b/demo/complex0/midpoint_server/container_files/httpd/host-key.pem
new file mode 100644
index 0000000..5746e59
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmP9vswRRJ+7eh
+cx82BHBOx7trlRXsmzB/Uz9k39lmQCQjE0F69mCjON6y8s9auaxOA42LteKAlQm8
+KN2OaVb14MyWuL+uQPwe45HUNAJUov2e+hLZzcPuyrkSZ1rdXxOWPzZWp8SZ493e
+xqPHuZxN9sfyPAAv02GQL5YyJvkimMsakbQUQALSFrsvFv7uMiKodUlqotckYLIY
+3iaHpzVD1LV/xFVOJbZrzHbYb73CdlhuSIDYrGWzXvuKYeWFLPwR29XgikbDVqas
+RaGG4MS6bsG9nXFAMtq2BGqHioAoshVh5GcnwfUV6Uxr3SoHgbTwwg+J+ZOxDCon
+IFhoR2BZAgMBAAECggEAEIRBpjjceiku6jRUwnoYaks/nIWYQwR8AfpUTwJKR/VR
+Yca097Fokm7A+UhUP3A45RtHQb0VPq8P44iv0kk24YCu8r5yFK7SHYOAZnOwU5ZJ
+2jSAEPF3aM7tKh3okhuzB3dKP7u1NZDE5zAW723KUJiW7sL1RcsbY0bHBj6G+9/H
+NplmsjuGt684vRBB0qOBfKF7EiG7mT69tHuNj4gRza9SMY31UtKbZdt2fNY6mp5V
+HscMba7egZP+Ke0pVX4+go9j7K8GG8hYaQDLjrzlPqrxZ2c5X9cC+CRDI/CHuL/s
+V/2yGZJ6n6UabwZoH83RdFrbQ94rU8Hkli6EvxXvMQKBgQDRpheNW5jDG5TfeJKh
+yfKTDQqH2Tk3BsBYYBN7Hf3m7vbkzlxnAKJAoSLmtRMuoeXvI5MrhzaHGsNIUS76
+LDIZnvB7DLUxhFUZsCPkpAA1QHuTWY96oR3PHnPjpk8lSUvtbOPwDLdzVApeFJgZ
+VqMNArZ7AHsK3Kkyi+f4WVQjbQKBgQDLAWiGb5dx6fAM2W6B6HjNmzjBWOuVEXa2
+76to9jzupBZmETfZgxtWUaWUDuNS+f7dtVUTE+p6v/w8clrHEhEZYkqunIOLo/UA
+LFPiuoTfEsWb1rh+nsCjCgy4uimixj/bSkf7NC6NyKTvCygA1mGnVVJUEPegYlDy
+LXCkaKWxHQKBgQCmyHSKL2lrJkEcOwakEU2acNCE3Gno/cT9SYmV83kvQ8JEqmrW
+QqnRsp9aXIljGscapPmKsmnNt5vNp1AxFAHTYh88NRLczsMIyZj0ZwgHVUI6KhC7
+5Psa78YQQBlMt2/g9TSsnuE+rYgF6mpKFiNm0Vasqeg47uzn2mdzqlUGTQKBgE04
+JutkTUY+h1pL5vYxWKpVDfy19z7H2tFxT1FowPrBneeLSyRI88Ac5I/yLdRlVeY9
+0LOmEr5Igwj3MsKgg7KVKfVLgdo/LrW3Jt2Kt3onKNXDkoBPoNUjwH0QC0Boiue+
+VK0gR0kVdm+bXccbxR+im+NwZNE0NLg6Qqu3RredAoGBALuVoqbPPmTCZXYG328H
+bzOs2aiR7BzPSVByV+qG6jW7w03RAnFPJZp7HMU+ViI5VY0wabUscMSvz5163+gM
+4KwY3v9ZjZzZGukIfLuudkdqtaiVOx/KeAC0n+nG21YU+wpZww8gkfHh1/sa2CME
+CWYCgOnmiTHcj83UaTqEXtmv
+-----END PRIVATE KEY-----
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/config.xml b/demo/complex0/midpoint_server/container_files/mp-home/config.xml
new file mode 100644
index 0000000..5a4e0ea
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/config.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2010-2017 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<configuration>
+    <midpoint>
+        <webApplication>
+            <importFolder>${midpoint.home}/import</importFolder>
+        </webApplication>
+        <repository>
+            <repositoryServiceFactoryClass>com.evolveum.midpoint.repo.sql.SqlRepositoryFactory</repositoryServiceFactoryClass>
+            <baseDir>${midpoint.home}</baseDir>
+            <asServer>true</asServer>
+            <enableIndexOnlyItems>true</enableIndexOnlyItems>
+            <enableNoFetchExtensionValuesInsertion>true</enableNoFetchExtensionValuesInsertion>
+            <enableNoFetchExtensionValuesDeletion>true</enableNoFetchExtensionValuesDeletion>
+        </repository>
+        <audit>
+            <auditService>
+                <auditServiceFactoryClass>com.evolveum.midpoint.audit.impl.LoggerAuditServiceFactory</auditServiceFactoryClass>
+            </auditService>
+            <auditService>
+                <auditServiceFactoryClass>com.evolveum.midpoint.repo.sql.SqlAuditServiceFactory</auditServiceFactoryClass>
+            </auditService>
+        </audit>
+        <icf>
+            <scanClasspath>true</scanClasspath>
+            <scanDirectory>${midpoint.home}/icf-connectors</scanDirectory>
+        </icf>
+        <keystore>
+            <keyStorePath>${midpoint.home}/keystore.jceks</keyStorePath>
+            <keyStorePassword>changeit</keyStorePassword>
+            <encryptionKeyAlias>default</encryptionKeyAlias>
+            <!--
+            You can use smaller cipher key size for encryption. For:
+            AES_128 "http://www.w3.org/2001/04/xmlenc#aes128-cbc";
+            AES_256 "http://www.w3.org/2001/04/xmlenc#aes256-cbc";
+            AES_192 "http://www.w3.org/2001/04/xmlenc#aes192-cbc";
+
+            in element <xmlCipher></xmlCipher>
+            By default AES_128 is used. If you change key size, than
+            you must also create secret key in key store with proper key size and change encryptionKeyAlias.
+
+            To generate keystore with keytool use command:
+            keytool -genseckey -alias default -keystore keystore.jceks -storetype jceks -keyalg AES -keysize 128
+
+            secret key password is by default 'midpoint'
+            -->
+        </keystore>
+        <!-- <profilingMode>dynamic</profilingMode> -->
+    </midpoint>
+</configuration>
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/cs-portal.csv b/demo/complex0/midpoint_server/container_files/mp-home/cs-portal.csv
new file mode 100644
index 0000000..02a0c65
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/cs-portal.csv
@@ -0,0 +1 @@
+identifier,name,mail,courses
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/faculty-portal.csv b/demo/complex0/midpoint_server/container_files/mp-home/faculty-portal.csv
new file mode 100644
index 0000000..ce346c5
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/faculty-portal.csv
@@ -0,0 +1 @@
+uid,givenName,familyName,fullName,mail
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar b/demo/complex0/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar
new file mode 100644
index 0000000..88fcb54
Binary files /dev/null and b/demo/complex0/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar differ
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/mailing-lists.csv b/demo/complex0/midpoint_server/container_files/mp-home/mailing-lists.csv
new file mode 100644
index 0000000..780ab04
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/mailing-lists.csv
@@ -0,0 +1 @@
+uid,mail,lists
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy b/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy
new file mode 100644
index 0000000..d133ac1
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy
@@ -0,0 +1,93 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import org.identityconnectors.framework.common.objects.AttributeInfo;
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags;
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder;
+import org.identityconnectors.framework.common.objects.ObjectClassInfo;
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder;
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+// This sample shows how to create 3 basic ObjectTypes: __ACCOUNT__, __GROUP__ and organization.
+// Each of them contains one required attribute and normal String attributes
+
+
+log.info("Entering "+action+" Script");
+
+// --- ACCOUNT ---
+
+uidAIB = new AttributeInfoBuilder("uid", String.class)
+uidAIB.setRequired(true)
+
+accAttrsInfo = new HashSet<AttributeInfo>()
+accAttrsInfo.add(uidAIB.build())
+accAttrsInfo.add(AttributeInfoBuilder.build("surname", String.class))
+accAttrsInfo.add(AttributeInfoBuilder.build("givenName", String.class))
+accAttrsInfo.add(AttributeInfoBuilder.build("fullName", String.class))
+accAttrsInfo.add(AttributeInfoBuilder.build("mail", String.class))
+accAttrsInfo.add(AttributeInfoBuilder.build("department", String.class))
+accAttrsInfo.add(AttributeInfoBuilder.build("affiliation", String.class, [Flags.MULTIVALUED] as Set))
+accAttrsInfo.add(AttributeInfoBuilder.build("course", String.class, [Flags.MULTIVALUED] as Set))
+ociAccount = new ObjectClassInfoBuilder().setType("__ACCOUNT__").addAllAttributeInfo(accAttrsInfo).build()
+builder.defineObjectClass(ociAccount);
+
+// --- DEPARTMENT ---
+
+builder.defineObjectClass(
+    new ObjectClassInfoBuilder()
+        .setType("Department")
+        .addAllAttributeInfo([
+            AttributeInfoBuilder.build("displayName", String.class)
+        ])
+        .build())
+
+// --- AFFILIATION ---
+
+builder.defineObjectClass(
+    new ObjectClassInfoBuilder()
+        .setType("Affiliation")
+        .addAllAttributeInfo([
+            AttributeInfoBuilder.build("displayName", String.class)
+        ])
+        .build())
+
+// --- COURSE ---
+
+builder.defineObjectClass(
+    new ObjectClassInfoBuilder()
+        .setType("Course")
+        .addAllAttributeInfo([
+            AttributeInfoBuilder.build("displayName", String.class)
+        ])
+        .build())
+
+log.info("Schema script done");
+
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy b/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy
new file mode 100644
index 0000000..5a1f572
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy
@@ -0,0 +1,153 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+
+import groovy.sql.Sql
+import groovy.sql.DataSet
+import org.identityconnectors.framework.common.objects.*
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used.
+//
+// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+log.info("Entering "+action+" Script");
+
+def sql = new Sql(connection);
+def result = []
+def where = "";
+def sqlParams = null
+
+switch ( objectClass ) {
+    case "__ACCOUNT__":
+
+    uidColumn = 'uid'
+    nameColumn = 'uid'
+
+    log.info("Building where clause, query {0}, uidcolumn {1}, nameColumn {2}", query, uidColumn, nameColumn)
+
+    String left = query?.get("left")
+    if (left != null) {
+      if (Uid.NAME.equals(left)) {
+          left = uidColumn
+      } else if (Name.NAME.equals(left)) {
+          left = nameColumn
+      }
+
+      String right = query.get("right")
+
+      String operation = query.get("operation")
+      switch (operation) {
+          case "CONTAINS":
+              right = '%' + right + '%'
+              break;
+          case "ENDSWITH":
+              right = '%' + right
+              break;
+          case "STARTSWITH":
+              right = right + '%'
+              break;
+      }
+
+      sqlParams = [:]
+      sqlParams.put(left, right)
+      right = ":" + left
+
+      def engine = new groovy.text.SimpleTemplateEngine()
+
+      def whereTemplates = [
+            CONTAINS          : ' $left ${not ? "not " : ""}like $right',
+            ENDSWITH          : ' $left ${not ? "not " : ""}like $right',
+            STARTSWITH        : ' $left ${not ? "not " : ""}like $right',
+            EQUALS            : ' $left ${not ? "<>" : "="} $right',
+            GREATERTHAN       : ' $left ${not ? "<=" : ">"} $right',
+            GREATERTHANOREQUAL: ' $left ${not ? "<" : ">="} $right',
+            LESSTHAN          : ' $left ${not ? ">=" : "<"} $right',
+            LESSTHANOREQUAL   : ' $left ${not ? ">" : "<="} $right'
+      ]
+
+      def wt = whereTemplates.get(operation)
+      if (wt != null) {
+        def binding = [left: left, right: right, not: query.get("not")]
+        def template = engine.createTemplate(wt).make(binding)
+        where = ' where ' + template.toString()
+        log.info("Where clause: {0}, with parameters {1}", where, sqlParams)
+      } else {
+        log.warn('Unsupported query: {0}, continuing without WHERE clause (worsening the performance)', query)
+        sqlParams = null
+        where = ''
+      }
+    }
+
+    q = 'select uid, surname, givenName, fullName, mail from SIS_PERSONS' + where
+
+    log.info('query = {0}', query)
+    log.info('sql = {0}', q)
+    log.info('sqlParams = {0}', sqlParams)
+   
+    def processRow = { row -> result.add([
+	__UID__:row.uid, 
+	__NAME__:row.uid, 
+	uid:row.uid,
+	surname:row.surname,
+	givenName:row.givenName,
+	fullName:row.fullName,
+	mail:row.mail])
+    }
+
+    if (sqlParams != null) {
+      sql.eachRow(sqlParams, q, processRow)
+    } else {
+      sql.eachRow(q, processRow)
+    }
+    break
+
+    default:
+    result;
+}
+
+return result;
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy b/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy
new file mode 100644
index 0000000..c887660
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy
@@ -0,0 +1,38 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering "+action+" Script");
+def sql = new Sql(connection);
+
+sql.eachRow("select * from SIS_PERSONS limit 10", { println it.uid } );
+
+
diff --git a/demo/complex0/midpoint_server/container_files/mp-home/schema/internet2.xsd b/demo/complex0/midpoint_server/container_files/mp-home/schema/internet2.xsd
new file mode 100644
index 0000000..c482436
--- /dev/null
+++ b/demo/complex0/midpoint_server/container_files/mp-home/schema/internet2.xsd
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<xsd:schema elementFormDefault="qualified"
+  targetNamespace="http://grouper-demo.tier.internet2.edu"
+  xmlns:tns="http://grouper-demo.tier.internet2.edu"
+  xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3"
+  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+  <xsd:complexType name="UserExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:UserType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+	<!-- nothing here for now -->
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="OrgExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:OrgType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperName" type="xsd:string" minOccurs="0"/>
+        <xsd:element name="ldapDn" type="xsd:string" minOccurs="0"/>
+    </xsd:sequence>
+  </xsd:complexType>  
+
+  <xsd:complexType name="ArchetypeExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:ArchetypeType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperNamePrefix" type="xsd:string" minOccurs="0"/>		<!-- e.g. ref:affiliation: -->
+        <xsd:element name="ldapRootDn" type="xsd:string" minOccurs="0"/>		<!-- e.g. ou=Affiliations,ou=Groups,dc=internet2,dc=edu -->
+        <xsd:element name="midPointNamePrefix" type="xsd:string" minOccurs="0"/>		<!-- e.g. affiliation_ -->
+        <xsd:element name="midPointDisplayNamePrefix" type="xsd:string" minOccurs="0"/>		<!-- e.g. Affiliation: -->
+    </xsd:sequence>
+  </xsd:complexType>  
+</xsd:schema>
+
diff --git a/demo/complex0/recompute.sh b/demo/complex0/recompute.sh
new file mode 100755
index 0000000..0d9633e
--- /dev/null
+++ b/demo/complex0/recompute.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+recompute orgs d48ec05b-fffd-4262-acd3-d9ff63365b62
+recompute users e897468f-20bd-419c-8fc5-1fe60e2600de
diff --git a/demo/complex0/sources/Dockerfile b/demo/complex0/sources/Dockerfile
new file mode 100644
index 0000000..a2c5a50
--- /dev/null
+++ b/demo/complex0/sources/Dockerfile
@@ -0,0 +1,10 @@
+FROM tier/mariadb:mariadb10
+
+COPY container_files/seed-data/ /seed-data/
+
+ENV MYSQL_DATABASE sis
+ENV MYSQL_USER sis_user
+ENV MYSQL_PASSWORD 49321420423
+ENV MYSQL_DATADIR /var/lib/mysqlmounted
+ENV AFTER_FIRST_TIME_SQL /seed-data/persons-and-courses.sql
+
diff --git a/demo/complex0/sources/container_files/seed-data/persons-and-courses.sql b/demo/complex0/sources/container_files/seed-data/persons-and-courses.sql
new file mode 100644
index 0000000..65f8376
--- /dev/null
+++ b/demo/complex0/sources/container_files/seed-data/persons-and-courses.sql
@@ -0,0 +1,531 @@
+USE sis;
+
+CREATE TABLE SIS_PERSONS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE SIS_AFFILIATIONS (
+    uid VARCHAR(255) NOT NULL,
+    affiliation VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , affiliation)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex0/targets/Dockerfile b/demo/complex0/targets/Dockerfile
new file mode 100644
index 0000000..6099cce
--- /dev/null
+++ b/demo/complex0/targets/Dockerfile
@@ -0,0 +1,7 @@
+FROM tier/mariadb:mariadb10
+
+#TODO better name for the target database
+ENV MYSQL_DATABASE target
+ENV MYSQL_USER target_user
+ENV MYSQL_PASSWORD fdjskjrkwqjrw
+ENV MYSQL_DATADIR /var/lib/mysql
diff --git a/demo/complex0/targets/container_files/seed-data/target.tmp b/demo/complex0/targets/container_files/seed-data/target.tmp
new file mode 100644
index 0000000..01fa4ef
--- /dev/null
+++ b/demo/complex0/targets/container_files/seed-data/target.tmp
@@ -0,0 +1,531 @@
+USE target;
+
+CREATE TABLE FACULTY_PORTAL_MEMBERS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE MAILING_LIST_MEMBERS (
+    list VARCHAR(255) NOT NULL,
+    member VARCHAR(255) NOT NULL,
+    PRIMARY KEY (list, member)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex0/test-resources-1.sh b/demo/complex0/test-resources-1.sh
new file mode 100755
index 0000000..989ad9f
--- /dev/null
+++ b/demo/complex0/test-resources-1.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
+test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+test_resource a343fc2e-3954-4034-ba1a-2b72c21e577a
+test_resource e417225d-8a08-46f3-9b5d-624990b52386
+test_resource fe805d13-481b-43ec-97d8-9d2df72cd38e
diff --git a/demo/complex0/tests/main.bats b/demo/complex0/tests/main.bats
new file mode 100644
index 0000000..4a781f7
--- /dev/null
+++ b/demo/complex0/tests/main.bats
@@ -0,0 +1,355 @@
+#!/usr/bin/env bats
+
+load ../../../common
+load ../../../library
+
+@test "000 Cleanup before running the tests" {
+    (cd ../simple ; docker-compose down -v)
+    (cd ../shibboleth ; docker-compose down -v)
+    (cd ../postgresql ; docker-compose down -v)
+    docker-compose down -v
+}
+
+@test "010 Initialize and start the composition" {
+    # We want to fail cleanly if there's any interference
+    docker ps
+    ! (docker ps | grep -E "shibboleth_(idp|directory)_1|(complex|simple|shibboleth|postgresql)_(midpoint_server|midpoint_data)_1")
+    docker-compose build --pull grouper_daemon grouper_ui grouper_data directory sources targets midpoint_data idp mq
+    # Sometimes the tier/midpoint:xyz is not yet in the repository, causing issues with --pull
+    docker-compose build midpoint_server
+    docker-compose up -d
+}
+
+@test "020 Wait until components are started" {
+    touch $BATS_TMPDIR/not-started
+    wait_for_midpoint_start complex_midpoint_server_1 complex_midpoint_data_1
+    wait_for_shibboleth_idp_start complex_idp_1
+    wait_for_grouper_ui_start complex_grouper_ui_1
+    rm $BATS_TMPDIR/not-started
+}
+
+@test "040 Check midPoint health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+}
+
+@test "050 Check Shibboleth IDP health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health_shibboleth_idp
+}
+
+@test "060 Check Grouper health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    skip TODO
+}
+
+@test "100 Get 'administrator'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    get_and_check_object users 00000000-0000-0000-0000-000000000002 administrator
+}
+
+@test "110 And and get 'test110'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    echo "<user><name>test110</name></user>" >/tmp/test110.xml
+    add_object users /tmp/test110.xml
+    rm /tmp/test110.xml
+    search_and_check_object users test110
+    delete_object_by_name users test110
+}
+
+@test "200 Upload objects" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    # reduce data in SIS database so imports will take reasonable time
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_COURSES where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_AFFILIATIONS where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_PERSONS where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+
+    check_health
+    ./upload-objects.sh
+
+    search_and_check_object objectTemplates template-org-course
+    search_and_check_object objectTemplates template-org-department
+    search_and_check_object objectTemplates template-role-affiliation
+    search_and_check_object objectTemplates template-role-generic-group
+    
+    search_and_check_object orgs courses
+    search_and_check_object orgs departments
+
+    search_and_check_object resources "LDAP (directory)"
+    search_and_check_object resources "Grouper Resource"
+    search_and_check_object resources "SQL SIS courses (sources)"
+    search_and_check_object resources "SQL SIS persons (sources)"
+
+    search_and_check_object roles metarole-affiliation
+    search_and_check_object roles metarole-course
+    search_and_check_object roles metarole-department 
+    search_and_check_object roles metarole-generic-group
+    search_and_check_object roles role-grouper-sysadmin
+    search_and_check_object roles role-ldap-basic
+}
+
+@test "210 Test LDAP and SQL resources" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
+    test_resource 13660d60-071b-4596-9aa1-5efcd1256c04
+    test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+}
+
+@test "220 Import SIS_PERSONS" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-import-sis-persons.xml
+    search_and_check_object tasks "Import from SIS persons"
+    wait_for_task_completion 22c2a3d0-0961-4255-9eec-c550a79aeaaa 6 10
+    assert_task_success 22c2a3d0-0961-4255-9eec-c550a79aeaaa
+
+    search_and_check_object users jsmith
+    search_and_check_object users banderson
+    search_and_check_object users kwhite
+    search_and_check_object users whenderson
+    search_and_check_object users ddavis
+    search_and_check_object users cmorrison
+    search_and_check_object users danderson
+    search_and_check_object users amorrison
+    search_and_check_object users wprice
+    search_and_check_object users mroberts
+
+    check_ldap_account_by_user_name jsmith complex_directory_1
+    check_ldap_account_by_user_name banderson complex_directory_1
+    check_ldap_account_by_user_name kwhite complex_directory_1
+    check_ldap_account_by_user_name whenderson complex_directory_1
+    check_ldap_account_by_user_name ddavis complex_directory_1
+    check_ldap_account_by_user_name cmorrison complex_directory_1
+    check_ldap_account_by_user_name danderson complex_directory_1
+    check_ldap_account_by_user_name amorrison complex_directory_1
+    check_ldap_account_by_user_name wprice complex_directory_1
+    check_ldap_account_by_user_name mroberts complex_directory_1
+}
+
+@test "230 Import SIS_COURSES" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-import-sis-courses.xml
+    search_and_check_object tasks "Import from SIS courses"
+    wait_for_task_completion b73a2e66-8233-4c20-928f-acb30027b33e 8 10
+    assert_task_success b73a2e66-8233-4c20-928f-acb30027b33e
+
+    search_and_check_object orgs course_ACCT101
+    search_and_check_object orgs course_ACCT201
+    search_and_check_object orgs course_CS251
+    search_and_check_object orgs course_CS252
+    search_and_check_object orgs course_MATH100
+    search_and_check_object orgs course_MATH101
+    search_and_check_object orgs course_SCI123
+    search_and_check_object orgs course_SCI404
+
+    check_ldap_courses_by_name course_ACCT101 complex_directory_1
+    check_ldap_courses_by_name course_ACCT201 complex_directory_1
+    check_ldap_courses_by_name course_CS251 complex_directory_1
+    check_ldap_courses_by_name course_CS252 complex_directory_1
+    check_ldap_courses_by_name course_MATH100 complex_directory_1
+    check_ldap_courses_by_name course_MATH101 complex_directory_1
+    check_ldap_courses_by_name course_SCI123 complex_directory_1
+    check_ldap_courses_by_name course_SCI404 complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership whenderson "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership ddavis "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "CS252" complex_directory_1
+
+    check_of_ldap_membership danderson "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership ddavis "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership wprice "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+
+    check_of_ldap_membership danderson "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI123" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI123" complex_directory_1
+
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI404" complex_directory_1
+    check_of_ldap_membership wprice "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI404" complex_directory_1
+}
+
+@test "240 Check 'TestUser240' in Midpoint and LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    echo "<user><name>TestUser240</name><fullName>Test User240</fullName><givenName>Test</givenName><familyName>User240</familyName><credentials><password><value><clearValue>password</clearValue></value></password></credentials></user>" >/tmp/testuser240.xml
+    add_object users /tmp/testuser240.xml
+    rm /tmp/testuser240.xml
+    search_and_check_object users TestUser240
+
+    execute_bulk_action tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml complex_midpoint_server_1
+    execute_bulk_action tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml complex_midpoint_server_1
+
+    check_ldap_account_by_user_name TestUser240 complex_directory_1
+    check_of_ldap_membership TestUser240 "ou=groups,dc=internet2,dc=edu" "sysadmingroup" complex_directory_1
+    
+    delete_object_by_name users TestUser240
+}
+
+@test "250 Make 'banderson' Grouper administrator" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    recompute roles d48ec05b-fffd-4262-acd3-d9ff63365b62
+    execute_bulk_action tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml complex_midpoint_server_1
+    recompute users e897468f-20bd-419c-8fc5-1fe60e2600de # for some reason this looks necessary (TODO)
+    check_of_ldap_membership banderson "ou=groups,dc=internet2,dc=edu" "sysadmingroup" complex_directory_1
+}
+
+#@test "255 Wait 120 seconds for changes to be propagated to Grouper" {
+#    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+#
+#    sleep 120
+#}
+
+@test "260 Export ref groups" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    ./add-ref-groups.sh
+}
+
+@test "265 Wait 120 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 120
+}
+
+@test "300 Test Grouper resource" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    test_resource 1eff65de-5bb6-483d-9edf-8cc2c2ee0233
+}
+
+@test "310 Import Grouper-to-midPoint async update task" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    check_health
+    add_object tasks midpoint-objects-manual/tasks/task-async-update-grouper.xml
+    search_and_check_object tasks "Grouper async updates"
+}
+
+@test "320 Wait for the queue to become empty" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    ATTEMPT=0
+    MAX_ATTEMPTS=20
+    DELAY=10
+
+    get_messages sampleQueue
+    echo "Messages: $MESSAGES"
+
+    until [[ $ATTEMPT = $MAX_ATTEMPTS ]]; do
+        ATTEMPT=$((ATTEMPT+1))
+        get_messages sampleQueue
+        echo "Messages: $MESSAGES"
+        if [ "$MESSAGES" = "0" ]; then return 0; fi
+        echo "Waiting $DELAY seconds for the queue to become empty (attempt $ATTEMPT) ..."
+        sleep $DELAY
+    done
+    return 1
+}
+
+@test "330 Add wprice to 'midpoint:test' and 'ref:affiliation:alum_includes' groups" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t330.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t330.gsh"
+}
+
+@test "335 Wait 80 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 80
+}
+
+@test "340 Assert wprice membership in LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    assert_ldap_user_has_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_value wprice Entitlement "ref:affiliation:alum" complex_directory_1
+}
+
+@test "350 Add kwhite to 'midpoint:test', remove wprice from 'ref:affiliation:alum_includes'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t350.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t350.gsh"
+}
+
+@test "355 Wait 80 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 80
+}
+
+@test "360 Assert wprice and kwhite membership in LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    assert_ldap_user_has_value kwhite Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_no_value wprice Entitlement "ref:affiliation:alum" complex_directory_1
+}
+
+@test "400 Suspend async update task" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    suspend_task 47fc57bd-8c34-4555-9b9f-7087ff179860 complex_midpoint_server_1
+    wait_for_task_completion 47fc57bd-8c34-4555-9b9f-7087ff179860 5 10
+}
+
+@test "410 Remove kwhite and wprice from 'midpoint:test'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t410.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t410.gsh"
+}
+
+@test "420 Reconcile Grouper" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
+    search_and_check_object tasks "Grouper reconciliation (users)"
+    wait_for_task_completion 42aa9f43-64c5-41a6-814c-b58b9ea4e204 6 10
+    assert_task_success 42aa9f43-64c5-41a6-814c-b58b9ea4e204
+
+    search_and_check_object users jsmith
+    search_and_check_object users banderson
+    search_and_check_object users kwhite
+    search_and_check_object users whenderson
+    search_and_check_object users ddavis
+    search_and_check_object users cmorrison
+    search_and_check_object users danderson
+    search_and_check_object users amorrison
+    search_and_check_object users wprice
+    search_and_check_object users mroberts
+
+    check_ldap_account_by_user_name jsmith complex_directory_1
+    check_ldap_account_by_user_name banderson complex_directory_1
+    check_ldap_account_by_user_name kwhite complex_directory_1
+    check_ldap_account_by_user_name whenderson complex_directory_1
+    check_ldap_account_by_user_name ddavis complex_directory_1
+    check_ldap_account_by_user_name cmorrison complex_directory_1
+    check_ldap_account_by_user_name danderson complex_directory_1
+    check_ldap_account_by_user_name amorrison complex_directory_1
+    check_ldap_account_by_user_name wprice complex_directory_1
+    check_ldap_account_by_user_name mroberts complex_directory_1
+
+    assert_ldap_user_has_no_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_no_value kwhite Entitlement "midpoint:test" complex_directory_1
+}
+
+@test "999 Clean up" {
+    docker-compose down -v
+}
diff --git a/demo/complex0/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml b/demo/complex0/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml
new file mode 100644
index 0000000..9ec69a2
--- /dev/null
+++ b/demo/complex0/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml
@@ -0,0 +1,22 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+   			  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+			  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+			  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+                    <s:type>c:UserType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>c:name</q:path>
+                            <q:value>banderson</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>assign</s:type>
+                        <s:parameter>
+                            <s:name>role</s:name>
+							<c:value xsi:type="xsd:string">d48ec05b-fffd-4262-acd3-d9ff63365b62</c:value>
+                        </s:parameter>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex0/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml b/demo/complex0/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml
new file mode 100644
index 0000000..0cb1a6b
--- /dev/null
+++ b/demo/complex0/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml
@@ -0,0 +1,22 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+   			  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+			  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+			  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+                    <s:type>c:UserType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>c:name</q:path>
+                            <q:value>TestUser240</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>assign</s:type>
+                        <s:parameter>
+                            <s:name>role</s:name>
+							<c:value xsi:type="xsd:string">d48ec05b-fffd-4262-acd3-d9ff63365b62</c:value>
+                        </s:parameter>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex0/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml b/demo/complex0/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml
new file mode 100644
index 0000000..1356484
--- /dev/null
+++ b/demo/complex0/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml
@@ -0,0 +1,16 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3"
+		     xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+		     xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
+                    <s:type>c:RoleType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>name</q:path>
+                            <q:value>role-grouper-sysadmin</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>recompute</s:type>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex0/tests/resources/grouper/t300.gsh b/demo/complex0/tests/resources/grouper/t300.gsh
new file mode 100644
index 0000000..d2b63e3
--- /dev/null
+++ b/demo/complex0/tests/resources/grouper/t300.gsh
@@ -0,0 +1,15 @@
+System.out.println("************** t300.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+exportedGroups = GroupFinder.findByName(gs, 'etc:exportedGroups')
+alumSubject = SubjectFinder.findByIdentifier('ref:affiliation:alum', 'group', 'g:gsa')
+exportedGroups.addMember(alumSubject, false)
+
+alumIncludes = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+testGroup = GroupFinder.findByName(gs, 'etc:testGroup')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+alumIncludes.addMember(wprice, false)
+testGroup.addMember(wprice, false)
+
+System.out.println("************** t300.gsh done **************");
diff --git a/demo/complex0/tests/resources/grouper/t330.gsh b/demo/complex0/tests/resources/grouper/t330.gsh
new file mode 100644
index 0000000..cb8f158
--- /dev/null
+++ b/demo/complex0/tests/resources/grouper/t330.gsh
@@ -0,0 +1,11 @@
+System.out.println("************** t330.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+alumIncludesGroup = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.addMember(wprice, false)
+alumIncludesGroup.addMember(wprice, false)
+
+System.out.println("************** t330.gsh done **************");
diff --git a/demo/complex0/tests/resources/grouper/t350.gsh b/demo/complex0/tests/resources/grouper/t350.gsh
new file mode 100644
index 0000000..d0d2d3e
--- /dev/null
+++ b/demo/complex0/tests/resources/grouper/t350.gsh
@@ -0,0 +1,12 @@
+System.out.println("************** t350.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+alumIncludes = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+kwhite = SubjectFinder.findById('kwhite', 'person', 'ldap')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.addMember(kwhite, false)
+alumIncludes.deleteMember(wprice, false)
+
+System.out.println("************** t350.gsh done **************");
diff --git a/demo/complex0/tests/resources/grouper/t410.gsh b/demo/complex0/tests/resources/grouper/t410.gsh
new file mode 100644
index 0000000..69e4b18
--- /dev/null
+++ b/demo/complex0/tests/resources/grouper/t410.gsh
@@ -0,0 +1,11 @@
+System.out.println("************** t410.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+kwhite = SubjectFinder.findById('kwhite', 'person', 'ldap')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.deleteMember(kwhite, false)
+testGroup.deleteMember(wprice, false)
+
+System.out.println("************** t410.gsh done **************");
diff --git a/demo/complex0/tests/resources/rabbitmq/check-samplequeue.sh b/demo/complex0/tests/resources/rabbitmq/check-samplequeue.sh
new file mode 100755
index 0000000..e336a63
--- /dev/null
+++ b/demo/complex0/tests/resources/rabbitmq/check-samplequeue.sh
@@ -0,0 +1,8 @@
+count=$(rabbitmqctl list_queues | grep sampleQueue | awk '{print $2}')
+if [[ -z $count || $count -eq 0 ]]; then
+    echo "ERROR: sampleQueue does not exist or is empty"
+    exit 1
+else
+    echo "OK: sampleQueue has $count message(s)"
+    exit 0
+fi
diff --git a/demo/complex0/tests/resources/tasks/task-livesync-grouper-single.xml b/demo/complex0/tests/resources/tasks/task-livesync-grouper-single.xml
new file mode 100644
index 0000000..365d007
--- /dev/null
+++ b/demo/complex0/tests/resources/tasks/task-livesync-grouper-single.xml
@@ -0,0 +1,29 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+      oid="87ffce52-717a-4205-ba01-0a698f0deaee">
+   <name>LiveSync from Grouper</name>
+   <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+              xmlns:gen437="http://midpoint.evolveum.com/xml/ns/public/provisioning/liveSync-3"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:type="c:ExtensionType">
+      <mext:kind>account</mext:kind>
+      <mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+   </extension>
+   <taskIdentifier>1535465478027-0-1</taskIdentifier>
+   <ownerRef oid="00000000-0000-0000-0000-000000000002"
+             relation="org:default"
+             type="c:UserType"><!-- administrator --></ownerRef>
+   <executionStatus>runnable</executionStatus>
+   <category>LiveSynchronization</category>
+   <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/live-sync/handler-3</handlerUri>
+   <objectRef oid="6dcb84f5-bf82-4931-9072-fbdf87f96442"
+              relation="org:default"
+              type="c:ResourceType"><!-- Grouper SQL NEW --></objectRef>
+   <recurrence>single</recurrence>
+   <binding>loose</binding>
+</task>
diff --git a/demo/complex0/tests/resources/users/user-grouper-admin.xml b/demo/complex0/tests/resources/users/user-grouper-admin.xml
new file mode 100644
index 0000000..d785e47
--- /dev/null
+++ b/demo/complex0/tests/resources/users/user-grouper-admin.xml
@@ -0,0 +1,20 @@
+<user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      oid="a0c7c01e-c203-4777-9b21-27a4735da3ae">
+    <name>grouper-admin</name>
+    <assignment id="1">
+        <targetRef oid="d48ec05b-fffd-4262-acd3-d9ff63365b62" relation="org:default" type="c:RoleType">
+            <!-- role-grouper-sysadmin -->
+        </targetRef>
+    </assignment>
+    <fullName>Grouper admin</fullName>
+    <givenName>Grouper</givenName>
+    <familyName>Admin</familyName>
+    <credentials>
+        <password>
+            <value>password</value>
+        </password>
+    </credentials>
+</user>
+	
diff --git a/demo/complex0/upload-import-sis-persons.sh b/demo/complex0/upload-import-sis-persons.sh
new file mode 100755
index 0000000..058c9af
--- /dev/null
+++ b/demo/complex0/upload-import-sis-persons.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-import-sis-persons.xml
diff --git a/demo/complex0/upload-objects.sh b/demo/complex0/upload-objects.sh
new file mode 100755
index 0000000..3f1c9b8
--- /dev/null
+++ b/demo/complex0/upload-objects.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+function upload () {
+  local filename=$1
+  local regex="midpoint-objects/(.*)/(.*)"
+  if [[ $filename =~ $regex ]]
+  then
+    type="${BASH_REMATCH[1]}"
+    oid=`cat $filename | sed -n 's:.*oid=\"\([A-Za-z0-9\-]*\)\".*:\1:p' | sed -n '1 p'`
+    echo "Uploading $filename ($type, $oid)"
+    curl -k --user administrator:5ecr3t -H "Content-Type: application/xml" -X PUT "https://localhost:8443/midpoint/ws/rest/$type/$oid?options=overwrite&options=raw" --data-binary @$filename
+  else
+    echo "Skipping $filename"
+  fi
+}
+
+find midpoint-objects -name "*.xml" | while read filename; do upload $filename; done
diff --git a/demo/complex0/upload-recompute-users.sh b/demo/complex0/upload-recompute-users.sh
new file mode 100644
index 0000000..42b5551
--- /dev/null
+++ b/demo/complex0/upload-recompute-users.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-recomputation-users.xml
diff --git a/demo/complex2/.env b/demo/complex2/.env
new file mode 100644
index 0000000..75949b1
--- /dev/null
+++ b/demo/complex2/.env
@@ -0,0 +1,14 @@
+AUTHENTICATION=internal
+ENV=demo
+REPO_DATABASE_TYPE=mariadb
+REPO_JDBC_URL=default
+REPO_HOST=midpoint_data
+REPO_PORT=default
+REPO_DATABASE=registry
+REPO_USER=registry_user
+REPO_MISSING_SCHEMA_ACTION=create
+REPO_UPGRADEABLE_SCHEMA_ACTION=stop
+MP_MEM_MAX=2048m
+MP_MEM_INIT=1024m
+SSO_HEADER=uid
+TIMEZONE=UTC
diff --git a/demo/complex2/README.md b/demo/complex2/README.md
new file mode 100644
index 0000000..9b7f0f6
--- /dev/null
+++ b/demo/complex2/README.md
@@ -0,0 +1,9 @@
+This is a demonstration of using midPoint dockerization for TIER environment in a broader context. It is a work in progress.
+
+# Building and execution
+```
+$ ../../build.sh
+$ docker-compose up --build
+```
+
+Please see a detailed description [here](https://spaces.at.internet2.edu/display/MID/Complex+midPoint+integration+demo).
diff --git a/demo/complex2/add-ref-groups.gsh b/demo/complex2/add-ref-groups.gsh
new file mode 100644
index 0000000..7697f99
--- /dev/null
+++ b/demo/complex2/add-ref-groups.gsh
@@ -0,0 +1,26 @@
+
+def addGroups(gs,stem,owner,regexp) {
+	for (group in stem.childGroups) {
+		if (!group.name.endsWith('_includes') &&
+		    !group.name.endsWith('_excludes') &&
+		    !group.name.endsWith('_systemOfRecord') &&
+		    !group.name.endsWith('_systemOfRecordAndIncludes') &&
+		    (regexp == null || group.extension ==~ regexp)) {
+			println 'Adding: ' + group
+			def s = SubjectFinder.findById(group.getId(), 'group', 'g:gsa')
+			owner.addMember(s, false)
+		} else {
+			println 'Ignoring: ' + group
+		}
+	}
+}
+
+gs = GrouperSession.startRootSession()
+def supergroup = GroupFinder.findByName(gs, "etc:midpointGroups", true)
+def cs = GroupFinder.findByName(gs, "app:cs", true)
+
+addGroups(gs, StemFinder.findByName(gs, 'ref:affiliation'), supergroup, null)
+addGroups(gs, StemFinder.findByName(gs, 'ref:dept'), supergroup, null)
+addGroups(gs, StemFinder.findByName(gs, 'ref:course'), supergroup, null)
+
+addGroups(gs, StemFinder.findByName(gs, 'ref:course'), cs, /CS.*/)
diff --git a/demo/complex2/add-ref-groups.sh b/demo/complex2/add-ref-groups.sh
new file mode 100755
index 0000000..d35b173
--- /dev/null
+++ b/demo/complex2/add-ref-groups.sh
@@ -0,0 +1,3 @@
+source ../../library.bash
+
+execute_gsh complex2_grouper_daemon_1 add-ref-groups.gsh
diff --git a/demo/complex2/after-installation.sh b/demo/complex2/after-installation.sh
new file mode 100755
index 0000000..68582e3
--- /dev/null
+++ b/demo/complex2/after-installation.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+B='\033[1;33m'
+N='\033[0m'
+
+echo -e "${B} * Uploading objects...${N}"
+$(dirname "$0")/upload-objects.sh
+
+echo -e "${B} * Testing LDAP and SQL resources...${N}"
+$(dirname "$0")/test-resources-1.sh
+
+echo -e "${B} * Recomputing Grouper admin group and user object...${N}"
+$(dirname "$0")/recompute.sh
+
+echo -e "${B} * Waiting 120 seconds for changes to propagate to Grouper...${N}"
+sleep 120
+
+echo -e "${B} * Testing Grouper resource...${N}"
+$(dirname "$0")/test-resource-grouper.sh
+
+echo -e "${B} * Done${N}"
diff --git a/demo/complex2/configs-and-secrets/grouper/application/database_password.txt b/demo/complex2/configs-and-secrets/grouper/application/database_password.txt
new file mode 100644
index 0000000..e69de29
diff --git a/demo/complex2/configs-and-secrets/grouper/application/grouper-loader.properties b/demo/complex2/configs-and-secrets/grouper/application/grouper-loader.properties
new file mode 100644
index 0000000..62ef5f0
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/application/grouper-loader.properties
@@ -0,0 +1,71 @@
+#################################
+## LDAP connections
+#################################
+# specify the ldap connection with user, pass, url
+# the string after "ldap." is the ID of the connection, and it should not have
+# spaces or other special chars in it.  In this case is it "personLdap"
+
+#note the URL should start with ldap: or ldaps: if it is SSL.  
+#It should contain the server and port (optional if not default), and baseDn,
+#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu
+ldap.demo.url = ldap://directory:389/dc=internet2,dc=edu
+ 
+#optional, if authenticated
+ldap.demo.user = cn=admin,dc=internet2,dc=edu
+#ldap.demo.user = cn=admin
+ 
+#optional, if authenticated note the password can be stored encrypted in an external file
+#ldap.demo.pass = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+ldap.demo.pass = password
+ 
+#optional, if you are using tls, set this to true.  Generally you will not be using an SSL URL to use TLS...
+ldap.demo.tls = false
+ 
+#optional, if using sasl
+#ldap.personLdap.saslAuthorizationId =
+#ldap.personLdap.saslRealm =
+ 
+#optional (note, time limit is for search operations, timeout is for connection timeouts),
+#most of these default to vt-ldap defaults.  times are in millis
+#validateOnCheckout defaults to true if all other validate methods are false
+#ldap.personLdap.batchSize =
+#ldap.personLdap.countLimit =
+#ldap.personLdap.timeLimit =
+#ldap.personLdap.timeout =
+#ldap.personLdap.minPoolSize =
+#ldap.personLdap.maxPoolSize =
+#ldap.personLdap.validateOnCheckIn =
+#ldap.personLdap.validateOnCheckOut =
+#ldap.personLdap.validatePeriodically =
+#ldap.personLdap.validateTimerPeriod =
+#ldap.personLdap.pruneTimerPeriod =
+#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes)
+#ldap.personLdap.expirationTime =
+
+#make the paths fully qualified and not relative to the loader group.
+loader.ldap.requireTopStemAsStemFromConfigGroup=false
+
+
+db.sis.user = sis_user
+db.sis.pass = 49321420423
+db.sis.url = jdbc:mysql://sources:3306/sis
+db.sis.driver = com.mysql.jdbc.Driver
+
+
+#####################################
+## Messaging integration with change log
+#####################################
+changeLog.consumer.rabbitMqMessagingSample.quartzCron = 0 * * * * ?                                                          
+
+# note, change "messagingSample" in key to be the name of the consumer.  e.g. changeLog.consumer.someNameAnyName.class
+changeLog.consumer.rabbitMqMessagingSample.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer
+
+changeLog.consumer.rabbitMqMessagingSample.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher
+changeLog.consumer.rabbitMqMessagingSample.publisher.messagingSystemName = rabbitmq
+# note, routingKey property is valid only for rabbitmq. For other messaging systems, it is ignored.
+changeLog.consumer.rabbitMqMessagingSample.publisher.routingKey = 
+## queue or topic
+changeLog.consumer.rabbitMqMessagingSample.publisher.messageQueueType = queue
+changeLog.consumer.rabbitMqMessagingSample.publisher.queueOrTopicName = sampleQueue
+## this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml
+#changeLog.consumer.rabbitMqMessagingSample.publisher.addSubjectAttributes = email
diff --git a/demo/complex2/configs-and-secrets/grouper/application/grouper.client.properties b/demo/complex2/configs-and-secrets/grouper/application/grouper.client.properties
new file mode 100644
index 0000000..d25ad96
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/application/grouper.client.properties
@@ -0,0 +1,112 @@
+#
+# Copyright 2014 Internet2
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Grouper client configuration
+# $Id: grouper.client.example.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $
+#
+
+# The grouper client uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.client.base.properties
+# (which should not be edited), and the grouper.client.properties overlays
+# the base settings.  See the grouper.client.base.properties for the possible
+# settings that can be applied to the grouper.client.properties
+
+########################################
+## LDAP connection settings
+########################################
+
+# url of directory, including the base DN (distinguished name)
+# e.g. ldap://server.school.edu/dc=school,dc=edu
+# e.g. ldaps://server.school.edu/dc=school,dc=edu
+grouperClient.ldap.url =
+
+# kerberos principal used to connect to ldap
+grouperClient.ldap.login =
+
+# password for shared secret authentication to ldap
+# or you can put a filename with an encrypted password
+grouperClient.ldap.password =
+
+########################################
+## Web service Connection settings
+########################################
+
+# url of web service, should include everything up to the first resource to access
+# e.g. http://groups.school.edu:8090/grouper-ws/servicesRest
+# e.g. https://groups.school.edu/grouper-ws/servicesRest
+grouperClient.webService.url = https://grouper_ws/grouper-ws/servicesRest
+
+# kerberos principal used to connect to web service
+grouperClient.webService.login = banderson
+
+# password for shared secret authentication to web service
+# or you can put a filename with an encrypted password
+grouperClient.webService.password.elConfig = ${java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD') }
+
+
+################################
+## Grouper Messaging System
+################################
+ 
+# name of messaging system which is the default
+grouper.messaging.default.name.of.messaging.system = rabbitmq
+ 
+# name of a messaging system.  note, "grouperBuiltinMessaging" can be arbitrary
+# grouper.messaging.system.grouperBuiltinMessaging.name = grouperBuiltinMessaging
+ 
+# class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem
+# grouper.messaging.system.grouperBuiltinMessaging.class = edu.internet2.middleware.grouper.messaging.GrouperBuiltinMessagingSystem
+ 
+# name of a messaging system.  note, "grouperBuiltinMessaging" can be arbitrary
+grouper.messaging.system.rabbitmqSystem.name = rabbitmqSystem
+ 
+# class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem
+grouper.messaging.system.rabbitmqSystem.class = edu.internet2.middleware.grouperMessagingRabbitmq.GrouperMessagingRabbitmqSystem
+ 
+# host address of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.host = mq
+ 
+# virtual host of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.virtualhost =
+ 
+# port of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.port =
+ 
+grouper.messaging.system.rabbitmqSystem.defaultPageSize = 10
+ 
+grouper.messaging.system.rabbitmqSystem.maxPageSize = 50
+ 
+ 
+# name of a messaging system, required
+grouper.messaging.system.rabbitmq.name = rabbitmq
+ 
+# default system settings to this messaging system, note, there is only one level of inheritance
+grouper.messaging.system.rabbitmq.defaultSystemName = rabbitmqSystem
+
+grouper.messaging.system.rabbitmq.user = guest
+
+#pass
+grouper.messaging.system.rabbitmq.password.elConfig = ${java.lang.System.getenv().get('RABBITMQ_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('RABBITMQ_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('RABBITMQ_PASSWORD') }
+# set the following three properties if you want to use TLS connection to rabbitmq. All three need to be populated.
+# TLS Version
+#grouper.messaging.system.rabbitmqSystem.tlsVersion = TLSv1.1
+ 
+# path to trust store file
+#grouper.messaging.system.rabbitmqSystem.pathToTrustStore =
+ 
+# trust passphrase
+#grouper.messaging.system.rabbitmqSystem.trustPassphrase =
diff --git a/demo/complex2/configs-and-secrets/grouper/application/grouper.hibernate.properties b/demo/complex2/configs-and-secrets/grouper/application/grouper.hibernate.properties
new file mode 100644
index 0000000..deb0d75
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/application/grouper.hibernate.properties
@@ -0,0 +1,29 @@
+#
+# Grouper Hibernate Configuration
+# $Id: grouper.hibernate.example.properties,v 1.9 2009-08-11 20:18:09 mchyzer Exp $
+#
+
+# The grouper hibernate config uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.hibernate.base.properties
+# (which should not be edited), and the grouper.hibernate.properties overlays
+# the base settings.  See the grouper.hibernate.base.properties for the possible
+# settings that can be applied to the grouper.hibernate.properties
+
+########################################
+## DB settings
+########################################
+
+# e.g. mysql:           jdbc:mysql://localhost:3306/grouper
+# e.g. p6spy (log sql): [use the URL that your DB requires]
+# e.g. oracle:          jdbc:oracle:thin:@server.school.edu:1521:sid
+# e.g. hsqldb (a):      jdbc:hsqldb:dist/run/grouper;create=true
+# e.g. hsqldb (b):      jdbc:hsqldb:hsql://localhost:9001/grouper
+# e.g. postgres:        jdbc:postgresql://localhost:5432/database
+# e.g. mssql:           jdbc:sqlserver://localhost:3280;databaseName=grouper
+hibernate.connection.url = jdbc:mysql://grouper_data:3306/grouper?CharSet=utf8&useUnicode=true&characterEncoding=utf8
+
+hibernate.connection.username         = root
+# If you are using an empty password, depending upon your version of
+# Java and Ant you may need to specify a password of "".
+# Note: you can keep passwords external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122
+hibernate.connection.password.elConfig = ${java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD') }
diff --git a/demo/complex2/configs-and-secrets/grouper/application/grouper.properties b/demo/complex2/configs-and-secrets/grouper/application/grouper.properties
new file mode 100644
index 0000000..c931287
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/application/grouper.properties
@@ -0,0 +1,25 @@
+#
+# Grouper Configuration
+# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $
+#
+
+# Grouper uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.base.properties
+# (which should not be edited), and the grouper.properties overlays
+# the base settings.  See the grouper.base.properties for the possible
+# settings that can be applied to the grouper.properties
+
+#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on)
+configuration.autocreate.system.groups = true
+
+# A wheel group allows you to enable non-GrouperSystem subjects to act
+# like a root user when interacting with the registry.
+groups.wheel.use                      = true
+
+# Set to the name of the group you want to treat as the wheel group.
+# The members of this group will be treated as root-like users.
+groups.wheel.group                    = etc:sysadmingroup
+
+# Used to allow Include Exclude groups
+grouperIncludeExclude.use = true
+grouperIncludeExclude.requireGroups.use = true
diff --git a/demo/complex2/configs-and-secrets/grouper/application/rabbitmq_password.txt b/demo/complex2/configs-and-secrets/grouper/application/rabbitmq_password.txt
new file mode 100644
index 0000000..158f675
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/application/rabbitmq_password.txt
@@ -0,0 +1 @@
+guest
\ No newline at end of file
diff --git a/demo/complex2/configs-and-secrets/grouper/application/subject.properties b/demo/complex2/configs-and-secrets/grouper/application/subject.properties
new file mode 100644
index 0000000..577db03
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/application/subject.properties
@@ -0,0 +1,78 @@
+#subject.sources.xml.location =
+
+subjectApi.source.ldap.param.ldapServerId.value = demo
+
+subjectApi.source.ldap.id = ldap
+subjectApi.source.ldap.name = EDU Ldap 
+subjectApi.source.ldap.types = person
+subjectApi.source.ldap.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter
+#subjectApi.source.ldap.param.INITIAL_CONTEXT_FACTORY.value = com.sun.jndi.ldap.LdapCtxFactory
+#subjectApi.source.ldap.param.PROVIDER_URL.value = ldap://directory:389
+#subjectApi.source.ldap.param.SECURITY_AUTHENTICATION.value = simple
+#subjectApi.source.ldap.param.SECURITY_PRINCIPAL.value = cn=admin,dc=internet2,dc=edu
+#subjectApi.source.ldap.param.SECURITY_CREDENTIALS.value.elConfig = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+#subjectApi.source.ldap.param.VTLDAP_VALIDATOR.value = ConnectLdapValidator
+
+subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid
+subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false
+subjectApi.source.ldap.param.Name_AttributeType.value = cn
+subjectApi.source.ldap.param.Description_AttributeType.value = cn
+subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")}
+subjectApi.source.ldap.param.sortAttribute0.value = cn
+subjectApi.source.ldap.param.searchAttribute0.value = searchAttribute0
+
+# STATUS SECTION for searches to filter out inactives and allow
+# the user to filter by status with e.g. status=all
+# this is optional, and advanced
+#
+# field in database or ldap or endpoint that is the status field
+#subjectApi.source.example.param.statusDatastoreFieldName.value = status
+
+# search string from user which represents the status.  e.g. status=active
+#subjectApi.source.example.param.statusLabel.value = status
+
+# available statuses from screen (if not specified, any will be allowed). comma separated list.
+# Note, this is optional and you probably dont want to configure it, it is mostly necessary
+# when you have multiple sources with statuses...  if someone types an invalid status
+# and you have this configured, it will not filter by it
+#subjectApi.source.example.param.statusesFromUser.value = Active, Inactive, Pending, All
+
+# all label from the user
+#subjectApi.source.example.param.statusAllFromUser.value = All
+
+# if no status is specified, this will be used (e.g. for active only).  Note, the value should be of the
+# form the user would type in
+#subjectApi.source.example.param.statusSearchDefault.value = status=active
+
+# translate between screen values of status, and the data store value.  Increment the 0 to 1, 2, etc for more translations.
+# so the user could enter: status=active, and that could translate to status_col=A.  The 'user' is what the user types in,
+# the 'datastore' is what is in the datastore.  The user part is not case-sensitive.  Note, this could be a many to one
+#subjectApi.source.example.param.statusTranslateUser0.value = active
+#subjectApi.source.example.param.statusTranslateDatastore0.value = A
+
+# subject identifier to store in grouper's member table.  this is used to increase speed of loader and perhaps for provisioning
+# you can have up to max 1 subject identifier
+#subjectApi.source.example.param.subjectIdentifierAttribute0.value = uid
+
+#searchSubject: find a subject by ID.  ID is generally an opaque and permanent identifier, e.g. 12345678.
+#  Each subject has one and only on ID.  Returns one result when searching for one ID.
+subjectApi.source.ldap.search.searchSubject.param.filter.value = (&(uid=%TERM%)(objectclass=person))
+subjectApi.source.ldap.search.searchSubject.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubject.param.base.value = ou=people
+
+#searchSubjectByIdentifier: find a subject by identifier.  Identifier is anything that uniquely
+#  identifies the user, e.g. jsmith or jsmith@institution.edu.
+#  Subjects can have multiple identifiers.  Note: it is nice to have if identifiers are unique
+#  even across sources.  Returns one result when searching for one identifier.
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.filter.value = (&(|(uid=%TERM%)(employeeNumber=%TERM%))(objectclass=person))
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.base.value = ou=people
+
+#   search: find subjects by free form search.  Returns multiple results.
+
+subjectApi.source.ldap.search.search.param.filter.value = (&(|(|(uid=%TERM%)(cn=*%TERM%*))(uid=%TERM%*))(objectclass=person))
+subjectApi.source.ldap.search.search.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.search.param.base.value = ou=people
+
+subjectApi.source.ldap.attributes = givenName, sn, uid, mail, employeeNumber
+subjectApi.source.ldap.internalAttributes = searchAttribute0
diff --git a/demo/complex2/configs-and-secrets/grouper/httpd/cachain-cer.pem b/demo/complex2/configs-and-secrets/grouper/httpd/cachain-cer.pem
new file mode 100644
index 0000000..e69de29
diff --git a/demo/complex2/configs-and-secrets/grouper/httpd/host-cert.pem b/demo/complex2/configs-and-secrets/grouper/httpd/host-cert.pem
new file mode 100644
index 0000000..9cc228a
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/httpd/host-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2/configs-and-secrets/grouper/httpd/host-key.pem b/demo/complex2/configs-and-secrets/grouper/httpd/host-key.pem
new file mode 100644
index 0000000..1b0b579
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEzSZrDaU6UeDa
+wycDoCv6N1GJTXYtXOsQX5bfpYiwLEHNetEEXleHUkhivC2bzefGvwUyLB/HS4UJ
+VEPKkFGNgH6JVazcW+1mrpnofzzs2FE0cpZ6BqVN1mxjBD8RPwHYD+VP2nWL8ruF
+yOXqb+8I2STk6nFWoNeUmpWPmrKPmQv+ZflM0cZlgWcSk7Ei9cuzxXoWOP2Zd2N6
+BlbFZf87KbeZbXqGUHnlcVF9vUtwH9dch2OMaRKfu67wM2P55bE4hwLFKAhSvzRU
+Nnr70kcedgfRZNXFj9TA1Q5tkI0Kg/cQRmEp1+m4UHo1ceyVCR5W5btkOaeV3VtA
+YoYBZbqBAgMBAAECggEAA/5t0ypZug9DUu0283niqpdIzlKGHXGPS6vE8hD37ytW
+wobFiyMm/5YJ5gcPnePV2lCyGEyQ8Ih10LSnE4tOPGLpLnxQn8A11ymf8fnzEJNr
+Qnc42o0b+bJqTLAfX4g5z1qzOqWiUQ7CA3sKP3G6FiHh/8tKNYnaFif09Q8cpJFb
+YDDkvm48NJgsrIoCgmaFIQIn+yDzGQKWwTNMIks+RByWpc67j1x1kiyQM1RfrEev
+Yyq/ZkP66IYZzmZKpFCWGs5qbRZdxyXNpq85DjwA99lAH7vxtMJHQM4z1h1eDH4L
+Ma5hEnmmHu4D5lF2GDQYflvuFdDGH5tThO6MV0IrSQKBgQD+kvEtNxJCMxLOVFyV
+NWF3pk/i2nkD+53t/VPXjMPtW7IesouEGzU82I/fT2wUTkNwFdkVpv37qoLypKZm
+npJFxr6abQNjiDh2Fsh8/iuJfvdZUFJbCEY6NS58qgjix8XCQKRD06EugK7uekIZ
+zJnttF3qVBBD8Z8Uwxz8i+jF1wKBgQDF51y/5XB6Bz47cdxw7P8NsfnTz2V3H0HU
+OnlEBANbhmBadjU8dqbM54Nxbn7VOdooXPuSnAKJ9vPDg1n5Y/GO+lgldNzfyK6g
+HnbldSu0zBvAaGvmAjLjetEtOkBqYkrHJlT6JAems/Kc/YX5uooAz9/jNJFXP9++
+KbjH3CzHZwKBgQC6ppxEDZPKi83nD/2NvMTIyFzcNFj0LaEepFW7vc7NkiSn0zrt
+0lEXWqUqEv5oaPWTEcHH2VdxFRTLuSL0LKGMnWqUqQcKDA9xrcSzuFvNhRTwHC81
+5XwwI1wBNV4sgFKj2WdW/6y2/szDt0oNxnC50zvkmlwOpPKBc4kmNaKmowKBgBmC
+uXIDIXyZcmw3QTNNWZNqXcnv8iRo4xN4dilOWyBxMfp3QmWI5feD4G2+0Jqr2nNZ
+iRRdB/bA3qtVQ0PinkDQBIzPg6lVNS1uv+TUNc4YgXtL+pyrq+Om8U/jMmqEQR9q
+0YltG49houSZyatnYGK6aSHgpNuaYD0jI66fsyYBAoGAMefyD0I/ncArjuf58hVQ
+zSjxfcvlja9okrC8ZgqsVluezcm4rQNcSjBnESGTCjJC7O29AofGLHkvnsBQDiGk
+hE38IRisd+okXdApr41ifWDhmtASud5q6wlhOpMmQxg+OALf1rTvFYhbnFEXV/KY
+e5A4iXLRIbxbmXZDa35Rebw=
+-----END PRIVATE KEY-----
diff --git a/demo/complex2/configs-and-secrets/grouper/shibboleth/idp-metadata.xml b/demo/complex2/configs-and-secrets/grouper/shibboleth/idp-metadata.xml
new file mode 100644
index 0000000..4fa67a7
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/shibboleth/idp-metadata.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex2/configs-and-secrets/grouper/shibboleth/shibboleth2.xml b/demo/complex2/configs-and-secrets/grouper/shibboleth/shibboleth2.xml
new file mode 100644
index 0000000..0c38f82
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/shibboleth/shibboleth2.xml
@@ -0,0 +1,136 @@
+<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"    
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    clockSkew="180">
+
+    <!--
+    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
+    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
+    -->
+
+    <!--
+    To customize behavior for specific resources on Apache, and to link vhosts or
+    resources to ApplicationOverride settings below, use web server options/commands.
+    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
+    
+    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
+    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
+    -->
+    <TCPListener address="127.0.0.1" port="1600"/> 
+
+
+    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
+    <ApplicationDefaults entityID="https://grouperdemo/shibboleth"
+                         REMOTE_USER="uid">
+
+        <!--
+        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
+        You MUST supply an effectively unique handlerURL value for each of your applications.
+        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
+        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
+        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
+        Note that while we default checkAddress to "false", this has a negative impact on the
+        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
+        -->
+        <Sessions lifetime="28800" timeout="28800" relayState="ss:mem"
+                  checkAddress="false" handlerSSL="true" cookieProps="https">
+
+            <!--
+            Configures SSO for a default IdP. To allow for >1 IdP, remove
+            entityID property and adjust discoveryURL to point to discovery service.
+            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
+            You can also override entityID on /Login query string, or in RequestMap/htaccess.
+            -->
+		<SSO entityID="https://idptestbed/idp/shibboleth">
+			SAML2
+		</SSO>
+
+            <!-- SAML and local-only logout. -->
+            <Logout>SAML2 Local</Logout>
+            
+            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
+            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
+
+            <!-- Status reporting service. -->
+            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
+
+            <!-- Session diagnostic service. -->
+            <Handler type="Session" Location="/Session" showAttributeValues="true"/>
+
+            <!-- JSON feed of discovery information. -->
+            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
+        </Sessions>
+
+        <!--
+        Allows overriding of error template information/filenames. You can
+        also add attributes with values that can be plugged into the templates.
+        -->
+        <Errors supportContact="root@localhost"
+            helpLocation="/about.html"
+            styleSheet="/shibboleth-sp/main.css"/>
+        
+        <!-- Example of remotely supplied batch of signed metadata. -->
+        <!--
+        <MetadataProvider type="XML" validate="true"
+	      uri="http://example.org/federation-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <MetadataProvider type="XML" validate="true" file="idp-metadata.xml"/>
+
+        <!--
+        InCommon
+	  <MetadataProvider type="XML" validate="true"
+		uri="http://md.incommon.org/InCommon/InCommon-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+		<MetdataFilter type="Signature" certificate="inc-md-cert.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <!-- Map to extract attributes from SAML assertions. -->
+        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
+        
+        <!-- Use a SAML query if no attributes are supplied during SSO. -->
+        <AttributeResolver type="Query" subjectMatch="true"/>
+
+        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
+        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
+
+        <!-- Simple file-based resolver for using a single keypair. -->
+        <CredentialResolver type="File" key="sp-key.pem" certificate="sp-cert.pem"/>
+
+        <!--
+        The default settings can be overridden by creating ApplicationOverride elements (see
+        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
+        Resource requests are mapped by web server commands, or the RequestMapper, to an
+        applicationId setting.
+        
+        Example of a second application (for a second vhost) that has a different entityID.
+        Resources on the vhost would map to an applicationId of "admin":
+        -->
+        <!--
+        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
+        -->
+    </ApplicationDefaults>
+    
+    <!-- Policies that determine how to process and authenticate runtime messages. -->
+    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
+
+    <!-- Low-level configuration about protocols and bindings available for use. -->
+    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
+
+</SPConfig>
diff --git a/demo/complex2/configs-and-secrets/grouper/shibboleth/sp-cert.pem b/demo/complex2/configs-and-secrets/grouper/shibboleth/sp-cert.pem
new file mode 100644
index 0000000..9cc228a
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/shibboleth/sp-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2/configs-and-secrets/grouper/shibboleth/sp-key.pem b/demo/complex2/configs-and-secrets/grouper/shibboleth/sp-key.pem
new file mode 100644
index 0000000..1b0b579
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/grouper/shibboleth/sp-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEzSZrDaU6UeDa
+wycDoCv6N1GJTXYtXOsQX5bfpYiwLEHNetEEXleHUkhivC2bzefGvwUyLB/HS4UJ
+VEPKkFGNgH6JVazcW+1mrpnofzzs2FE0cpZ6BqVN1mxjBD8RPwHYD+VP2nWL8ruF
+yOXqb+8I2STk6nFWoNeUmpWPmrKPmQv+ZflM0cZlgWcSk7Ei9cuzxXoWOP2Zd2N6
+BlbFZf87KbeZbXqGUHnlcVF9vUtwH9dch2OMaRKfu67wM2P55bE4hwLFKAhSvzRU
+Nnr70kcedgfRZNXFj9TA1Q5tkI0Kg/cQRmEp1+m4UHo1ceyVCR5W5btkOaeV3VtA
+YoYBZbqBAgMBAAECggEAA/5t0ypZug9DUu0283niqpdIzlKGHXGPS6vE8hD37ytW
+wobFiyMm/5YJ5gcPnePV2lCyGEyQ8Ih10LSnE4tOPGLpLnxQn8A11ymf8fnzEJNr
+Qnc42o0b+bJqTLAfX4g5z1qzOqWiUQ7CA3sKP3G6FiHh/8tKNYnaFif09Q8cpJFb
+YDDkvm48NJgsrIoCgmaFIQIn+yDzGQKWwTNMIks+RByWpc67j1x1kiyQM1RfrEev
+Yyq/ZkP66IYZzmZKpFCWGs5qbRZdxyXNpq85DjwA99lAH7vxtMJHQM4z1h1eDH4L
+Ma5hEnmmHu4D5lF2GDQYflvuFdDGH5tThO6MV0IrSQKBgQD+kvEtNxJCMxLOVFyV
+NWF3pk/i2nkD+53t/VPXjMPtW7IesouEGzU82I/fT2wUTkNwFdkVpv37qoLypKZm
+npJFxr6abQNjiDh2Fsh8/iuJfvdZUFJbCEY6NS58qgjix8XCQKRD06EugK7uekIZ
+zJnttF3qVBBD8Z8Uwxz8i+jF1wKBgQDF51y/5XB6Bz47cdxw7P8NsfnTz2V3H0HU
+OnlEBANbhmBadjU8dqbM54Nxbn7VOdooXPuSnAKJ9vPDg1n5Y/GO+lgldNzfyK6g
+HnbldSu0zBvAaGvmAjLjetEtOkBqYkrHJlT6JAems/Kc/YX5uooAz9/jNJFXP9++
+KbjH3CzHZwKBgQC6ppxEDZPKi83nD/2NvMTIyFzcNFj0LaEepFW7vc7NkiSn0zrt
+0lEXWqUqEv5oaPWTEcHH2VdxFRTLuSL0LKGMnWqUqQcKDA9xrcSzuFvNhRTwHC81
+5XwwI1wBNV4sgFKj2WdW/6y2/szDt0oNxnC50zvkmlwOpPKBc4kmNaKmowKBgBmC
+uXIDIXyZcmw3QTNNWZNqXcnv8iRo4xN4dilOWyBxMfp3QmWI5feD4G2+0Jqr2nNZ
+iRRdB/bA3qtVQ0PinkDQBIzPg6lVNS1uv+TUNc4YgXtL+pyrq+Om8U/jMmqEQR9q
+0YltG49houSZyatnYGK6aSHgpNuaYD0jI66fsyYBAoGAMefyD0I/ncArjuf58hVQ
+zSjxfcvlja9okrC8ZgqsVluezcm4rQNcSjBnESGTCjJC7O29AofGLHkvnsBQDiGk
+hE38IRisd+okXdApr41ifWDhmtASud5q6wlhOpMmQxg+OALf1rTvFYhbnFEXV/KY
+e5A4iXLRIbxbmXZDa35Rebw=
+-----END PRIVATE KEY-----
diff --git a/demo/complex2/configs-and-secrets/midpoint/application/database_password.txt b/demo/complex2/configs-and-secrets/midpoint/application/database_password.txt
new file mode 100644
index 0000000..11bff19
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/application/database_password.txt
@@ -0,0 +1 @@
+WJzesbe3poNZ91qIbmR7
diff --git a/demo/complex2/configs-and-secrets/midpoint/application/keystore_password.txt b/demo/complex2/configs-and-secrets/midpoint/application/keystore_password.txt
new file mode 100644
index 0000000..1d40192
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/application/keystore_password.txt
@@ -0,0 +1 @@
+changeit
diff --git a/demo/complex2/configs-and-secrets/midpoint/httpd/host-cert.pem b/demo/complex2/configs-and-secrets/midpoint/httpd/host-cert.pem
new file mode 100644
index 0000000..9b1021b
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/httpd/host-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAMOSkn4oS2aAMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXbWlkcG9pbnQuc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU1OTQ1WhcNMTkwOTE0MDU1OTQ1WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF21pZHBvaW50LnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApj/b7MEUSfu3oXMfNgRwTse7
+a5UV7Jswf1M/ZN/ZZkAkIxNBevZgozjesvLPWrmsTgONi7XigJUJvCjdjmlW9eDM
+lri/rkD8HuOR1DQCVKL9nvoS2c3D7sq5Emda3V8Tlj82VqfEmePd3sajx7mcTfbH
+8jwAL9NhkC+WMib5IpjLGpG0FEAC0ha7Lxb+7jIiqHVJaqLXJGCyGN4mh6c1Q9S1
+f8RVTiW2a8x22G+9wnZYbkiA2Kxls177imHlhSz8EdvV4IpGw1amrEWhhuDEum7B
+vZ1xQDLatgRqh4qAKLIVYeRnJ8H1FelMa90qB4G08MIPifmTsQwqJyBYaEdgWQID
+AQABo1MwUTAdBgNVHQ4EFgQUqb9BteODF6wv5R57aEON/wGXMiowHwYDVR0jBBgw
+FoAUqb9BteODF6wv5R57aEON/wGXMiowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAAcKhxI+tSItrXmqC0PSmgWyAYpqbkz6W/cefTutXqhIgY09f
+h0LSv7ogTahoGpyiZk9vy6u3OE9bYwxapEfa4KBjO6HxBMIVBBb3RegVjoPzjElN
+BDwAx0VGFcZTXwMxDWycWdG8ql7rCZBvS50w04uTaIgnGmqXAdWWmBgfJ9cRbxW+
+JwO/mOl1QM1lR/5142NpvuUVWlmZSKEGydE5A1qPz2wpDbBR1ym1BQNS4NEqw6Kp
+GSB8jKyCS1Ve0v2wVze2038Wukz02dq9uKPTIO3T+B+ibZmxn6Op/kFCc1/kK5NS
+Q6JdO1B6KquGAYdGmKAcQ19mv+jqGktqWEEf0g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2/configs-and-secrets/midpoint/httpd/host-key.pem b/demo/complex2/configs-and-secrets/midpoint/httpd/host-key.pem
new file mode 100644
index 0000000..5746e59
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmP9vswRRJ+7eh
+cx82BHBOx7trlRXsmzB/Uz9k39lmQCQjE0F69mCjON6y8s9auaxOA42LteKAlQm8
+KN2OaVb14MyWuL+uQPwe45HUNAJUov2e+hLZzcPuyrkSZ1rdXxOWPzZWp8SZ493e
+xqPHuZxN9sfyPAAv02GQL5YyJvkimMsakbQUQALSFrsvFv7uMiKodUlqotckYLIY
+3iaHpzVD1LV/xFVOJbZrzHbYb73CdlhuSIDYrGWzXvuKYeWFLPwR29XgikbDVqas
+RaGG4MS6bsG9nXFAMtq2BGqHioAoshVh5GcnwfUV6Uxr3SoHgbTwwg+J+ZOxDCon
+IFhoR2BZAgMBAAECggEAEIRBpjjceiku6jRUwnoYaks/nIWYQwR8AfpUTwJKR/VR
+Yca097Fokm7A+UhUP3A45RtHQb0VPq8P44iv0kk24YCu8r5yFK7SHYOAZnOwU5ZJ
+2jSAEPF3aM7tKh3okhuzB3dKP7u1NZDE5zAW723KUJiW7sL1RcsbY0bHBj6G+9/H
+NplmsjuGt684vRBB0qOBfKF7EiG7mT69tHuNj4gRza9SMY31UtKbZdt2fNY6mp5V
+HscMba7egZP+Ke0pVX4+go9j7K8GG8hYaQDLjrzlPqrxZ2c5X9cC+CRDI/CHuL/s
+V/2yGZJ6n6UabwZoH83RdFrbQ94rU8Hkli6EvxXvMQKBgQDRpheNW5jDG5TfeJKh
+yfKTDQqH2Tk3BsBYYBN7Hf3m7vbkzlxnAKJAoSLmtRMuoeXvI5MrhzaHGsNIUS76
+LDIZnvB7DLUxhFUZsCPkpAA1QHuTWY96oR3PHnPjpk8lSUvtbOPwDLdzVApeFJgZ
+VqMNArZ7AHsK3Kkyi+f4WVQjbQKBgQDLAWiGb5dx6fAM2W6B6HjNmzjBWOuVEXa2
+76to9jzupBZmETfZgxtWUaWUDuNS+f7dtVUTE+p6v/w8clrHEhEZYkqunIOLo/UA
+LFPiuoTfEsWb1rh+nsCjCgy4uimixj/bSkf7NC6NyKTvCygA1mGnVVJUEPegYlDy
+LXCkaKWxHQKBgQCmyHSKL2lrJkEcOwakEU2acNCE3Gno/cT9SYmV83kvQ8JEqmrW
+QqnRsp9aXIljGscapPmKsmnNt5vNp1AxFAHTYh88NRLczsMIyZj0ZwgHVUI6KhC7
+5Psa78YQQBlMt2/g9TSsnuE+rYgF6mpKFiNm0Vasqeg47uzn2mdzqlUGTQKBgE04
+JutkTUY+h1pL5vYxWKpVDfy19z7H2tFxT1FowPrBneeLSyRI88Ac5I/yLdRlVeY9
+0LOmEr5Igwj3MsKgg7KVKfVLgdo/LrW3Jt2Kt3onKNXDkoBPoNUjwH0QC0Boiue+
+VK0gR0kVdm+bXccbxR+im+NwZNE0NLg6Qqu3RredAoGBALuVoqbPPmTCZXYG328H
+bzOs2aiR7BzPSVByV+qG6jW7w03RAnFPJZp7HMU+ViI5VY0wabUscMSvz5163+gM
+4KwY3v9ZjZzZGukIfLuudkdqtaiVOx/KeAC0n+nG21YU+wpZww8gkfHh1/sa2CME
+CWYCgOnmiTHcj83UaTqEXtmv
+-----END PRIVATE KEY-----
diff --git a/demo/complex2/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml b/demo/complex2/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
new file mode 100644
index 0000000..4fa67a7
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex2/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml b/demo/complex2/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
new file mode 100644
index 0000000..ee05a97
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
@@ -0,0 +1,139 @@
+<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"    
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    clockSkew="180">
+
+    <!--
+    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
+    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
+    -->
+
+    <!--
+    To customize behavior for specific resources on Apache, and to link vhosts or
+    resources to ApplicationOverride settings below, use web server options/commands.
+    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
+    
+    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
+    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
+    -->
+    <TCPListener address="127.0.0.1" port="1600"/> 
+
+
+    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
+    <ApplicationDefaults entityID="https://midpointdemo/shibboleth"
+                         REMOTE_USER="uid">
+
+        <!--
+        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
+        You MUST supply an effectively unique handlerURL value for each of your applications.
+        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
+        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
+        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
+        Note that while we default checkAddress to "false", this has a negative impact on the
+        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
+        -->
+        <Sessions lifetime="28800" timeout="28800" relayState="ss:mem"
+                  checkAddress="false" handlerSSL="true" cookieProps="https">
+
+            <!--
+            Configures SSO for a default IdP. To allow for >1 IdP, remove
+            entityID property and adjust discoveryURL to point to discovery service.
+            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
+            You can also override entityID on /Login query string, or in RequestMap/htaccess.
+            -->
+		<SSO entityID="https://idptestbed/idp/shibboleth">
+			SAML2
+		</SSO>
+
+            <!-- SAML and local-only logout. -->
+            <Logout>SAML2 Local</Logout>
+            
+            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
+            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
+
+            <!-- Status reporting service. -->
+            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
+
+            <!-- Session diagnostic service. -->
+            <Handler type="Session" Location="/Session" showAttributeValues="true"/>
+
+            <!-- JSON feed of discovery information. -->
+            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
+        </Sessions>
+
+        <!--
+        Allows overriding of error template information/filenames. You can
+        also add attributes with values that can be plugged into the templates.
+        -->
+        <Errors supportContact="root@localhost"
+            helpLocation="/about.html"
+            styleSheet="/shibboleth-sp/main.css"/>
+        
+        <!-- Example of remotely supplied batch of signed metadata. -->
+        <!--
+        <MetadataProvider type="XML" validate="true"
+	      uri="http://example.org/federation-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <MetadataProvider type="XML" validate="true" file="idp-metadata.xml"/>
+
+        <!--
+        InCommon
+	  <MetadataProvider type="XML" validate="true"
+		uri="http://md.incommon.org/InCommon/InCommon-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+		<MetdataFilter type="Signature" certificate="inc-md-cert.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <!-- Map to extract attributes from SAML assertions. -->
+        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
+        
+        <!-- Use a SAML query if no attributes are supplied during SSO. -->
+        <AttributeResolver type="Query" subjectMatch="true"/>
+
+        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
+        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
+
+        <!-- Simple file-based resolvers for separate signing/encryption keys. -->
+        <CredentialResolver type="File" use="signing"
+            key="sp-signing-key.pem" certificate="sp-signing-cert.pem"/>
+        <CredentialResolver type="File" use="encryption"
+            key="sp-encrypt-key.pem" certificate="sp-encrypt-cert.pem"/>
+
+        <!--
+        The default settings can be overridden by creating ApplicationOverride elements (see
+        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
+        Resource requests are mapped by web server commands, or the RequestMapper, to an
+        applicationId setting.
+        
+        Example of a second application (for a second vhost) that has a different entityID.
+        Resources on the vhost would map to an applicationId of "admin":
+        -->
+        <!--
+        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
+        -->
+    </ApplicationDefaults>
+    
+    <!-- Policies that determine how to process and authenticate runtime messages. -->
+    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
+
+    <!-- Low-level configuration about protocols and bindings available for use. -->
+    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
+
+</SPConfig>
diff --git a/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
new file mode 100644
index 0000000..7a66196
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAmWgAwIBAgIJAINng1bI63LGMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
+BAMTEnNwdGVzdC5leGFtcGxlLmVkdTAeFw0xODEyMjAyMjM4MDJaFw0yODEyMTcy
+MjM4MDJaMB0xGzAZBgNVBAMTEnNwdGVzdC5leGFtcGxlLmVkdTCCAaIwDQYJKoZI
+hvcNAQEBBQADggGPADCCAYoCggGBAOjmPSBzRsjbPBBA6jYVW+QtsYM5fvIuNErG
+VDRvKHyCTNbmdFZ37qEl/fwsrdF4hn4V7fAZ6jW6R1aMGFl1vQyJ289B8l5HOPjf
+GuB2gL9IxulOmrkYVN8nfgjlbFNNktMQJ8NprYEyl3o786xCCxx3AiA5Mgdv400L
+6vlmEfNHIwsOHAUTNRyCwMS9P6jBJ5IIxD0Mef+3oUjAvVsPZu24EJnzTUasZnI0
+F8aC/YzVbxObBNcymtA2Ipec/gLe1B09eDZUduXPL/as57QWvgJrWj8bCK+Ldj0P
+MPSvWzr4BnN58dxaYgCgRH7tnhZudPvCjBakQzkxo/njsRIKtm3lN9UmUYiXbl+e
+bu0DSQFUaFfO2hOOUTNAr/QuC+GQL+U7VAdybTbP+KcH5LbNUSqYkxSwhbFz5aym
+o5KppnYB9K5iySRWvGIhnwXHNv5yFrmUbet2BPJlMzv7NaePaZ76ypobzNjjNBbg
+aNECsQ1ZD9fe2Q8UBe0m2gQP5Yux5QIDAQABo0AwPjAdBgNVHREEFjAUghJzcHRl
+c3QuZXhhbXBsZS5lZHUwHQYDVR0OBBYEFGcLIl5kg+GFIh9HXeZyLzsv5e7qMA0G
+CSqGSIb3DQEBCwUAA4IBgQAf8/iZXUWtWGMBw2OfonDDWbuhgLnNWddpllcVx7v/
+Yu75+wgfIdNXg6XM4WkGkpbhlkpDLRt2c6rMQpxrQtq/5G3OKEXKyjUOl5pZsYkG
+asVENYPSCfuu3rlK85XaW3H1SSJqSax/UKcYXyB1TIW6mNy3OxuvHak6y4LzFnug
+CO7p/W2jvffwmxfqjbO7wQfXUQz3SZS04sHMqQoStOwy2N5xxQ3uTF34EoXBto+n
+XIEOptKPhV2NkEzj+UUIi1588dck8T0SstbSElbTnJ4sNZFriX6JOPFNW08fezot
+izerOHuAFpFQvtugWoZT87YYaFwG+Zr5QNa4fNOcAL+FHvbOfEqIGs+H6GSf0dZV
+lkcJyzWZvuK/4RGqWbLvfAYRm0PAGTQSLdO8QJSYWdJtJvZFEMgddQ2HoIzeO5wo
+B42FKDSHottI9avilApQBdRCtust8XRPtEAzDB/t/1jbO7u2tkzgY3614mX5xgut
+Ileaae5eVCjw4uYbkh+Mt5M=
+-----END CERTIFICATE-----
diff --git a/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
new file mode 100644
index 0000000..1622ef3
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDo5j0gc0bI2zwQ
+QOo2FVvkLbGDOX7yLjRKxlQ0byh8gkzW5nRWd+6hJf38LK3ReIZ+Fe3wGeo1ukdW
+jBhZdb0MidvPQfJeRzj43xrgdoC/SMbpTpq5GFTfJ34I5WxTTZLTECfDaa2BMpd6
+O/OsQgscdwIgOTIHb+NNC+r5ZhHzRyMLDhwFEzUcgsDEvT+owSeSCMQ9DHn/t6FI
+wL1bD2btuBCZ801GrGZyNBfGgv2M1W8TmwTXMprQNiKXnP4C3tQdPXg2VHblzy/2
+rOe0Fr4Ca1o/Gwivi3Y9DzD0r1s6+AZzefHcWmIAoER+7Z4WbnT7wowWpEM5MaP5
+47ESCrZt5TfVJlGIl25fnm7tA0kBVGhXztoTjlEzQK/0LgvhkC/lO1QHcm02z/in
+B+S2zVEqmJMUsIWxc+WspqOSqaZ2AfSuYskkVrxiIZ8Fxzb+cha5lG3rdgTyZTM7
++zWnj2me+sqaG8zY4zQW4GjRArENWQ/X3tkPFAXtJtoED+WLseUCAwEAAQKCAYBM
+3eCC20kbdbAnNSWX4AjKEIKr6sgJKlK78yVLgPx9y4uMydbPyxmJOj7PgfeEUSEi
+cB5txj/Up7xvxiErNX7FqqJPj1Zs41jcWtZGCxaHC4AK9JSATpWEaUZhrUbJX6r7
+2jMlfbV0FLyF7U+JJOsB5A1hkT7/0V/Vx/8vfQ6jmnDobym0SxiWZlk1Fbjy+30R
+567M71c8nOCwYFyet0CjaMKh7PkuQCw3uRW3wPfqCW91qw438E3ENnnITFpRnDUI
+iZIXJSj3Sqcx/W7Q6xei+y95U4tksT3/SQ7hVXp+BhfyjXdK/k0vNzxZfWk9nCD8
+h7HeiQuLPENzrlOwuWtI+gLDIdFplXUJ+/piK3okdstdHJcWcNUelW8yr7JSpv1I
+a2KMgHI2F4UVcTYLZrevzxd5a0cpvFW7vmvdw2vFrCb5JsVsmqBu5OLeaVGDIbIA
+2SLfJqq12fi2rxk28VtwXXgaCTttSM+8VY7dlT/mPCqX3Sx2eM7EPt6RVHuri4EC
+gcEA+3q6Vht60YXNaw7m4BFISntVm4Z2gGFNswLlrgPRHOacaQVMKhpqt3HmNKAT
+1MD/a5C60HkUjMB95m2nE4k1Iade8EzUPXD1FvFbE9/+ifNx2OrC8pKrEmRiTmCY
+oel45uoXsksNGJynfuRp2TpAVSZrXaIbGKZiMJZv0QZAilVBurZnZyV0jKQYkSFM
+FOt60PDJJEqZzG01dvDJxsIYQURtjNscO0R2ncloLXm7qu1/fcP7CAawWgFYyer2
+WEdVAoHBAO0WAhxCvFoev348Wf33lQi9c6w7WN/WEkhNOJ5p4PKsJphSZbt2bjCt
+RdRmvahSXeiGrDPuaxoWaQqcXprcu3ndFYBcK2xZpIl/mf0wr1QTEHCkRXzfxRjC
+Mmy+yTeKT4L18xKgg6pJn+wC3hwsv2BQPkp+NPJhD2bmVUWorqXq5fiBV2b7lTg0
+q1HHXYtxk22bw7xtstFENGTqa22KwD5Wd6nj9DamLzKhUhOdcJ7yGVu9se7YcGGh
+pg57muigUQKBwQD5feH96Zdo5UFN9GPTavH4ivH8sWNBrMeEUNyDTuAYtyX3/zx4
+DOtRAhwsm5/xFGSTV+wvReDAX3zIroLym85ti/phlyd9qWJOl7cPOcvzGuYZGZe9
+RwuX3KW3MphbEiFTnm1SAqmEgG6gMoZc8DDBCbO9GkWdp/yETcuzaWuAkmL6lVpy
+97LwkSCaY5lyq8iWIDy915FMQhCn5u2YVhnwLq4s73jLx/mSQy4q57nrM2Kn6FZV
+uSUetnVbJdOu810CgcBNCzbaWjF9E7rk2dXguwD6Wx5o3MxPyPAeAMIicIPCOIE+
+RKB8n8rFFLm5gT2mokWUF5eENLknPBsccJ4pswtVWavwD4Oo7SST7hxrc9O1/Y/9
+GtTd9JXHKuxZ/FHFM7QM+cHozrKattw6ROBKxZvXP5xOdt7b2QC5TqZtQZinoELl
+U5rEg4MFRdBafe//LYRcPR8Jb5iJeqGQHcGVUl6Qo2a1lbc5vx1dVaEncKU1cbUd
+4/IbjMhQYchlsnMvn1ECgcEAxwT/UvLwhYeFK6UHRwJ/z1eKGAC8R2B9tlmgddZx
+T93qbVq4lZXKw3osqdi+pgWvvmg9aK9r/dO1E93S11msnoTI+W9xTr+y5y9dN/hx
+5deQMUK+3woLog6LsGiKE2IamCNQBFkgd4VvhXgG+2pTPYJ9nyuEA+na+tfE6bSa
+foJ8KQT1rmRFQYRboBY/xxqtsl6Nh84JK7kCw27NNdhssyuiipfa8NLM4m+yeA6n
+/oz8xKl5PKwOrvk2DH+FwaAg
+-----END PRIVATE KEY-----
diff --git a/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
new file mode 100644
index 0000000..73aaaab
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAmWgAwIBAgIJAJZqOL69C6nRMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
+BAMTEnNwdGVzdC5leGFtcGxlLmVkdTAeFw0xODEyMjAyMjM4NDhaFw0yODEyMTcy
+MjM4NDhaMB0xGzAZBgNVBAMTEnNwdGVzdC5leGFtcGxlLmVkdTCCAaIwDQYJKoZI
+hvcNAQEBBQADggGPADCCAYoCggGBANJ1OC6Ql4te2/7PArBkuM/EF1NcQILv7bJa
+ecJDGYBVoWgL0a2KQ0XMESusgkVmVjj/jcbtvwIiXI/6BEu815OF6eSZIwxWdQBp
+eKbrWTbt07GiGgdXoXot6oMs5a9YXuWLt8pTXrFVMmwXU+ZfWJtuU8OIgm9esAEI
+QBHvDVOJtdKdBMWJFa5nUzkaVvA0Fr8r+/FHUvSCnlKOMaUIfTgtoS9AQnaRQ1dV
+l39Z2KAh87JYvRIxvbaPaKgar2eGQ+PQD8rqsB5K5wgnADAxYM9Vo0YXSpPH+Fvw
+N3EJgURUSEY2E0Jx8JOx368ERNLXx3kfnRxCiZRDkTZF9WP6lBnDwc1WXRwpVCDT
+RnF+SIh6IC1Bj/qpkpCD3nri7tycejoeAtVj1YZHWarf9iqdcLYOAWmeyGbFl3hj
+v6qcXnIfy1KyHLCAdIrg1TymLovXXKW09pEbVLdsHmLz0h+DxPs4FsinK2AQBMn1
+6u8BJJ/+spCzIQ2QNPcGORh6XemBpQIDAQABo0AwPjAdBgNVHREEFjAUghJzcHRl
+c3QuZXhhbXBsZS5lZHUwHQYDVR0OBBYEFPC8rkASWHQxrtCQ4wwtnsJRy6K5MA0G
+CSqGSIb3DQEBCwUAA4IBgQCks2nY7YzdIKV02NHD9STWD3yPtEwPYZZ3NBno0WW2
+0rS6cU+fxFx37nY8ULve4cFQkLR8fOO44e1qIuTgLGCauSGTx/Ts/tbmZXbpGTwV
+7cjZDCfC7yEFAVrfQFOMNKeQEssuLFj+d4STGLorxsM+2YygdOgohJz0e3xOcmCN
+HqEuC9RbzrnLc/A4/mOHKwnwCCg71zA1/Ew9NUoRm2n8IfaONIUaMg9opNiHxX4e
+u3UFaaPmn/mInuWYYMXzbIbdlU/XhKvXrujWYWj7anTDWvGQmNEecsQH92SrO0pf
++9WwcWUQTQiWUdq8/OxjXfzs1PrQnSlp0eizgcdKHDKbCUaSuK1i2wdxfEsu5sbZ
+AIW0+dXJ2IyzM+0sv2g4DOsXsnSvinGqjr82A54mXGSr7edhPdlQhILFkJfhTwLq
++mjnyQSNe3s24VNeGc76jbHIrkEWuA460QGqz1Fa2CsQo5SH1IkxNIKpBZWt+w2L
+dAza/NzYyDruY5IJCrZa9Qw=
+-----END CERTIFICATE-----
diff --git a/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
new file mode 100644
index 0000000..9e979fe
--- /dev/null
+++ b/demo/complex2/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDSdTgukJeLXtv+
+zwKwZLjPxBdTXECC7+2yWnnCQxmAVaFoC9GtikNFzBErrIJFZlY4/43G7b8CIlyP
++gRLvNeThenkmSMMVnUAaXim61k27dOxohoHV6F6LeqDLOWvWF7li7fKU16xVTJs
+F1PmX1ibblPDiIJvXrABCEAR7w1TibXSnQTFiRWuZ1M5GlbwNBa/K/vxR1L0gp5S
+jjGlCH04LaEvQEJ2kUNXVZd/WdigIfOyWL0SMb22j2ioGq9nhkPj0A/K6rAeSucI
+JwAwMWDPVaNGF0qTx/hb8DdxCYFEVEhGNhNCcfCTsd+vBETS18d5H50cQomUQ5E2
+RfVj+pQZw8HNVl0cKVQg00ZxfkiIeiAtQY/6qZKQg9564u7cnHo6HgLVY9WGR1mq
+3/YqnXC2DgFpnshmxZd4Y7+qnF5yH8tSshywgHSK4NU8pi6L11yltPaRG1S3bB5i
+89Ifg8T7OBbIpytgEATJ9ervASSf/rKQsyENkDT3BjkYel3pgaUCAwEAAQKCAYEA
+kmBxGQH8RTVO8eTtS95iJC+QwavyOp/BxUDkWtbsj7P/NSyzQ25c59jNQIEVgktx
+QOeNpoSJS2S22HTeNAc+MR781MAl/ljLu+OfxQj/3hKAIJZMYDr01tPEvkOl5NUj
++6e3xwNBYzmMfl2jPyGlsUWFAQSbI/bJl44zccXAkQ/A5KHNRc7Yw5qd6aOGQD8a
+axCehOxEqEeI8oZvxQcogMBL0V9yWqEiI0Ymvq6w2n+CzdKmflcWSjloYzNcODbL
+Ef2+8/fBZhHTS0GLCIqQpK+tZxt4K77DK2p2L9dYuHK7vtWn1j0YIwPqD+QVVtuT
+d7BOOmakPj2E7EXq/GvFw8gB/gRLoLuJSq5vvhPrSVuJqWdxDuxSutGgIoN3mQxd
+2AjuBXvqwYaZ3UGHZlBYAQx5ICiAGjxv/1zmKp+9OJHge/a1e6Z8jgQcpS7OWNhU
+dj6qfs+IiWKEaMM7D8dj4ncoArBpE7/BzlVuJ377cqRx35alMcKlawQWF1YqSDrB
+AoHBAPSipCLz4sr3U2jluXehntYsKevWcBtFkEd49Ay5uZTu/aweKWIozjDt7T3L
+mjYi+QGpt28MdNmpoofYOmpt+lrc0HWrv+UB9k/qFxfwgZKaXa1nm/VLfK77L4IB
+8I9dpjvDi724Xg/JJ1jsGM13+jGEfTQTl4Hi0lZwMydUO+O4oWB4kG9qhF8C+yQc
+12CCFH+Da8uwcwM+zCJwRm3qMKceifhEGAuFJ430Rp7cuqlJYfQZ4pVhRxwP6vns
+cLCz+QKBwQDcPB5bCjci/HMe0V19HxPrKh0hGPLIRCPAakT8Mz8N2lVAtWDXFL5q
+eHskl6cf8RQLfrcUiL+jQvD5VV8I7BkolCv0GZT/q36I/Z1QKlQC1O0IGG/hNqwt
+PS85YM6yC84YIKx0rN6O03/nYcslRv19q+MNiR9sZEeN6cScUc6aUINhWjzQ4mb8
+Z9ErguJrq0sCoAVU+t/yRo/YB/d2xdN9XLe+2cgsM6s0TiHo4v2SeFHKewBw+RLp
+yrShY6COzg0CgcEA0EFwt2ylgiGgeSkvhV8qJ6s7GNDZaO4EUEPwhrDJAredbhvT
+IQQZ29+AWl3sbu/AySCgzsFs7CsT+M8jk50CRr26HKJUXvEXrZpbhH6y34nX+5m7
+U8uqXg/ptqROFM4liLUETkMYmBmnDHUY/DmJ3QOrzlxrWyAr7XfgpDd6MHbpsoWQ
+d7jW7UdNYsXGuBqktpS7fJA+qOGZyCuKWWHHf01pKNdXHN+C976fK/g+U4TsBXDP
+ylkgvwvx/kbA/DyJAoHAQxXA/WRYNT0G6B1ISAO+coTKiLlrwtsWtNbqGpSVoWef
+Tm2xiPKVqiL3B8d2LgGmZHX92LBrB5UtiBWcNECOzVCNLvbX7yVTDvGKCNBL9Ozd
+Ivkmo0ifG8ymZOj7LTrxVWImhgfeZ00/icC9O6arMqu4Jvhc7QyCy1SpAiDdOR5L
+Vs1A9zPvwPTyvzlINRnhaHRMC32717XsvRZ4J+LMsEQc6HK4SdaXUQB3zdPO/93M
+tEvRb5g/TZ3kdcC+OKHFAoHAO9R3y6ZjUM8T8/4XcyRD968V4sZIvVQfpSaH86GO
+TrECZp5SqSWUTqAWTJWS0yIctAML60nWF+OPRUlrq0yk2veN9Re6eWfyoyQOFd92
+U+bxh3QEue5LGOwpqrPV/1cJSFdv88eS+F8q7i/dD765Tio6kJjKzXPN3FJqAvNB
+lAnaO4Apbuzob25Qkmm0NVQHap+TJGJMvX2vVX9CjE6haVWq1lJMakkoQOeIlyi5
+iDjt9rDlIwDYeGWk4KFgsKM7
+-----END PRIVATE KEY-----
diff --git a/demo/complex2/create-ref-loaders.gsh b/demo/complex2/create-ref-loaders.gsh
new file mode 100644
index 0000000..0cfdcdf
--- /dev/null
+++ b/demo/complex2/create-ref-loaders.gsh
@@ -0,0 +1,31 @@
+gs = GrouperSession.startRootSession()
+
+group = new GroupSave(gs).assignName("etc:affiliationLoader").assignCreateParentStemsIfNotExist(true).save()
+group.addType(GroupTypeFinder.find("grouperLoader"))
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderType", "SQL_GROUP_LIST")
+group.setAttribute("grouperLoaderScheduleType", "CRON")
+group.setAttribute("grouperLoaderQuartzCron", "0 * * * * ?")
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderGroupTypes", "addIncludeExclude")
+group.setAttribute("grouperLoaderQuery", "SELECT concat('ref:affiliation:',affiliation,'_systemOfRecord') as GROUP_NAME, uid as SUBJECT_ID, 'ldap' as SUBJECT_SOURCE_ID from SIS_AFFILIATIONS")
+
+group = new GroupSave(gs).assignName("etc:deptLoader").assignCreateParentStemsIfNotExist(true).save()
+group.addType(GroupTypeFinder.find("grouperLoader"))
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderType", "SQL_GROUP_LIST")
+group.setAttribute("grouperLoaderScheduleType", "CRON")
+group.setAttribute("grouperLoaderQuartzCron", "0 * * * * ?")
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderQuery", "SELECT concat('ref:dept:',department) as GROUP_NAME, uid as SUBJECT_ID, 'ldap' as SUBJECT_SOURCE_ID from SIS_PERSONS where department is not null")
+
+group = new GroupSave(gs).assignName("etc:coursesLoader").assignCreateParentStemsIfNotExist(true).save()
+group.addType(GroupTypeFinder.find("grouperLoader"))
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderType", "SQL_GROUP_LIST")
+group.setAttribute("grouperLoaderScheduleType", "CRON")
+group.setAttribute("grouperLoaderQuartzCron", "0 * * * * ?")
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderQuery", "SELECT concat('ref:course:',courseId) as GROUP_NAME, uid as SUBJECT_ID, 'ldap' as SUBJECT_SOURCE_ID from SIS_COURSES")
+
+edu.internet2.middleware.grouper.app.loader.GrouperLoaderType.scheduleLoads()
diff --git a/demo/complex2/create-ref-loaders.sh b/demo/complex2/create-ref-loaders.sh
new file mode 100755
index 0000000..627a186
--- /dev/null
+++ b/demo/complex2/create-ref-loaders.sh
@@ -0,0 +1,3 @@
+source ../../library.bash
+
+execute_gsh complex2_grouper_daemon_1 create-ref-loaders.gsh
diff --git a/demo/complex2/directory/Dockerfile b/demo/complex2/directory/Dockerfile
new file mode 100644
index 0000000..5df66ad
--- /dev/null
+++ b/demo/complex2/directory/Dockerfile
@@ -0,0 +1,28 @@
+FROM centos:centos7
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+RUN yum install -y epel-release \
+    && yum update -y \
+    && yum install -y 389-ds-base 389-admin 389-adminutil \
+    && yum clean all \
+    && rm -rf /var/cache/yum
+
+COPY container_files/seed-data/ /seed-data/
+
+RUN useradd ldapadmin \
+    && rm -fr /var/lock /usr/lib/systemd/system \
+    # The 389-ds setup will fail because the hostname can't reliable be determined, so we'll bypass it and then install. \
+    && sed -i 's/checkHostname {/checkHostname {\nreturn();/g' /usr/lib64/dirsrv/perl/DSUtil.pm \
+    # Not doing SELinux \
+    && sed -i 's/updateSelinuxPolicy($inf);//g' /usr/lib64/dirsrv/perl/* \
+    # Do not restart at the end \
+    && sed -i '/if (@errs = startServer($inf))/,/}/d' /usr/lib64/dirsrv/perl/* \
+    && setup-ds.pl --silent --file /seed-data/ds-setup.inf \
+    && /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir \
+    && while ! curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to start; sleep 1; done; \
+    ldapadd -H ldap:/// -f /seed-data/users.ldif -x -D "cn=Directory Manager" -w password
+
+EXPOSE 389
+
+CMD rm -rf /var/lock/dirsrv/slapd-dir/server/* && /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir && sleep infinity
diff --git a/demo/complex2/directory/container_files/seed-data/ds-setup.inf b/demo/complex2/directory/container_files/seed-data/ds-setup.inf
new file mode 100644
index 0000000..96c29a1
--- /dev/null
+++ b/demo/complex2/directory/container_files/seed-data/ds-setup.inf
@@ -0,0 +1,28 @@
+[General]
+AdminDomain = internet2.edu
+ConfigDirectoryAdminID = admin
+ConfigDirectoryAdminPwd = admin
+ConfigDirectoryLdapURL = ldap://localhost:389/o=NetscapeRoot
+FullMachineName = localhost
+ServerRoot = /usr/lib64/dirsrv
+SuiteSpotGroup = nobody
+SuiteSpotUserID = nobody
+
+[admin]
+Port = 9830
+ServerAdminID = admin
+ServerAdminPwd = admin
+ServerIpAddress = 0.0.0.0
+SysUser = nobody
+
+[slapd]
+AddOrgEntries = No
+AddSampleEntries = No
+InstallLdifFile = suggest
+RootDN = cn=Directory Manager
+RootDNPwd = password
+ServerIdentifier = dir
+ServerPort = 389
+SlapdConfigForMC = yes
+Suffix = dc=internet2,dc=edu
+UseExistingMC = No
diff --git a/demo/complex2/directory/container_files/seed-data/users.ldif b/demo/complex2/directory/container_files/seed-data/users.ldif
new file mode 100644
index 0000000..383b1b7
--- /dev/null
+++ b/demo/complex2/directory/container_files/seed-data/users.ldif
@@ -0,0 +1,35 @@
+dn: cn=admin,dc=internet2,dc=edu
+objectClass: simpleSecurityObject
+objectClass: organizationalRole
+cn: admin
+userPassword: password
+description: LDAP administrator
+
+dn: cn=users,ou=Groups,dc=internet2,dc=edu
+objectClass: groupOfUniqueNames
+objectClass: top
+uniqueMember: uid=banderson,ou=People,dc=internet2,dc=edu
+uniqueMember: uid=jsmith,ou=People,dc=internet2,dc=edu
+cn: users
+
+dn: ou=Affiliations,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Affiliations
+
+dn: ou=Courses,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Courses
+
+dn: ou=midpoint,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: midpoint
+
+dn: ou=Generic,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Generic
+
+
diff --git a/demo/complex2/docker-compose.yml b/demo/complex2/docker-compose.yml
new file mode 100644
index 0000000..d35f63e
--- /dev/null
+++ b/demo/complex2/docker-compose.yml
@@ -0,0 +1,307 @@
+version: "3.3"
+
+services:
+  grouper_daemon:
+    build: ./grouper_daemon/
+    command: bash -c "while ! curl -s grouper_data:3306 > /dev/null; do echo waiting for mysql on grouper_data to start; sleep 3; done; while ! curl -s ldap://directory:389 > /dev/null; do echo waiting for ldap on directory to start; sleep 3; done; exec daemon"
+    depends_on:
+     - grouper_data
+     - directory
+    environment:
+     - ENV
+     - USERTOKEN
+     - GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE=password
+     - GROUPER_DATABASE_PASSWORD_FILE=/run/secrets/g_database_password.txt
+     - RABBITMQ_PASSWORD_FILE=/run/secrets/rabbitmq_password.txt
+     - SUBJECT_SOURCE_LDAP_PASSWORD=password
+    networks:
+      net:
+        aliases:
+         - grouper-daemon
+    secrets:
+     - g_database_password.txt
+     - rabbitmq_password.txt
+     - source: grouper.hibernate.properties
+       target: grouper_grouper.hibernate.properties
+     - source: grouper-loader.properties
+       target: grouper_grouper-loader.properties
+     - source: subject.properties
+       target: grouper_subject.properties
+    volumes:
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.properties
+       target: /opt/grouper/conf/grouper.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.client.properties
+       target: /opt/grouper/conf/grouper.client.properties
+
+  grouper_ui:
+    build: ./grouper_ui/
+    command: bash -c "while ! curl -s grouper_data:3306 > /dev/null; do echo waiting for mysql on grouper_data to start; sleep 3; done; while ! curl -s ldap://directory:389 > /dev/null; do echo waiting for ldap on directory to start; sleep 3; done; exec ui"
+    depends_on:
+     - grouper_data
+     - directory
+    environment:
+     - ENV
+     - USERTOKEN
+     - GROUPER_DATABASE_PASSWORD_FILE=/run/secrets/g_database_password.txt
+     - SUBJECT_SOURCE_LDAP_PASSWORD=password
+    networks:
+      net:
+        aliases:
+         - grouper-ui
+    ports:
+     - 4443:443
+    secrets:
+     - g_database_password.txt
+     - source: grouper.hibernate.properties
+       target: grouper_grouper.hibernate.properties
+     - source: grouper-loader.properties
+       target: grouper_grouper-loader.properties
+     - source: subject.properties
+       target: grouper_subject.properties
+     - source: g_sp-key.pem
+       target: shib_sp-key.pem
+     - source: g_host-key.pem
+       target: host-key.pem
+    volumes:
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.properties
+       target: /opt/grouper/conf/grouper.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.client.properties
+       target: /opt/grouper/conf/grouper.client.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/shibboleth/sp-cert.pem
+       target: /etc/shibboleth/sp-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/grouper/shibboleth/shibboleth2.xml
+       target: /etc/shibboleth/shibboleth2.xml
+     - type: bind
+       source: ./configs-and-secrets/grouper/shibboleth/idp-metadata.xml
+       target: /etc/shibboleth/idp-metadata.xml
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  grouper_ws:
+    build: ./grouper_ws/
+    command: bash -c "while ! curl -s grouper_data:3306 > /dev/null; do echo waiting for mysql to start; sleep 3; done; while ! curl -s ldap://directory:389 > /dev/null; do echo waiting for ldap to start; sleep 3; done; exec ws"
+    depends_on:
+     - grouper_data
+     - directory
+    environment:
+     - ENV
+     - GROUPER_DATABASE_PASSWORD_FILE=/run/secrets/g_database_password.txt
+     - SUBJECT_SOURCE_LDAP_PASSWORD=password
+     - USERTOKEN
+    networks:
+      net:
+        aliases:
+         - grouper-ws
+    ports:
+     - 9443:443
+    secrets:
+     - g_database_password.txt
+     - source: grouper.hibernate.properties
+       target: grouper_grouper.hibernate.properties
+     - source: grouper-loader.properties
+       target: grouper_grouper-loader.properties
+     - source: subject.properties
+       target: grouper_subject.properties
+     - source: g_sp-key.pem
+       target: shib_sp-key.pem
+     - source: g_host-key.pem
+       target: host-key.pem
+    volumes:
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.properties
+       target: /opt/grouper/conf/grouper.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.client.properties
+       target: /opt/grouper/conf/grouper.client.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  grouper_data:
+    build: ./grouper_data/
+    networks:
+      net:
+        aliases:
+         - grouper-data
+    ports:
+     - 3306:3306
+    volumes:
+     - grouper_data:/var/lib/mysql  
+
+  directory:
+    build: ./directory/
+    ports:
+     - 389:389
+    networks:
+     - net
+    volumes:
+     - ldap:/var/lib/dirsrv
+
+  sources:
+    build: ./sources/
+    ports:
+     - 13306:3306
+    networks:
+     - net
+    volumes:
+     - source_data:/var/lib/mysql
+
+  targets:
+    build: ./targets/
+    ports:
+     - 23306:389
+    networks:
+     - net
+    volumes:
+     - target_data:/var/lib/mysql
+
+  midpoint_data:
+    image: tier/mariadb:mariadb10
+    ports:
+     - 33306:3306
+    networks:
+      net:
+        aliases:
+         - midpoint-data
+    volumes:
+     - midpoint_mysql:/var/lib/mysql
+     - midpoint_data:/var/lib/mysqlmounted
+    environment:
+     - CREATE_NEW_DATABASE=if_needed
+
+  midpoint_server:
+    build: ./midpoint_server/
+    depends_on:
+     - midpoint_data
+    ports:
+     - 8443:443
+    environment:
+     - AUTHENTICATION
+     - ENV
+     - USERTOKEN
+     - REPO_DATABASE_TYPE
+     - REPO_JDBC_URL
+     - REPO_HOST
+     - REPO_PORT
+     - REPO_DATABASE
+     - REPO_USER
+     - REPO_MISSING_SCHEMA_ACTION
+     - REPO_UPGRADEABLE_SCHEMA_ACTION
+     - REPO_SCHEMA_VERSION_IF_MISSING
+     - REPO_SCHEMA_VARIANT
+     - MP_MEM_MAX
+     - MP_MEM_INIT
+     - MP_JAVA_OPTS
+     - SSO_HEADER
+     - TIER_BEACON_OPT_OUT
+     - TIMEZONE
+    networks:
+      net:
+        aliases:
+         - midpoint-server
+    secrets:
+     - mp_database_password.txt
+     - mp_keystore_password.txt
+     - mp_sp-encrypt-key.pem
+     - mp_sp-signing-key.pem
+     - mp_host-key.pem
+    volumes:
+     - midpoint_home:/opt/midpoint/var
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
+       target: /etc/shibboleth/shibboleth2.xml
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
+       target: /etc/shibboleth/idp-metadata.xml
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
+       target: /etc/shibboleth/sp-signing-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
+       target: /etc/shibboleth/sp-encrypt-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  idp:
+    build: ./idp/
+    depends_on:
+     - directory
+    environment:
+     - JETTY_MAX_HEAP=64m
+     - JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=password
+     - JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=password
+    networks:
+     - net
+    ports:
+     - 443:443
+
+  mq:
+    build: ./mq/
+    environment:
+     - RABBITMQ_NODENAME=docker-rabbit
+    hostname: rabbitmq
+    networks:
+     - net
+    ports:
+     - 15672:15672
+    volumes:
+     - mq:/var/lib/rabbitmq
+
+networks:
+  net:    
+    driver: bridge
+
+secrets:
+# grouper
+  g_host-key.pem:
+    file: ./configs-and-secrets/grouper/httpd/host-key.pem
+  g_sp-key.pem:
+    file: ./configs-and-secrets/grouper/shibboleth/sp-key.pem
+  g_database_password.txt:
+    file: ./configs-and-secrets/grouper/application/database_password.txt
+  rabbitmq_password.txt:
+    file: ./configs-and-secrets/grouper/application/rabbitmq_password.txt
+  grouper.hibernate.properties:
+    file: ./configs-and-secrets/grouper/application/grouper.hibernate.properties
+  grouper-loader.properties:
+    file: ./configs-and-secrets/grouper/application/grouper-loader.properties
+  subject.properties:
+    file: ./configs-and-secrets/grouper/application/subject.properties
+# midPoint
+  mp_host-key.pem:
+    file: ./configs-and-secrets/midpoint/httpd/host-key.pem
+  mp_sp-signing-key.pem:
+    file: ./configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
+  mp_sp-encrypt-key.pem:
+    file: ./configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
+  mp_database_password.txt:
+    file: ./configs-and-secrets/midpoint/application/database_password.txt
+  mp_keystore_password.txt:
+    file: ./configs-and-secrets/midpoint/application/keystore_password.txt    
+    
+volumes:
+  grouper_data:
+  source_data:
+  target_data:
+  ldap:
+  midpoint_data:
+  midpoint_mysql:
+  midpoint_home:
+  mq:
diff --git a/demo/complex2/get-import-sis-persons-status.sh b/demo/complex2/get-import-sis-persons-status.sh
new file mode 100755
index 0000000..26d3fcd
--- /dev/null
+++ b/demo/complex2/get-import-sis-persons-status.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+get_task_execution_status "Import from SIS persons"
diff --git a/demo/complex2/grouper_daemon/Dockerfile b/demo/complex2/grouper_daemon/Dockerfile
new file mode 100644
index 0000000..4ed3dc7
--- /dev/null
+++ b/demo/complex2/grouper_daemon/Dockerfile
@@ -0,0 +1,5 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+CMD ["daemon"]
diff --git a/demo/complex2/grouper_data/Dockerfile b/demo/complex2/grouper_data/Dockerfile
new file mode 100644
index 0000000..15d196a
--- /dev/null
+++ b/demo/complex2/grouper_data/Dockerfile
@@ -0,0 +1,40 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+RUN yum install -y epel-release \
+    && yum update -y \
+    && yum install -y mariadb-server mariadb \
+    && yum clean all \
+    && rm -rf /var/cache/yum
+
+COPY container_files/seed-data/ /seed-data/
+COPY container_files/conf/ /opt/grouper/grouper.apiBinary/conf/
+
+RUN mysql_install_db \
+    && chown -R mysql:mysql /var/lib/mysql/ \
+    && sed -i 's/^\(bind-address\s.*\)/# \1/' /etc/my.cnf \
+    && sed -i 's/^\(log_error\s.*\)/# \1/' /etc/my.cnf \
+    && sed -i 's/\[mysqld\]/\[mysqld\]\ncharacter_set_server = utf8/' /etc/my.cnf \
+    && sed -i 's/\[mysqld\]/\[mysqld\]\ncollation_server = utf8_general_ci/' /etc/my.cnf \
+    && sed -i 's/\[mysqld\]/\[mysqld\]\nport = 3306/' /etc/my.cnf \
+    && cat  /etc/my.cnf \
+    && echo "/usr/bin/mysqld_safe &" > /tmp/config \
+    && echo "mysqladmin --silent --wait=30 ping || exit 1" >> /tmp/config \
+    && echo "mysql -e 'GRANT ALL PRIVILEGES ON *.* TO \"root\"@\"%\" WITH GRANT OPTION;'" >> /tmp/config \
+    && echo "mysql -e 'CREATE DATABASE grouper CHARACTER SET utf8 COLLATE utf8_bin;'" >> /tmp/config \
+    && bash /tmp/config \
+    && rm -f /tmp/config
+
+RUN (mysqld_safe & ) \
+    && while ! curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to start; sleep 1; done; \
+    bin/gsh -registry -check -runscript -noprompt && \
+    echo "Running demo.gsh" && \
+    sleep 10 && \
+    bin/gsh /seed-data/demo.gsh && \
+    echo "demo.gsh DONE" && \
+    rm /seed-data/demo.gsh
+
+EXPOSE 3306
+
+CMD mysqld_safe
diff --git a/demo/complex2/grouper_data/container_files/conf/grouper-loader.properties b/demo/complex2/grouper_data/container_files/conf/grouper-loader.properties
new file mode 100644
index 0000000..777376c
--- /dev/null
+++ b/demo/complex2/grouper_data/container_files/conf/grouper-loader.properties
@@ -0,0 +1,64 @@
+#################################
+## LDAP connections
+#################################
+# specify the ldap connection with user, pass, url
+# the string after "ldap." is the ID of the connection, and it should not have
+# spaces or other special chars in it.  In this case is it "personLdap"
+
+#note the URL should start with ldap: or ldaps: if it is SSL.  
+#It should contain the server and port (optional if not default), and baseDn,
+#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu
+ldap.demo.url = ldap://directory:389/dc=internet2,dc=edu
+ 
+#optional, if authenticated
+ldap.demo.user = cn=admin,dc=internet2,dc=edu
+#ldap.demo.user = cn=admin
+ 
+#optional, if authenticated note the password can be stored encrypted in an external file
+#ldap.demo.pass = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+ldap.demo.pass = password
+ 
+#optional, if you are using tls, set this to true.  Generally you will not be using an SSL URL to use TLS...
+ldap.demo.tls = false
+ 
+#optional, if using sasl
+#ldap.personLdap.saslAuthorizationId =
+#ldap.personLdap.saslRealm =
+ 
+#optional (note, time limit is for search operations, timeout is for connection timeouts),
+#most of these default to vt-ldap defaults.  times are in millis
+#validateOnCheckout defaults to true if all other validate methods are false
+#ldap.personLdap.batchSize =
+#ldap.personLdap.countLimit =
+#ldap.personLdap.timeLimit =
+#ldap.personLdap.timeout =
+#ldap.personLdap.minPoolSize =
+#ldap.personLdap.maxPoolSize =
+#ldap.personLdap.validateOnCheckIn =
+#ldap.personLdap.validateOnCheckOut =
+#ldap.personLdap.validatePeriodically =
+#ldap.personLdap.validateTimerPeriod =
+#ldap.personLdap.pruneTimerPeriod =
+#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes)
+#ldap.personLdap.expirationTime =
+
+#make the paths fully qualified and not relative to the loader group.
+loader.ldap.requireTopStemAsStemFromConfigGroup=false
+
+#####################################
+## Messaging integration with change log
+#####################################
+changeLog.consumer.rabbitMqMessagingSample.quartzCron = 0 * * * * ?                                                          
+
+# note, change "messagingSample" in key to be the name of the consumer.  e.g. changeLog.consumer.someNameAnyName.class
+changeLog.consumer.rabbitMqMessagingSample.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer
+
+changeLog.consumer.rabbitMqMessagingSample.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher
+changeLog.consumer.rabbitMqMessagingSample.publisher.messagingSystemName = rabbitmq
+# note, routingKey property is valid only for rabbitmq. For other messaging systems, it is ignored.
+changeLog.consumer.rabbitMqMessagingSample.publisher.routingKey = 
+## queue or topic
+changeLog.consumer.rabbitMqMessagingSample.publisher.messageQueueType = queue
+changeLog.consumer.rabbitMqMessagingSample.publisher.queueOrTopicName = sampleQueue
+## this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml
+#changeLog.consumer.rabbitMqMessagingSample.publisher.addSubjectAttributes = email
diff --git a/demo/complex2/grouper_data/container_files/conf/grouper.hibernate.properties b/demo/complex2/grouper_data/container_files/conf/grouper.hibernate.properties
new file mode 100644
index 0000000..154b8eb
--- /dev/null
+++ b/demo/complex2/grouper_data/container_files/conf/grouper.hibernate.properties
@@ -0,0 +1,29 @@
+#
+# Grouper Hibernate Configuration
+# $Id: grouper.hibernate.example.properties,v 1.9 2009-08-11 20:18:09 mchyzer Exp $
+#
+
+# The grouper hibernate config uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.hibernate.base.properties
+# (which should not be edited), and the grouper.hibernate.properties overlays
+# the base settings.  See the grouper.hibernate.base.properties for the possible
+# settings that can be applied to the grouper.hibernate.properties
+
+########################################
+## DB settings
+########################################
+
+# e.g. mysql:           jdbc:mysql://localhost:3306/grouper
+# e.g. p6spy (log sql): [use the URL that your DB requires]
+# e.g. oracle:          jdbc:oracle:thin:@server.school.edu:1521:sid
+# e.g. hsqldb (a):      jdbc:hsqldb:dist/run/grouper;create=true
+# e.g. hsqldb (b):      jdbc:hsqldb:hsql://localhost:9001/grouper
+# e.g. postgres:        jdbc:postgresql://localhost:5432/database
+# e.g. mssql:           jdbc:sqlserver://localhost:3280;databaseName=grouper
+hibernate.connection.url = jdbc:mysql://localhost:3306/grouper?CharSet=utf8&useUnicode=true&characterEncoding=utf8
+
+hibernate.connection.username         = root
+# If you are using an empty password, depending upon your version of
+# Java and Ant you may need to specify a password of "".
+# Note: you can keep passwords external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122
+hibernate.connection.password =
diff --git a/demo/complex2/grouper_data/container_files/conf/grouper.properties b/demo/complex2/grouper_data/container_files/conf/grouper.properties
new file mode 100644
index 0000000..c931287
--- /dev/null
+++ b/demo/complex2/grouper_data/container_files/conf/grouper.properties
@@ -0,0 +1,25 @@
+#
+# Grouper Configuration
+# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $
+#
+
+# Grouper uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.base.properties
+# (which should not be edited), and the grouper.properties overlays
+# the base settings.  See the grouper.base.properties for the possible
+# settings that can be applied to the grouper.properties
+
+#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on)
+configuration.autocreate.system.groups = true
+
+# A wheel group allows you to enable non-GrouperSystem subjects to act
+# like a root user when interacting with the registry.
+groups.wheel.use                      = true
+
+# Set to the name of the group you want to treat as the wheel group.
+# The members of this group will be treated as root-like users.
+groups.wheel.group                    = etc:sysadmingroup
+
+# Used to allow Include Exclude groups
+grouperIncludeExclude.use = true
+grouperIncludeExclude.requireGroups.use = true
diff --git a/demo/complex2/grouper_data/container_files/conf/subject.properties b/demo/complex2/grouper_data/container_files/conf/subject.properties
new file mode 100644
index 0000000..4a31712
--- /dev/null
+++ b/demo/complex2/grouper_data/container_files/conf/subject.properties
@@ -0,0 +1,78 @@
+#subject.sources.xml.location =
+
+subjectApi.source.ldap.param.ldapServerId.value = demo
+
+subjectApi.source.ldap.id = ldap
+subjectApi.source.ldap.name = EDU Ldap 
+subjectApi.source.ldap.types = person
+subjectApi.source.ldap.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter
+#subjectApi.source.ldap.param.INITIAL_CONTEXT_FACTORY.value = com.sun.jndi.ldap.LdapCtxFactory
+#subjectApi.source.ldap.param.PROVIDER_URL.value = ldap://localhost:389
+#subjectApi.source.ldap.param.SECURITY_AUTHENTICATION.value = simple
+#subjectApi.source.ldap.param.SECURITY_PRINCIPAL.value = cn=admin,dc=internet2,dc=edu
+#subjectApi.source.ldap.param.SECURITY_CREDENTIALS.value = password
+#subjectApi.source.ldap.param.VTLDAP_VALIDATOR.value = ConnectLdapValidator
+
+subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid
+subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false
+subjectApi.source.ldap.param.Name_AttributeType.value = cn
+subjectApi.source.ldap.param.Description_AttributeType.value = cn
+subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")}
+subjectApi.source.ldap.param.sortAttribute0.value = cn
+subjectApi.source.ldap.param.searchAttribute0.value = searchAttribute0
+
+# STATUS SECTION for searches to filter out inactives and allow
+# the user to filter by status with e.g. status=all
+# this is optional, and advanced
+#
+# field in database or ldap or endpoint that is the status field
+#subjectApi.source.example.param.statusDatastoreFieldName.value = status
+
+# search string from user which represents the status.  e.g. status=active
+#subjectApi.source.example.param.statusLabel.value = status
+
+# available statuses from screen (if not specified, any will be allowed). comma separated list.
+# Note, this is optional and you probably dont want to configure it, it is mostly necessary
+# when you have multiple sources with statuses...  if someone types an invalid status
+# and you have this configured, it will not filter by it
+#subjectApi.source.example.param.statusesFromUser.value = Active, Inactive, Pending, All
+
+# all label from the user
+#subjectApi.source.example.param.statusAllFromUser.value = All
+
+# if no status is specified, this will be used (e.g. for active only).  Note, the value should be of the
+# form the user would type in
+#subjectApi.source.example.param.statusSearchDefault.value = status=active
+
+# translate between screen values of status, and the data store value.  Increment the 0 to 1, 2, etc for more translations.
+# so the user could enter: status=active, and that could translate to status_col=A.  The 'user' is what the user types in,
+# the 'datastore' is what is in the datastore.  The user part is not case-sensitive.  Note, this could be a many to one
+#subjectApi.source.example.param.statusTranslateUser0.value = active
+#subjectApi.source.example.param.statusTranslateDatastore0.value = A
+
+# subject identifier to store in grouper's member table.  this is used to increase speed of loader and perhaps for provisioning
+# you can have up to max 1 subject identifier
+#subjectApi.source.example.param.subjectIdentifierAttribute0.value = uid
+
+#searchSubject: find a subject by ID.  ID is generally an opaque and permanent identifier, e.g. 12345678.
+#  Each subject has one and only on ID.  Returns one result when searching for one ID.
+subjectApi.source.ldap.search.searchSubject.param.filter.value = (&(uid=%TERM%)(objectclass=person))
+subjectApi.source.ldap.search.searchSubject.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubject.param.base.value = ou=people
+
+#searchSubjectByIdentifier: find a subject by identifier.  Identifier is anything that uniquely
+#  identifies the user, e.g. jsmith or jsmith@institution.edu.
+#  Subjects can have multiple identifiers.  Note: it is nice to have if identifiers are unique
+#  even across sources.  Returns one result when searching for one identifier.
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.filter.value = (&(|(uid=%TERM%)(employeeNumber=%TERM%))(objectclass=person))
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.base.value = ou=people
+
+#   search: find subjects by free form search.  Returns multiple results.
+
+subjectApi.source.ldap.search.search.param.filter.value = (&(|(|(uid=%TERM%)(cn=*%TERM%*))(uid=%TERM%*))(objectclass=person))
+subjectApi.source.ldap.search.search.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.search.param.base.value = ou=people
+
+subjectApi.source.ldap.attributes = givenName, sn, uid, mail, employeeNumber
+subjectApi.source.ldap.internalAttributes = searchAttribute0
diff --git a/demo/complex2/grouper_data/container_files/seed-data/demo.gsh b/demo/complex2/grouper_data/container_files/seed-data/demo.gsh
new file mode 100644
index 0000000..c58d289
--- /dev/null
+++ b/demo/complex2/grouper_data/container_files/seed-data/demo.gsh
@@ -0,0 +1,41 @@
+System.out.println("************** demo.gsh starting...");
+
+gs = GrouperSession.startRootSession();
+
+addStem("", "app", "app")
+addStem("", "basis", "basis")
+addStem("", "bundle", "bundle")
+addStem("", "org", "org")
+addStem("", "test", "test")
+addStem("", "midpoint", "midpoint")
+
+addRootStem("ref", "ref")
+addStem("ref", "course", "course")
+addStem("ref", "affiliation", "affiliation")
+
+group = GroupFinder.findByName(gs, "etc:sysadmingroup", true);
+group.getAttributeDelegate().assignAttribute(LoaderLdapUtils.grouperLoaderLdapAttributeDefName()).getAttributeAssign();
+attributeAssign = group.getAttributeDelegate().retrieveAssignment(null, LoaderLdapUtils.grouperLoaderLdapAttributeDefName(), false, true);
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapQuartzCronName(), "0 * * * * ?");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapTypeName(), "LDAP_SIMPLE");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapFilterName(), "(cn=sysadmingroup)");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSearchDnName(), "ou=midpoint,ou=Groups");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapServerIdName(), "demo");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSourceIdName(), "ldap");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectExpressionName(), '${loaderLdapElUtils.convertDnToSpecificValue(subjectId)}');
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectAttributeName(), "uniqueMember");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectIdTypeName(), "subjectId");
+
+midpointGroupsGroup = new GroupSave(gs).assignName("etc:midpointGroups").assignCreateParentStemsIfNotExist(true).save();
+
+testGroup = new GroupSave(gs).assignName("midpoint:test").assignCreateParentStemsIfNotExist(true).save();
+chess = new GroupSave(gs).assignName("app:mailinglist:chess").assignCreateParentStemsIfNotExist(true).save()
+idmfans = new GroupSave(gs).assignName("app:mailinglist:idm-fans").assignCreateParentStemsIfNotExist(true).save()
+cs = new GroupSave(gs).assignName("app:cs").assignCreateParentStemsIfNotExist(true).save()
+volunteers = new GroupSave(gs).assignName("test:volunteers").assignCreateParentStemsIfNotExist(true).save()
+
+midpointGroupsGroup.addMember(SubjectFinder.findById(testGroup.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(chess.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(idmfans.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(cs.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(volunteers.getId(), 'group', 'g:gsa'), false)
diff --git a/demo/complex2/grouper_ui/Dockerfile b/demo/complex2/grouper_ui/Dockerfile
new file mode 100644
index 0000000..3551f04
--- /dev/null
+++ b/demo/complex2/grouper_ui/Dockerfile
@@ -0,0 +1,7 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+#COPY in custom css, images, etc
+
+CMD ["ui"]
diff --git a/demo/complex2/grouper_ui/container_files/shibboleth/shibd.logger b/demo/complex2/grouper_ui/container_files/shibboleth/shibd.logger
new file mode 100644
index 0000000..2589b43
--- /dev/null
+++ b/demo/complex2/grouper_ui/container_files/shibboleth/shibd.logger
@@ -0,0 +1,69 @@
+# set overall behavior
+log4j.rootCategory=DEBUG, shibd_log, warn_log
+
+# fairly verbose for DEBUG, so generally leave at DEBUG
+log4j.category.XMLTooling.XMLObject=DEBUG
+log4j.category.XMLTooling.KeyInfoResolver=DEBUG
+log4j.category.Shibboleth.IPRange=DEBUG
+log4j.category.Shibboleth.PropertySet=DEBUG
+
+# raise for low-level tracing of SOAP client HTTP/SSL behavior
+log4j.category.XMLTooling.libcurl=DEBUG
+
+# useful categories to tune independently:
+#
+# tracing of SAML messages and security policies
+#log4j.category.OpenSAML.MessageDecoder=DEBUG
+#log4j.category.OpenSAML.MessageEncoder=DEBUG
+#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG
+#log4j.category.XMLTooling.SOAPClient=DEBUG
+# interprocess message remoting
+#log4j.category.Shibboleth.Listener=DEBUG
+# mapping of requests to applicationId
+#log4j.category.Shibboleth.RequestMapper=DEBUG
+# high level session cache operations
+#log4j.category.Shibboleth.SessionCache=DEBUG
+# persistent storage and caching
+#log4j.category.XMLTooling.StorageService=DEBUG
+
+# logs XML being signed or verified if set to DEBUG
+log4j.category.XMLTooling.Signature.Debugger=DEBUG, sig_log
+log4j.additivity.XMLTooling.Signature.Debugger=false
+
+# the tran log blocks the "default" appender(s) at runtime
+# Level should be left at DEBUG for this category
+log4j.category.Shibboleth-TRANSACTION=DEBUG, tran_log
+log4j.additivity.Shibboleth-TRANSACTION=false
+# uncomment to suppress particular event types
+#log4j.category.Shibboleth-TRANSACTION.AuthnRequest=WARN
+#log4j.category.Shibboleth-TRANSACTION.Login=WARN
+#log4j.category.Shibboleth-TRANSACTION.Logout=WARN
+
+# define the appenders
+
+log4j.appender.shibd_log=org.apache.log4j.RollingFileAppender
+log4j.appender.shibd_log.fileName=/var/log/shibboleth/shibd.log
+log4j.appender.shibd_log.maxFileSize=1000000
+log4j.appender.shibd_log.maxBackupIndex=10
+log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.shibd_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.warn_log=org.apache.log4j.RollingFileAppender
+log4j.appender.warn_log.fileName=/var/log/shibboleth/shibd_warn.log
+log4j.appender.warn_log.maxFileSize=1000000
+log4j.appender.warn_log.maxBackupIndex=10
+log4j.appender.warn_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.warn_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+log4j.appender.warn_log.threshold=WARN
+
+log4j.appender.tran_log=org.apache.log4j.RollingFileAppender
+log4j.appender.tran_log.fileName=/var/log/shibboleth/transaction.log
+log4j.appender.tran_log.maxFileSize=1000000
+log4j.appender.tran_log.maxBackupIndex=20
+log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.tran_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.sig_log=org.apache.log4j.FileAppender
+log4j.appender.sig_log.fileName=/var/log/shibboleth/signature.log
+log4j.appender.sig_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.sig_log.layout.ConversionPattern=%m
diff --git a/demo/complex2/grouper_ws/Dockerfile b/demo/complex2/grouper_ws/Dockerfile
new file mode 100644
index 0000000..ca4cf1a
--- /dev/null
+++ b/demo/complex2/grouper_ws/Dockerfile
@@ -0,0 +1,9 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+COPY container_files/web.xml /opt/grouper/grouper.ws/WEB-INF/
+COPY container_files/tomcat-users.xml /opt/tomcat/conf/
+COPY container_files/server.xml /opt/tomcat/conf/
+
+CMD ["ws"]
diff --git a/demo/complex2/grouper_ws/container_files/server.xml b/demo/complex2/grouper_ws/container_files/server.xml
new file mode 100644
index 0000000..3c919f5
--- /dev/null
+++ b/demo/complex2/grouper_ws/container_files/server.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- Note:  A "Server" is not itself a "Container", so you may not
+     define subcomponents such as "Valves" at this level.
+     Documentation at /docs/config/server.html
+ -->
+<Server port="8005" shutdown="SHUTDOWN">
+  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
+  <!-- Security listener. Documentation at /docs/config/listeners.html
+  <Listener className="org.apache.catalina.security.SecurityListener" />
+  -->
+  <!--APR library loader. Documentation at /docs/apr.html -->
+  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
+  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
+
+  <!-- Global JNDI resources
+       Documentation at /docs/jndi-resources-howto.html
+  -->
+  <GlobalNamingResources>
+    <!-- Editable user database that can also be used by
+         UserDatabaseRealm to authenticate users
+    -->
+    <Resource name="UserDatabase" auth="Container"
+              type="org.apache.catalina.UserDatabase"
+              description="User database that can be updated and saved"
+              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+              pathname="conf/tomcat-users.xml" />
+  </GlobalNamingResources>
+
+  <!-- A "Service" is a collection of one or more "Connectors" that share
+       a single "Container" Note:  A "Service" is not itself a "Container",
+       so you may not define subcomponents such as "Valves" at this level.
+       Documentation at /docs/config/service.html
+   -->
+  <Service name="Catalina">
+
+    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+    <!--
+    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+        maxThreads="150" minSpareThreads="4"/>
+    -->
+
+
+    <!-- A "Connector" represents an endpoint by which requests are received
+         and responses are returned. Documentation at :
+         Java HTTP Connector: /docs/config/http.html
+         Java AJP  Connector: /docs/config/ajp.html
+         APR (HTTP/AJP) Connector: /docs/apr.html
+         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
+    -->
+    <Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
+               connectionTimeout="20000"
+               redirectPort="8443" />
+    <!-- A "Connector" using the shared thread pool-->
+    <!--
+    <Connector executor="tomcatThreadPool"
+               port="8080" protocol="HTTP/1.1"
+               connectionTimeout="20000"
+               redirectPort="8443" />
+    -->
+    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
+         This connector uses the NIO implementation. The default
+         SSLImplementation will depend on the presence of the APR/native
+         library and the useOpenSSL attribute of the
+         AprLifecycleListener.
+         Either JSSE or OpenSSL style configuration may be used regardless of
+         the SSLImplementation selected. JSSE style configuration is used below.
+    -->
+    <!--
+    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
+               maxThreads="150" SSLEnabled="true">
+        <SSLHostConfig>
+            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
+                         type="RSA" />
+        </SSLHostConfig>
+    </Connector>
+    -->
+    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
+         This connector uses the APR/native implementation which always uses
+         OpenSSL for TLS.
+         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
+         configuration is used below.
+    -->
+    <!--
+    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
+               maxThreads="150" SSLEnabled="true" >
+        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
+        <SSLHostConfig>
+            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
+                         certificateFile="conf/localhost-rsa-cert.pem"
+                         certificateChainFile="conf/localhost-rsa-chain.pem"
+                         type="RSA" />
+        </SSLHostConfig>
+    </Connector>
+    -->
+
+    <!-- Define an AJP 1.3 Connector on port 8009 -->
+    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8" />
+
+
+    <!-- An Engine represents the entry point (within Catalina) that processes
+         every request.  The Engine implementation for Tomcat stand alone
+         analyzes the HTTP headers included with the request, and passes them
+         on to the appropriate Host (virtual host).
+         Documentation at /docs/config/engine.html -->
+
+    <!-- You should set jvmRoute to support load-balancing via AJP ie :
+    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+    -->
+    <Engine name="Catalina" defaultHost="localhost">
+
+      <!--For clustering, please take a look at documentation at:
+          /docs/cluster-howto.html  (simple how to)
+          /docs/config/cluster.html (reference documentation) -->
+      <!--
+      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+      -->
+
+      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
+           via a brute-force attack -->
+      <Realm className="org.apache.catalina.realm.LockOutRealm">
+        <!-- This Realm uses the UserDatabase configured in the global JNDI
+             resources under the key "UserDatabase".  Any edits
+             that are performed against this UserDatabase are immediately
+             available for use by the Realm.  -->
+        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+               resourceName="UserDatabase"/> <!-- we can log in with tomcat-users.xml accounts -->
+
+        <Realm className="org.apache.catalina.realm.JNDIRealm"
+               connectionURL="ldap://directory"
+               userBase="ou=people,dc=internet2,dc=edu"
+               userSearch="(uid={0})"
+               userSubtree="true"
+               connectionName="cn=admin,dc=internet2,dc=edu"
+               connectionPassword="password"
+               allRolesMode="authOnly"  /> <!-- Or we can log in with ldap accounts -->
+      </Realm>
+
+      <!-- Define the default virtual host
+           Note: XML Schema validation will not work with Xerces 2.2.
+       -->
+
+      <Host name="localhost"  appBase="webapps"
+            unpackWARs="true" autoDeploy="true">
+
+        <!-- SingleSignOn valve, share authentication between web applications
+             Documentation at: /docs/config/valve.html -->
+        <!--
+        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+        -->
+
+        <!-- Access log processes all example.
+             Documentation at: /docs/config/valve.html
+             Note: The pattern used is equivalent to using pattern="common" -->
+        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+               prefix="localhost_access_log" suffix=".txt"
+               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
+
+      </Host>
+    </Engine>
+  </Service>
+</Server>
diff --git a/demo/complex2/grouper_ws/container_files/tomcat-users.xml b/demo/complex2/grouper_ws/container_files/tomcat-users.xml
new file mode 100644
index 0000000..f5d6945
--- /dev/null
+++ b/demo/complex2/grouper_ws/container_files/tomcat-users.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<tomcat-users xmlns="http://tomcat.apache.org/xml"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
+              version="1.0">
+<role rolename="grouper_user"/>
+<user username="banderson" password="password1" roles="grouper_user"/>
+<!--
+  NOTE:  By default, no user is included in the "manager-gui" role required
+  to operate the "/manager/html" web application.  If you wish to use this app,
+  you must define such a user - the username and password are arbitrary. It is
+  strongly recommended that you do NOT use one of the users in the commented out
+  section below since they are intended for use with the examples web
+  application.
+-->
+<!--
+  NOTE:  The sample user and role entries below are intended for use with the
+  examples web application. They are wrapped in a comment and thus are ignored
+  when reading this file. If you wish to configure these users for use with the
+  examples web application, do not forget to remove the <!.. ..> that surrounds
+  them. You will also need to set the passwords to something appropriate.
+-->
+<!--
+  <role rolename="tomcat"/>
+  <role rolename="role1"/>
+  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
+  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
+  <user username="role1" password="<must-be-changed>" roles="role1"/>
+-->
+</tomcat-users>
\ No newline at end of file
diff --git a/demo/complex2/grouper_ws/container_files/web.xml b/demo/complex2/grouper_ws/container_files/web.xml
new file mode 100644
index 0000000..03d3deb
--- /dev/null
+++ b/demo/complex2/grouper_ws/container_files/web.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+
+<!DOCTYPE web-app PUBLIC 
+          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+          "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+  <filter>
+    <!-- keeps the request and response in threadlocal so they dont have to be passed around -->
+    <filter-name>Grouper service filter</filter-name>
+    <filter-class>edu.internet2.middleware.grouper.ws.GrouperServiceJ2ee</filter-class>
+  </filter>
+
+  <filter>
+    <!-- logging filter -->
+    <filter-name>Grouper logging filter</filter-name>
+    <filter-class>edu.internet2.middleware.grouper.ws.j2ee.ServletFilterLogger</filter-class>
+  </filter>
+
+  <!-- filter-mapping>
+    <filter-name>Grouper logging filter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping -->
+  <!-- Map the filter to a Servlet or URL -->
+  <filter-mapping>
+    <filter-name>Grouper service filter</filter-name>
+    <url-pattern>/services/*</url-pattern>
+  </filter-mapping>
+  <filter-mapping>
+    <filter-name>Grouper service filter</filter-name>
+    <url-pattern>/servicesRest/*</url-pattern>
+  </filter-mapping>
+	<servlet>
+		<servlet-name>AxisServlet</servlet-name>
+		<display-name>Apache-Axis Servlet</display-name>
+		<servlet-class>edu.internet2.middleware.grouper.ws.GrouperServiceAxisServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+    <!-- hint that this is the wssec servlet -->
+    <!-- init-param>
+      <param-name>wssec</param-name>
+      <param-value>true</param-value>
+    </init-param --> 
+	</servlet>
+  <servlet>
+    <servlet-name>RestServlet</servlet-name>
+    <display-name>WS REST Servlet</display-name>
+    <servlet-class>edu.internet2.middleware.grouper.ws.rest.GrouperRestServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet>
+    <servlet-name>StatusServlet</servlet-name>
+    <display-name>Status Servlet</display-name>
+    <servlet-class>edu.internet2.middleware.grouper.j2ee.status.GrouperStatusServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>StatusServlet</servlet-name>
+    <url-pattern>/status</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>AxisServlet</servlet-name>
+    <url-pattern>/services/*</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>RestServlet</servlet-name>
+    <url-pattern>/servicesRest/*</url-pattern>
+  </servlet-mapping>
+
+	<security-constraint>
+		<web-resource-collection>
+			<web-resource-name>Web services</web-resource-name>
+			<url-pattern>/services/*</url-pattern>
+		</web-resource-collection>
+		<auth-constraint>
+			<role-name>*</role-name>
+		</auth-constraint>
+	</security-constraint>
+
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>Web services</web-resource-name>
+      <url-pattern>/servicesRest/*</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+      <!-- NOTE:  This role is not present in the default users file -->
+      <role-name>*</role-name>
+    </auth-constraint>
+  </security-constraint>
+
+	<!-- Define the Login Configuration for this Application -->
+	<login-config>
+		<auth-method>BASIC</auth-method>
+		<realm-name>Grouper Application</realm-name>
+	</login-config>
+
+	<!-- Security roles referenced by this web application -->
+	<security-role>
+		<description>
+			The role that is required to log in to web service
+		</description>
+		<role-name>*</role-name>
+	</security-role>
+  
+  <session-config>
+    <session-timeout>1</session-timeout> 
+  </session-config>
+  <!--  config to enable ESB listener servlet
+  <servlet>
+    <servlet-name>EsbServlet</servlet-name>
+    <display-name>Esb Servlet</display-name>
+    <servlet-class>edu.internet2.middleware.grouper.esb.EsbHttpHandler</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>EsbServlet</servlet-name>
+    <url-pattern>/servicesEsb/*</url-pattern>
+  </servlet-mapping>
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>Web services</web-resource-name>
+      <url-pattern>/servicesEsb/*</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+      <role-name>grouper_user</role-name>
+    </auth-constraint>
+  </security-constraint> -->  
+</web-app>
diff --git a/demo/complex2/idp/Dockerfile b/demo/complex2/idp/Dockerfile
new file mode 100644
index 0000000..0f6f508
--- /dev/null
+++ b/demo/complex2/idp/Dockerfile
@@ -0,0 +1,5 @@
+FROM tier/shib-idp
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+COPY shibboleth-idp/ /opt/shibboleth-idp/
diff --git a/demo/complex2/idp/shibboleth-idp/conf/attribute-filter.xml b/demo/complex2/idp/shibboleth-idp/conf/attribute-filter.xml
new file mode 100644
index 0000000..21ffdb8
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/conf/attribute-filter.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    This file is an EXAMPLE policy file.  While the policy presented in this 
+    example file is illustrative of some simple cases, it relies on the names of
+    non-existent example services and the example attributes demonstrated in the
+    default attribute-resolver.xml file.
+    
+    Deployers should refer to the documentation for a complete list of components
+    and their options.
+-->
+<afp:AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
+        xmlns:afp="urn:mace:shibboleth:2.0:afp"
+        xmlns:basic="urn:mace:shibboleth:2.0:afp:mf:basic"
+        xmlns:saml="urn:mace:shibboleth:2.0:afp:mf:saml"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd
+                            urn:mace:shibboleth:2.0:afp:mf:basic http://shibboleth.net/schema/idp/shibboleth-afp-mf-basic.xsd
+                            urn:mace:shibboleth:2.0:afp:mf:saml http://shibboleth.net/schema/idp/shibboleth-afp-mf-saml.xsd">
+
+    <!-- Release some attributes to an SP. -->
+    <afp:AttributeFilterPolicy id="example1">
+        <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://grouperdemo/shibboleth" />
+
+        <afp:AttributeRule attributeID="eduPersonPrincipalName">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+        <afp:AttributeRule attributeID="uid">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+        <afp:AttributeRule attributeID="mail">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+    </afp:AttributeFilterPolicy>
+
+    <afp:AttributeFilterPolicy id="midpoint">
+        <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://midpointdemo/shibboleth" />
+
+        <afp:AttributeRule attributeID="uid">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+    </afp:AttributeFilterPolicy>
+
+</afp:AttributeFilterPolicyGroup>
diff --git a/demo/complex2/idp/shibboleth-idp/conf/attribute-resolver.xml b/demo/complex2/idp/shibboleth-idp/conf/attribute-resolver.xml
new file mode 100644
index 0000000..ee9519f
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/conf/attribute-resolver.xml
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    This file is an EXAMPLE configuration file containing lots of commented
+    example attributes, encoders, and a couple of example data connectors.
+    
+    Not all attribute definitions or data connectors are demonstrated, but
+    a variety of LDAP attributes, some common to Shibboleth deployments and
+    many not, are included.
+    
+    Deployers should refer to the Shibboleth 2 documentation for a complete
+    list of components  and their options.
+-->
+<resolver:AttributeResolver
+        xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
+        xmlns:pc="urn:mace:shibboleth:2.0:resolver:pc"
+        xmlns:ad="urn:mace:shibboleth:2.0:resolver:ad"
+        xmlns:dc="urn:mace:shibboleth:2.0:resolver:dc"
+        xmlns:enc="urn:mace:shibboleth:2.0:attribute:encoder"
+        xmlns:sec="urn:mace:shibboleth:2.0:security"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd
+                            urn:mace:shibboleth:2.0:resolver:pc http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-pc.xsd
+                            urn:mace:shibboleth:2.0:resolver:ad http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-ad.xsd
+                            urn:mace:shibboleth:2.0:resolver:dc http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-dc.xsd
+                            urn:mace:shibboleth:2.0:attribute:encoder http://shibboleth.net/schema/idp/shibboleth-attribute-encoder.xsd
+                            urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+
+    <!-- ========================================== -->
+    <!--      Attribute Definitions                 -->
+    <!-- ========================================== -->
+
+    <!-- Schema: Core schema attributes-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="uid" sourceAttributeID="uid">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:uid" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.1" friendlyName="uid" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="mail" sourceAttributeID="mail">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mail" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="homePhone" sourceAttributeID="homePhone">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:homePhone" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.20" friendlyName="homePhone" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="homePostalAddress" sourceAttributeID="homePostalAddress">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:homePostalAddress" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.39" friendlyName="homePostalAddress" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="mobileNumber" sourceAttributeID="mobile">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mobile" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.41" friendlyName="mobile" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="pagerNumber" sourceAttributeID="pager">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:pager" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.42" friendlyName="pager" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="surname" sourceAttributeID="sn">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:sn" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.4" friendlyName="sn" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="locality" sourceAttributeID="l">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:l" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.7" friendlyName="l" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="stateProvince" sourceAttributeID="st">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:st" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.8" friendlyName="st" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="street" sourceAttributeID="street">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:street" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.9" friendlyName="street" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="organizationName" sourceAttributeID="o">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:o" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.10" friendlyName="o" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="organizationalUnit" sourceAttributeID="ou">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:ou" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.11" friendlyName="ou" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="title" sourceAttributeID="title">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:title" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.12" friendlyName="title" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postalAddress" sourceAttributeID="postalAddress">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postalAddress" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.16" friendlyName="postalAddress" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postalCode" sourceAttributeID="postalCode">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postalCode" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.17" friendlyName="postalCode" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postOfficeBox" sourceAttributeID="postOfficeBox">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postOfficeBox" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.18" friendlyName="postOfficeBox" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="telephoneNumber" sourceAttributeID="telephoneNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:telephoneNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.20" friendlyName="telephoneNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="givenName" sourceAttributeID="givenName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:givenName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.42" friendlyName="givenName" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="initials" sourceAttributeID="initials">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:initials" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.43" friendlyName="initials" encodeType="false" />
+    </resolver:AttributeDefinition>
+     -->
+
+    <!-- Schema: inetOrgPerson attributes-->
+    <!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="departmentNumber" sourceAttributeID="departmentNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:departmentNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.2" friendlyName="departmentNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="displayName" sourceAttributeID="displayName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:displayName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.241" friendlyName="displayName" encodeType="false" />
+    </resolver:AttributeDefinition> 
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="employeeNumber" sourceAttributeID="employeeNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.3" friendlyName="employeeNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="employeeType" sourceAttributeID="employeeType">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeType" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.4" friendlyName="employeeType" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="jpegPhoto" sourceAttributeID="jpegPhoto">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:jpegPhoto" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.60" friendlyName="jpegPhoto" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="preferredLanguage" sourceAttributeID="preferredLanguage">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:preferredLanguage" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.39" friendlyName="preferredLanguage" encodeType="false" />
+    </resolver:AttributeDefinition>
+    -->
+
+    <!-- Schema: eduPerson attributes -->
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAffiliation" sourceAttributeID="cn">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonEntitlement" sourceAttributeID="eduPersonEntitlement">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonEntitlement" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" friendlyName="eduPersonEntitlement" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonNickname" sourceAttributeID="eduPersonNickname">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonNickname" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.2" friendlyName="eduPersonNickname" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonPrimaryAffiliation" sourceAttributeID="eduPersonPrimaryAffiliation">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.5" friendlyName="eduPersonPrimaryAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonUniqueId" scope="%{idp.scope}" sourceAttributeID="localUniqueId">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" friendlyName="eduPersonUniqueId" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonPrincipalName" scope="%{idp.scope}" sourceAttributeID="eduPersonPrincipalName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonPrincipalName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Prescoped" id="eduPersonPrincipalNamePrior" sourceAttributeID="eduPersonPrincipalNamePrior">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.12" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.12" friendlyName="eduPersonPrincipalNamePrior" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonScopedAffiliation" scope="%{idp.scope}" sourceAttributeID="eduPersonAffiliation">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" friendlyName="eduPersonScopedAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAssurance" sourceAttributeID="eduPersonAssurance">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAssurance" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" friendlyName="eduPersonAssurance" encodeType="false" />
+    </resolver:AttributeDefinition>
+    -->
+
+    <!-- ========================================== -->
+    <!--      Data Connectors                       -->
+    <!-- ========================================== -->
+
+    <!-- Example Static Connector -->
+    <!--
+    <resolver:DataConnector id="staticAttributes" xsi:type="dc:Static">
+        <dc:Attribute id="eduPersonAffiliation">
+            <dc:Value>member</dc:Value>
+        </dc:Attribute>
+    </resolver:DataConnector>
+    -->
+
+    <!-- Example Relational Database Connector -->
+    <!--
+    <resolver:DataConnector id="mySIS" xsi:type="dc:RelationalDatabase">
+        <dc:ApplicationManagedConnection jdbcDriver="oracle.jdbc.driver.OracleDriver"
+                                         jdbcURL="jdbc:oracle:thin:@db.example.org:1521:SomeDB" 
+                                         jdbcUserName="myid" 
+                                         jdbcPassword="mypassword" />
+        <dc:QueryTemplate>
+            <![CDATA[
+                SELECT * FROM student WHERE gzbtpid = '$requestContext.principalName'
+            ]]>
+        </dc:QueryTemplate>
+
+        <dc:Column columnName="gzbtpid" attributeID="uid" />
+        <dc:Column columnName="fqlft" attributeID="gpa" />
+    </resolver:DataConnector>
+     -->
+
+    <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
+        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
+        baseDN="%{idp.attribute.resolver.LDAP.baseDN}" 
+        principal="%{idp.attribute.resolver.LDAP.bindDN}"
+        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
+        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}">
+        <dc:FilterTemplate>
+            <![CDATA[
+                %{idp.attribute.resolver.LDAP.searchFilter}
+            ]]>
+        </dc:FilterTemplate>
+        <!--
+        <dc:StartTLSTrustCredential id="LDAPtoIdPCredential" xsi:type="sec:X509ResourceBacked">
+            <sec:Certificate>%{idp.attribute.resolver.LDAP.trustCertificates}</sec:Certificate>
+        </dc:StartTLSTrustCredential>
+    -->
+    </resolver:DataConnector>
+
+</resolver:AttributeResolver>
\ No newline at end of file
diff --git a/demo/complex2/idp/shibboleth-idp/conf/idp.properties b/demo/complex2/idp/shibboleth-idp/conf/idp.properties
new file mode 100644
index 0000000..4396f49
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/conf/idp.properties
@@ -0,0 +1,195 @@
+# Load any additional property resources from a comma-delimited list
+idp.additionalProperties= /conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties
+
+# Set the entityID of the IdP
+idp.entityID= https://idptestbed/idp/shibboleth
+
+# Set the scope used in the attribute resolver for scoped attributes
+idp.scope= example.org
+
+# General cookie properties (maxAge only applies to persistent cookies)
+#idp.cookie.secure = false
+#idp.cookie.httpOnly = true
+#idp.cookie.domain =
+#idp.cookie.path =
+#idp.cookie.maxAge = 31536000
+
+# Set the location of user-supplied web flow definitions
+#idp.webflows = %{idp.home}/flows
+
+# Set the location of Velocity view templates
+#idp.views = %{idp.home}/views
+
+# Settings for internal AES encryption key
+#idp.sealer.storeType = JCEKS
+#idp.sealer.updateInterval = PT15M
+#idp.sealer.aliasBase = secret
+idp.sealer.storeResource= %{idp.home}/credentials/sealer.jks
+idp.sealer.versionResource= %{idp.home}/credentials/sealer.kver
+idp.sealer.storePassword= password
+idp.sealer.keyPassword= password
+
+# Settings for public/private signing and encryption key(s)
+# During decryption key rollover, point the ".2" properties at a second
+# keypair, uncomment in credentials.xml, then publish it in your metadata.
+idp.signing.key= %{idp.home}/credentials/idp-signing.key
+idp.signing.cert= %{idp.home}/credentials/idp-signing.crt
+idp.encryption.key= %{idp.home}/credentials/idp-encryption.key
+idp.encryption.cert= %{idp.home}/credentials/idp-encryption.crt
+#idp.encryption.key.2 = %{idp.home}/credentials/idp-encryption-old.key
+#idp.encryption.cert.2 = %{idp.home}/credentials/idp-encryption-old.crt
+
+# Sets the bean ID to use as a default security configuration set
+#idp.security.config = shibboleth.DefaultSecurityConfiguration
+
+# To default to SHA-1, set to shibboleth.SigningConfiguration.SHA1
+#idp.signing.config = shibboleth.SigningConfiguration.SHA256
+
+# Configures trust evaluation of keys used by services at runtime
+# Defaults to supporting both explicit key and PKIX using SAML metadata.
+#idp.trust.signatures = shibboleth.ChainingSignatureTrustEngine
+# To pick only one set to one of:
+#   shibboleth.ExplicitKeySignatureTrustEngine, shibboleth.PKIXSignatureTrustEngine
+#idp.trust.certificates = shibboleth.ChainingX509TrustEngine
+# To pick only one set to one of:
+#   shibboleth.ExplicitKeyX509TrustEngine, shibboleth.PKIXX509TrustEngine
+
+# If true, encryption will happen whenever a key to use can be located, but
+# failure to encrypt won't result in request failure.
+#idp.encryption.optional = false
+
+# Configuration of client- and server-side storage plugins
+#idp.storage.cleanupInterval = PT10M
+#idp.storage.htmlLocalStorage = false
+
+# Set to true to expose more detailed errors in responses to SPs
+#idp.errors.detailed = false
+# Set to false to skip signing of SAML response messages that signal errors
+#idp.errors.signed = true
+# Name of bean containing a list of Java exception classes to ignore
+#idp.errors.excludedExceptions = ExceptionClassListBean
+# Name of bean containing a property set mapping exception names to views
+#idp.errors.exceptionMappings = ExceptionToViewPropertyBean
+# Set if a different default view name for events and exceptions is needed
+#idp.errors.defaultView = error
+
+# Set to false to disable the IdP session layer
+#idp.session.enabled = true
+
+# Set to "shibboleth.StorageService" for server-side storage of user sessions
+#idp.session.StorageService = shibboleth.ClientSessionStorageService
+idp.session.StorageService = shibboleth.StorageService
+
+# Size of session IDs
+#idp.session.idSize = 32
+# Bind sessions to IP addresses
+#idp.session.consistentAddress = true
+# Inactivity timeout
+#idp.session.timeout = PT60M
+# Extra time to store sessions for logout
+#idp.session.slop = PT0S
+# Tolerate storage-related errors
+#idp.session.maskStorageFailure = false
+# Track information about SPs logged into
+#idp.session.trackSPSessions = false
+# Support lookup by SP for SAML logout
+#idp.session.secondaryServiceIndex = false
+# Length of time to track SP sessions
+#idp.session.defaultSPlifetime = PT2H
+
+# Regular expression matching login flows to enable, e.g. IPAddress|Password
+idp.authn.flows= Password
+
+# Regular expression of forced "initial" methods when no session exists,
+# usually in conjunction with the idp.authn.resolveAttribute property below.
+#idp.authn.flows.initial = Password
+
+# Set to an attribute ID to resolve prior to selecting authentication flows;
+# its values are used to filter the flows to allow.
+#idp.authn.resolveAttribute = eduPersonAssurance
+
+# Default lifetime and timeout of various authentication methods
+#idp.authn.defaultLifetime = PT60M
+#idp.authn.defaultTimeout = PT30M
+
+# Whether to prioritize "active" results when an SP requests more than
+# one possible matching login method (V2 behavior was to favor them)
+#idp.authn.favorSSO = true
+
+# Whether to fail requests when a user identity after authentication
+# doesn't match the identity in a pre-existing session.
+#idp.authn.identitySwitchIsError = false
+
+# Set to "shibboleth.StorageService" or custom bean for alternate storage of consent
+#idp.consent.StorageService = shibboleth.ClientPersistentStorageService
+
+# Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute
+# to key user consent storage records (and set the attribute name)
+#idp.consent.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
+#idp.consent.userStorageKeyAttribute = uid
+
+# Flags controlling how built-in attribute consent feature operates
+#idp.consent.allowDoNotRemember = true
+#idp.consent.allowGlobal = true
+#idp.consent.allowPerAttribute = false
+
+# Whether attribute values and terms of use text are compared
+#idp.consent.compareValues = false
+# Maximum number of consent records for space-limited storage (e.g. cookies)
+#idp.consent.maxStoredRecords = 10
+# Maximum number of consent records for larger/server-side storage (0 = no limit)
+#idp.consent.expandedMaxStoredRecords = 0
+
+# Time in milliseconds to expire consent storage records.
+#idp.consent.storageRecordLifetime = P1Y
+
+# Whether to lookup metadata, etc. for every SP involved in a logout
+# for use by user interface logic; adds overhead so off by default.
+#idp.logout.elaboration = false
+
+# Whether to require logout requests be signed/authenticated.
+#idp.logout.authenticated = true
+
+# Message freshness and replay cache tuning
+#idp.policy.messageLifetime = PT3M
+#idp.policy.clockSkew = PT3M
+
+# Set to custom bean for alternate storage of replay cache
+#idp.replayCache.StorageService = shibboleth.StorageService
+
+# Toggles whether to allow outbound messages via SAML artifact
+#idp.artifact.enabled = true
+# Suppresses typical signing/encryption when artifact binding used
+#idp.artifact.secureChannel = true
+# May differ to direct SAML 2 artifact lookups to specific server nodes
+#idp.artifact.endpointIndex = 2
+# Set to custom bean for alternate storage of artifact map state
+#idp.artifact.StorageService = shibboleth.StorageService
+
+# Name of access control policy for various admin flows
+idp.status.accessPolicy= AccessByIPAddress
+idp.resolvertest.accessPolicy= AccessByIPAddress
+idp.reload.accessPolicy= AccessByIPAddress
+
+# Comma-delimited languages to use if not match can be found with the
+# browser-supported languages, defaults to an empty list.
+idp.ui.fallbackLanguages= en,fr,de
+
+# Storage service used by CAS protocol
+# Defaults to shibboleth.StorageService (in-memory)
+# MUST be server-side storage (e.g. in-memory, memcached, database)
+# NOTE that idp.session.StorageService requires server-side storage
+# when CAS protocol is enabled
+idp.cas.StorageService=shibboleth.StorageService
+
+# CAS service registry implementation class
+#idp.cas.serviceRegistryClass=net.shibboleth.idp.cas.service.PatternServiceRegistry
+
+# Profile flows in which the ProfileRequestContext should be exposed
+# in servlet request under the key "opensamlProfileRequestContext"
+#idp.profile.exposeProfileRequestContextInServletRequest = SAML2/POST/SSO,SAML2/Redirect/SSO
+
+# F-TICKS auditing - set salt to include hashed username
+#idp.fticks.federation=MyFederation
+#idp.fticks.algorithm=SHA-256
+#idp.fticks.salt=somethingsecret
diff --git a/demo/complex2/idp/shibboleth-idp/conf/ldap.properties b/demo/complex2/idp/shibboleth-idp/conf/ldap.properties
new file mode 100644
index 0000000..726f145
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/conf/ldap.properties
@@ -0,0 +1,58 @@
+# LDAP authentication configuration, see authn/ldap-authn-config.xml
+
+## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator
+#idp.authn.LDAP.authenticator                   = anonSearchAuthenticator
+
+## Connection properties ##
+idp.authn.LDAP.ldapURL                          = ldap://directory:389
+idp.authn.LDAP.useStartTLS                     = false
+idp.authn.LDAP.useSSL                          = false
+#idp.authn.LDAP.connectTimeout                  = 3000
+
+## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust
+#idp.authn.LDAP.sslConfig                       = certificateTrust
+## If using certificateTrust above, set to the trusted certificate's path
+idp.authn.LDAP.trustCertificates                = %{idp.home}/credentials/ldap-server.crt
+## If using keyStoreTrust above, set to the truststore path
+idp.authn.LDAP.trustStore                       = %{idp.home}/credentials/ldap-server.truststore
+
+## Return attributes during authentication
+## NOTE: this is not used during attribute resolution; configure that directly in the
+## attribute-resolver.xml configuration via a DataConnector's <dc:ReturnAttributes> element
+idp.authn.LDAP.returnAttributes                 = cn,businessCategory,mail
+
+## DN resolution properties ##
+
+# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator
+# for AD: CN=Users,DC=example,DC=org
+idp.authn.LDAP.baseDN                           = ou=people,dc=internet2,dc=edu
+#idp.authn.LDAP.subtreeSearch                   = false
+idp.authn.LDAP.userFilter                       = (uid={user})
+# bind search configuration
+# for AD: idp.authn.LDAP.bindDN=adminuser@domain.com
+idp.authn.LDAP.bindDN                           = cn=admin,dc=internet2,dc=edu
+idp.authn.LDAP.bindDNCredential                 = password
+
+# Format DN resolution, used by directAuthenticator, adAuthenticator
+# for AD use idp.authn.LDAP.dnFormat=%s@domain.com
+idp.authn.LDAP.dnFormat                         = uid=%s,ou=people,dc=internet2,dc=edu
+
+# LDAP attribute configuration, see attribute-resolver.xml
+idp.attribute.resolver.LDAP.ldapURL             = %{idp.authn.LDAP.ldapURL}
+idp.attribute.resolver.LDAP.baseDN              = %{idp.authn.LDAP.baseDN}
+idp.attribute.resolver.LDAP.bindDN              = %{idp.authn.LDAP.bindDN}
+idp.attribute.resolver.LDAP.bindDNCredential    = %{idp.authn.LDAP.bindDNCredential}
+idp.attribute.resolver.LDAP.useStartTLS         = %{idp.authn.LDAP.useStartTLS:true}
+idp.attribute.resolver.LDAP.trustCertificates   = %{idp.authn.LDAP.trustCertificates}
+idp.attribute.resolver.LDAP.searchFilter        = (uid=$requestContext.principalName)
+
+# LDAP pool configuration, used for both authn and DN resolution
+#idp.pool.LDAP.minSize                          = 3
+#idp.pool.LDAP.maxSize                          = 10
+#idp.pool.LDAP.validateOnCheckout               = false
+#idp.pool.LDAP.validatePeriodically             = true
+#idp.pool.LDAP.validatePeriod                   = 300
+#idp.pool.LDAP.prunePeriod                      = 300
+#idp.pool.LDAP.idleTime                         = 600
+#idp.pool.LDAP.blockWaitTime                    = 3000
+#idp.pool.LDAP.failFastInitialize               = false
diff --git a/demo/complex2/idp/shibboleth-idp/conf/metadata-providers.xml b/demo/complex2/idp/shibboleth-idp/conf/metadata-providers.xml
new file mode 100644
index 0000000..f70135e
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/conf/metadata-providers.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This file is an EXAMPLE metadata configuration file. -->
+<MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider"
+    xmlns="urn:mace:shibboleth:2.0:metadata"
+    xmlns:resource="urn:mace:shibboleth:2.0:resource"
+    xmlns:security="urn:mace:shibboleth:2.0:security"
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd
+                        urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd 
+                        urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd
+                        urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd">
+                        
+    <!-- ========================================================================================== -->
+    <!--                             Metadata Configuration                                         -->
+    <!--                                                                                            -->
+    <!--  Below you place the mechanisms which define how to load the metadata for the SP you will  -->
+    <!--  provide a service to.                                                                     -->
+    <!--                                                                                            -->
+    <!--  Two examples are provided.  The Shibboleth Documentation at                               -->
+    <!--  https://wiki.shibboleth.net/confluence/display/IDP30/MetadataConfiguration                -->
+    <!--  provides more details.                                                                    --> 
+    <!--                                                                                            -->
+    <!--  NOTE.  This file SHOULD NOT contain the metadata for this IdP.                            -->
+    <!--                                                                                            -->
+    <!-- ========================================================================================== -->
+
+    <MetadataProvider id="GrouperSP"  xsi:type="FilesystemMetadataProvider" metadataFile="%{idp.home}/metadata/grouper-sp.xml"/>
+    <MetadataProvider id="MidpointSP"  xsi:type="FilesystemMetadataProvider" metadataFile="%{idp.home}/metadata/midpoint-sp.xml"/>
+
+    <!-- Example HTTP metadata provider.  Use this if you want to download
+         the metadata from a remote service.
+         
+         You *MUST*  provider the SignatureValidationFilter in order to function securely.
+         Get the PubLic key, and validate it via some out of band mechanism, from the
+         party publishing the metadata
+         
+         The EntityRoleWhiteList saves memory by only loading metadata from entity types
+         that you will interoperate with. 
+    
+    <MetadataProvider id="HTTPMetadata"
+                      xsi:type="FileBackedHTTPMetadataProvider"
+                      backingFile="%{idp.home}/metadata/localCopyFromXYZHTTP.xml"
+                      metadataURL="http://WHATEVER"> 
+        
+        <MetadataFilter xsi:type="SignatureValidation"
+            requireSignedMetadata="false">
+            <PublicKey>
+                THIS IS AN EXAMPLE
+            
+                MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
+                uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
+                LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
+                NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
+                nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
+                E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
+                4wIDAQAB
+            </PublicKey>
+        </MetadataFilter>
+        <MetadataFilter xsi:type="EntityRoleWhiteList">
+            <RetainedRole>md:SPSSODescriptor</RetainedRole>
+        </MetadataFilter>
+        
+    </MetadataProvider>
+    
+    -->   
+
+    <!-- Example file metadata provider.  Use this if you want to load metadata
+         from a local file.  You might use this if you have some local SPs
+         which are not "federated" but you wish to offer a service to.
+         
+         If you do not provide a SignatureValidation filter then you *have*
+         to know that the file is valid.
+         
+
+    <MetadataProvider id="LocalMetadata"  xsi:type="FilesystemMetadataProvider" metadataFile="PATH_TO_YOUR_METADATA"/>
+
+     -->
+          
+    
+</MetadataProvider>
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-backchannel.crt b/demo/complex2/idp/shibboleth-idp/credentials/idp-backchannel.crt
new file mode 100644
index 0000000..c1f8fab
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/credentials/idp-backchannel.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+-----END CERTIFICATE-----
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-backchannel.p12 b/demo/complex2/idp/shibboleth-idp/credentials/idp-backchannel.p12
new file mode 100644
index 0000000..112540a
Binary files /dev/null and b/demo/complex2/idp/shibboleth-idp/credentials/idp-backchannel.p12 differ
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-browser.p12 b/demo/complex2/idp/shibboleth-idp/credentials/idp-browser.p12
new file mode 100644
index 0000000..032be0b
Binary files /dev/null and b/demo/complex2/idp/shibboleth-idp/credentials/idp-browser.p12 differ
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-encryption.crt b/demo/complex2/idp/shibboleth-idp/credentials/idp-encryption.crt
new file mode 100644
index 0000000..15d764f
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/credentials/idp-encryption.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+-----END CERTIFICATE-----
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-encryption.key b/demo/complex2/idp/shibboleth-idp/credentials/idp-encryption.key
new file mode 100644
index 0000000..8bb5cc6
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/credentials/idp-encryption.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAgV79KN35k/Ipbsi4yeJQQFQlvmUVchFz2ELkYu73w3DuGund
+ZMYiS7GitFvPFTcYxUEa/D4A5Fq9vL8KB9a4JOKS7LMyw+PAwcw/eNqXiZf0uhZ7
+CCY5mh3AYeKWzYVOMqMLut4ipL7ba3GQBG6RK6OmfAs4lhMfLMsKGmBEBonz5K/T
+kVegp97cavvYDAXjxuNRq7Wa1BiLvsa53S9EoYeD6tHqv/TALFZSCFxGvPVnx/Cd
+pBXEzn6FrSHO9G+0y2ULMeGJzXJ6xi0lBHLLRcjy1/l7b+UjWRfPTjiMV1TYzb4B
+OQ2yW/YTDOFABaiPtW6PUKrccE4Y3P7DryMczQIDAQABAoIBAF/IflMllcUtw/Nb
+9USzpIscQh2nJaugtE5nqER/fT1cfU273Mjh0T6NtFMorjec5WAWBe6/0VVAwb3f
+C4QmO4xDnFhXjLxwAaT6nfvSi+O5d93XCxxLgNZUNL3ET7a2feELyoF+OdQT4sy3
+9dLyMdVHgtnQTQMAAVLeuQoyP+s+Zax4Gca6ln8QxIIvDoD7NITnpl8887Hghhzl
+CvKtRiPRtoI2JTXWgWuLI6xXfVsDvFT+Up+ki9TMLWLACcmMU1d+lUBOKIqhhQHG
++np9iKxVausJwYaLwwT3h8SItNon7ltbV6kcqyZxMAA+uN8CVgIb5UaUrlW7Nvze
+1iUNudkCgYEAxpnBg8YxdEHFSMTqjEOYapn18cs3n32EBPtvPaUcvw3mGC1+ZVx1
+9WqnVsgykBOWI0qSBVF7Kke8yOqgqWtYQUFqLiMgCC9e/QcXnrm/bzAmKDgLVcCR
+KzgqU2ECQDkNSS0qeODjLGX4SEabDbLhN59WykHKM0i/RcrbhuvT1BcCgYEApsMD
+TFQBaiaEmLVm252piZf8b5g3DrUHeqGktHkHXTW4Iyyn8zEknoiCosk/Tej73zga
+cTT3zQgEh63DMC9Ag8IbIJiDpYLMkt1QvZYtq95E/94GVEfRRok6/pyagGYB351R
+PXcykrDyy26FSofmtaXU37Wxaj3ow+WROaPgULsCgYEArFoFScG3a2gkuRlDX8TN
+wj2o5lTxCbWY2+YEzR+8icWbGQJqPbb3G6uaW8LTtpt44Vm2zWzAEZo+KLMOCNmC
+tub5Kd8Lzm6l5brA8dvLWcgUZTT2CU5b7YEJomB+3pNkh0vuHwczv3Ui+j5kE4hY
+0bezT0W3H7iTXhNFXprMs7MCgYEAlIZn75l6URLRUjluzPdVQoktei72CpFNgflp
++ps45dmskRd61mzUkqY+w8G+MiPqANu1IVLtyZz0e+tVRxsuuKsvAg8UYVtn3P5k
+pRaWwtaKWeFjfbkhOVOMSa0tJmK0FHfHHZmGX4ReGrXq3YDBCNQUDtOCmn9dSuyy
+NcYxSXUCgYB+yo6dg8nyHDSqKDdrQQiAKv7jNsbecQ/rYrt8l0n9FBiwn5R7v6kp
+afsimCVou5i06L2Cr5Xs+XSf11KVkDh+qM70ZFubWEsHCDrS1KrxUzfFbrQczKof
+qX7ZsBuOT72RwVEa8fpT6IZ6IpOOEPmUid/f2VM2aAcXgaF//vMjxA==
+-----END RSA PRIVATE KEY-----
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-signing.crt b/demo/complex2/idp/shibboleth-idp/credentials/idp-signing.crt
new file mode 100644
index 0000000..6a032c1
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/credentials/idp-signing.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+-----END CERTIFICATE-----
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/idp-signing.key b/demo/complex2/idp/shibboleth-idp/credentials/idp-signing.key
new file mode 100644
index 0000000..011c27c
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/credentials/idp-signing.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7gu6eo4dua
+eLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2Z6dzJsul
+JZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJCb/Q6dYz
+RWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+MNkv6aId
+cHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBsuYlY7lEr
+89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABAoIBAGpInLarQ0+X+ZXK
++aoC+tNO9DUiHq/z2OD4ALGhXSTvr4mgBWNWTkc0F+qJD8MlM8zNkJxaoNGTyLjY
+Z95NQJPXAx2k15HwCENdulvV1oiX0dkTjgmscRmj6FwNAZ0EnWtien45mxZHxEyW
+FkbB9+OHc6JzNvzG9ps1Vk1FtFtO8w4exXuJVATJeArQmMvAUHMJYPb7Qs+/NX9R
+RlDvFfXDzQv5eAzudT1SyFSa5W+Bsw6BtEoeiqdp+xQh4yc733nwN7KG2Z/TpGse
+jVe6akbULuCXOe9uPa7kv8hnQEUH38QVlIw8pK1SsgNq7S0U44WU5uF8gbDBYle/
+OoPBvSECgYEAvCwVEa8ryLzee5FaX4PBxk10lEl/Yp9jC88wPUQ+ZpfniIIQIfwl
+csRE9D3/dJOVAxw/Ac32F72SLVDzLabAhlBRINYLB0ZkVuJi1CIoDHIf9nfh/pOx
+b96VMUe/mpAL4hZnZkmBKjesX5URPEKtBD0aSeCw9aFqhORjRrxCJg0CgYEAuNaD
+LOuTPKsC6nxRtiL9r0CA5gCCdpALxwJA7wHAeh03i5xmy61i4iOMaunxKZhG+nzz
+PhcI8Uhwwk+l3tbYAf1rrtmMKNcyjy+UqWXGt4ZkWFlIyIungyLiH9L32IMhXNF0
+fBgOZNtFTmQBU18a78uIir9xASUbtaakzOtJ2+cCgYAgfawVpZ11x8bSp0Jng6SN
+zQn4IMiyCrtbaqb1rTbpGAmOdIa8l4EP0/vkAGB/jIwKQXJPqXR4nO8EjBmxJD3R
+80RO2yaEVw80QVq3Lj6kB4ClWgXXo0DcBB7Wp4DZ+01R+HRaIQ8AbySATIjxUsH1
+HWfQoc9sWja+Q4Ew0YjKcQKBgGLoPsdBw8b6B5RsM9lPvgoSbScmbKl/CR5TwWVj
+vZhanAd0CLnCrSAvP4tSZf8JAio1xH+cGefrCJOhxTOKKYpfDklBFjQge2iNYHKJ
+CJ3aJ0XzePP/bwLIHtJCtOdBvA+L8VYaFVG418xLzT3MrYBVnFoKeTDQp5Q7eQJC
+gYJPAoGBAKHcuXWzvXoHKnOg8Ljg2xZ6/SfjwNDIIrpXVTAQifmK3q4+Ua2Q+Cjq
+97tPMxF2bVRcbnCSNKpTMOTrsWs8Z3GpMyCh6XgYMSlclXusDVUkRkPpWj8hVTR4
+opm/rxS83hCrTsIX3Il3T8Fpb97kdF+unCiWEaxrPEurjW8lB506
+-----END RSA PRIVATE KEY-----
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/sealer.jks b/demo/complex2/idp/shibboleth-idp/credentials/sealer.jks
new file mode 100644
index 0000000..89957e0
Binary files /dev/null and b/demo/complex2/idp/shibboleth-idp/credentials/sealer.jks differ
diff --git a/demo/complex2/idp/shibboleth-idp/credentials/sealer.kver b/demo/complex2/idp/shibboleth-idp/credentials/sealer.kver
new file mode 100644
index 0000000..d64b0e4
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/credentials/sealer.kver
@@ -0,0 +1,2 @@
+#Fri Dec 11 02:20:32 UTC 2015
+CurrentVersion=1
diff --git a/demo/complex2/idp/shibboleth-idp/metadata/grouper-sp.xml b/demo/complex2/idp/shibboleth-idp/metadata/grouper-sp.xml
new file mode 100644
index 0000000..5b42a7b
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/metadata/grouper-sp.xml
@@ -0,0 +1,78 @@
+<!--
+This is example metadata only. Do *NOT* supply it as is without review,
+and do *NOT* provide it in real time to your partners.
+ -->
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_57114916ca68943103854cb57a3a3b1c7c38bb81" entityID="https://grouperdemo/shibboleth">
+
+  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+  </md:Extensions>
+
+  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://localhost:4443/Shibboleth.sso/Login"/>
+      <idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://localhost:4443/Shibboleth.sso/Login" index="1"/>
+    </md:Extensions>
+    <md:KeyDescriptor>
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:KeyName>sp.example.org</ds:KeyName>
+        <ds:X509Data>
+          <ds:X509SubjectName>CN=sp.example.org,O=Internet2/TIER,L=Ann Arbor,ST=MI,C=US</ds:X509SubjectName>
+          <ds:X509Certificate>MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+</ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
+    </md:KeyDescriptor>
+    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:4443/Shibboleth.sso/Artifact/SOAP" index="1"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:4443/Shibboleth.sso/SLO/SOAP"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:4443/Shibboleth.sso/SLO/Redirect"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:4443/Shibboleth.sso/SLO/POST"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:4443/Shibboleth.sso/SLO/Artifact"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:4443/Shibboleth.sso/SAML2/POST" index="1"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost:4443/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:4443/Shibboleth.sso/SAML2/Artifact" index="3"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://localhost:4443/Shibboleth.sso/SAML2/ECP" index="4"/>
+  </md:SPSSODescriptor>
+
+</md:EntityDescriptor>
diff --git a/demo/complex2/idp/shibboleth-idp/metadata/idp-metadata.xml b/demo/complex2/idp/shibboleth-idp/metadata/idp-metadata.xml
new file mode 100644
index 0000000..84266d4
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/metadata/idp-metadata.xml
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex2/idp/shibboleth-idp/metadata/midpoint-sp-new.xml b/demo/complex2/idp/shibboleth-idp/metadata/midpoint-sp-new.xml
new file mode 100644
index 0000000..a819f4b
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/metadata/midpoint-sp-new.xml
@@ -0,0 +1,37 @@
+<EntityDescriptor entityID="https://midpointdemo/idp/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+  <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <Extensions>
+      <shibmd:Scope regexp="false">midpointdemo</shibmd:Scope>
+    </Extensions>
+    <KeyDescriptor use="signing">
+      <ds:KeyInfo>
+        <ds:X509Data>
+          <ds:X509Certificate>
+MIIDHDCCAgSgAwIBAgIJAPEnL5jgbeVoMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
+BAMMD2lkcC5leGFtcGxlLmVkdTAeFw0xODEwMTAyMDM1NDBaFw0yMzEwMDkyMDM1
+NDBaMBoxGDAWBgNVBAMMD2lkcC5leGFtcGxlLmVkdTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKwTrvQhmFX3SUNgJAhQ/YV0UX56Rt53mwbiKuH+Ez83
+7z6XRynBVsfzHfbWe0IpNKx5mIr84dfbGhQKQBEKzQuek7ihW3J6PIVZN1A3icZZ
+B9i7gow902bT0ZfRG8QW49gl7pk3ASutPcO9Dq5Xc/AqWr3OSO/Pei0yBtTdzG3b
+rm0u0gbj3P2tjt7BN77wIB+yjJsND3ITtP0MFXIJxLTlty8thwqQOAOAYcF+rhC5
+znnBLsRNo0E57PtzZs8i/BpEX2uPTxpEyvlU1vtyxcKUiHtK5ZjOsDEkS2rEualr
++FILYg/Oxw1gi0+mNO1a94Ft+UoLiREztq6MQt8OK98CAwEAAaNlMGMwQgYDVR0R
+BDswOYIPaWRwLmV4YW1wbGUuZWR1hiZodHRwczovL2lkcC5leGFtcGxlLmVkdS9p
+ZHAvc2hpYmJvbGV0aDAdBgNVHQ4EFgQU3ZJ8oHkmlgPtZuZAxnzONccPsb8wDQYJ
+KoZIhvcNAQELBQADggEBAIJ4oZKSMGpF8J3qdfjLZGkc3iVbu/eiE1MD77no0oCz
+nelY0CNUBuFJk1Xv+Bv0fW0cVugtMPz4xi7zv0zkpS2IVxpPZWBosuVabUD9k+V4
+iN5woJdO7e2KRGvhlWmbkmoZUvhygDe0u0vblNfLzDwFQvxHXiWG//P7SanoQrjP
+dE8U21tYz+EFm6s5TvHxVhr9id8c+UacAFCpAtzUB+J8K1abx05XlKsySflkOQV9
+JbM4zOy5gXSI5dY9dGUF77g0muyC+jAhIhLSt/7v3vJgvBurrxPoeBFXOU3D+siT
+VZlKtYzYjJhVqXx1vKrWEE1hkpqm+iYgZe4MvgcdswY=
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </KeyDescriptor>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/ECP"/>
+  </IDPSSODescriptor>
+</EntityDescriptor>
+
diff --git a/demo/complex2/idp/shibboleth-idp/metadata/midpoint-sp.xml b/demo/complex2/idp/shibboleth-idp/metadata/midpoint-sp.xml
new file mode 100644
index 0000000..54f0577
--- /dev/null
+++ b/demo/complex2/idp/shibboleth-idp/metadata/midpoint-sp.xml
@@ -0,0 +1,80 @@
+<!--
+This is example metadata only. Do *NOT* supply it as is without review,
+and do *NOT* provide it in real time to your partners.
+ -->
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_57114916ca68943103854cb57a3a3b1c7c38bb81" entityID="https://midpointdemo/shibboleth">
+
+  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+  </md:Extensions>
+
+  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://localhost:8443/Shibboleth.sso/Login"/>
+      <idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://localhost:8443/Shibboleth.sso/Login" index="1"/>
+    </md:Extensions>
+    <md:KeyDescriptor>
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:KeyName>midpoint.sp.example.org</ds:KeyName>
+        <ds:X509Data>
+          <ds:X509SubjectName>CN=midpoint.sp.example.org,O=Internet2/TIER,L=Ann Arbor,ST=MI,C=US</ds:X509SubjectName>
+          <ds:X509Certificate>MIIDqDCCApCgAwIBAgIJAKUZrfriIt9cMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXZXZvbHZldW0uc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU0NjU3WhcNMTkwOTE0MDU0NjU3WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF2V2b2x2ZXVtLnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw5v1zxlM94yaBssgNNbIUJwW
+XxbGxgSs2AWBeg2aEi/VQd2UE5ivZakNJlqWSJyHo2xE4kxeSyBBxinjSyhmpNao
+xIcqQsgW0gxo4SEHo3kUXWPo+of/pj6CslutsSJZWGTRV0dHITvaWX+NM8eXMfgu
+mJFwy3RMdLaWQhY1Dyi2jNoO+DZnfNgPyPeEZcmORaoeEID9QdZfHtcgTf2QfSHq
++xsTwHB6Ro5t7YD2ma8Krb/XcDTfsq3qJemd7LhPj5lGmhYSMgDbgwEkZgZ1kBOP
+lfsP2BvX5nipv7Vd1C5YXmv+NDR8V3yAWBC7ZAenxGmrnkaSVXnpUplUsGGm1QID
+AQABo1MwUTAdBgNVHQ4EFgQUuxSZwW6V1P/b0tsTM32OU/v/n+UwHwYDVR0jBBgw
+FoAUuxSZwW6V1P/b0tsTM32OU/v/n+UwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAJWLXEfZkPeUyiGvsIUjczzdF3ptqXoP9aETS2pOV9sTri19R
+TsQZW6XQRHGtuEOsqEGH8yiTdGR5hbGC+ynH/xTJnK+tBn/R3KrgxLKyMvoUzAPl
+mhVq1dh+ZEtbsRpQRRubP6nm9kXNma0cXrkJSzuWM0W+l/xSOOYiSRRk3XWJfVjn
+9jQlcJRh5SOkKN08oZHrCYKxToEuOfV8PtRj3T80DhsBTv2SHqhg4cBhzQPb0Kjm
+9m4IkYOz8c5ZtuHDGnqMHw60Nyt+jyik4mMFP2frcOVP0W0sgwcfHllYzHoA/Khq
+Yk3TBVs1BjPuNDJWHct8Eo68YP2/ZvzqfVM87Q==
+</ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
+    </md:KeyDescriptor>
+    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:8443/Shibboleth.sso/Artifact/SOAP" index="1"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:8443/Shibboleth.sso/SLO/SOAP"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:8443/Shibboleth.sso/SLO/Redirect"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:8443/Shibboleth.sso/SLO/POST"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:8443/Shibboleth.sso/SLO/Artifact"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:8443/Shibboleth.sso/SAML2/POST" index="1"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost:8443/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:8443/Shibboleth.sso/SAML2/Artifact" index="3"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://localhost:8443/Shibboleth.sso/SAML2/ECP" index="4"/>
+  </md:SPSSODescriptor>
+
+</md:EntityDescriptor>
diff --git a/demo/complex2/midpoint-objects-manual/tasks/task-async-update-grouper.xml b/demo/complex2/midpoint-objects-manual/tasks/task-async-update-grouper.xml
new file mode 100644
index 0000000..750ddc5
--- /dev/null
+++ b/demo/complex2/midpoint-objects-manual/tasks/task-async-update-grouper.xml
@@ -0,0 +1,43 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="47fc57bd-8c34-4555-9b9f-7087ff179860">
+	<name>Grouper async updates</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<!-- ... -->
+	</extension>
+	<taskIdentifier>1552664339630-0-2</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>AsynchronousUpdate</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/async-update/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex2/midpoint-objects-manual/tasks/task-import-sis-persons.xml b/demo/complex2/midpoint-objects-manual/tasks/task-import-sis-persons.xml
new file mode 100644
index 0000000..9fa12e9
--- /dev/null
+++ b/demo/complex2/midpoint-objects-manual/tasks/task-import-sis-persons.xml
@@ -0,0 +1,29 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+      oid="22c2a3d0-0961-4255-9eec-c550a79aeaaa">
+   <name>Import from SIS persons</name>
+   <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:type="c:ExtensionType">
+      <mext:kind>account</mext:kind>
+      <mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+      <mext:tracingInterval>2000</mext:tracingInterval>
+   </extension>
+   <taskIdentifier>1535407239440-0-1</taskIdentifier>
+   <ownerRef oid="00000000-0000-0000-0000-000000000002"
+             relation="org:default"
+             type="c:UserType"><!-- administrator --></ownerRef>
+   <executionStatus>runnable</executionStatus>
+   <category>ImportingAccounts</category>
+   <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3</handlerUri>
+   <objectRef oid="4d70a0da-02dd-41cf-b0a1-00e75d3eaa15"
+              relation="org:default"
+              type="c:ResourceType"><!-- SQL SIS persons (sources) --></objectRef>
+   <recurrence>single</recurrence>
+   <binding>loose</binding>
+</task>
diff --git a/demo/complex2/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml b/demo/complex2/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
new file mode 100644
index 0000000..6dd7321
--- /dev/null
+++ b/demo/complex2/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
@@ -0,0 +1,43 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="605a0127-a313-442a-9d5e-151eac8b0745">
+	<name>Grouper reconciliation (groups)</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<mext:objectclass>ri:GroupObjectClass</mext:objectclass>
+	</extension>
+	<taskIdentifier>605a0127-a313-442a-9d5e-151eac8b0745</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>Reconciliation</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/reconciliation/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex2/midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml b/demo/complex2/midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
new file mode 100644
index 0000000..ed0dd54
--- /dev/null
+++ b/demo/complex2/midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
@@ -0,0 +1,44 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="42aa9f43-64c5-41a6-814c-b58b9ea4e204">
+	<name>Grouper reconciliation (users)</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+                <mext:tracingInterval>2000</mext:tracingInterval>
+ 	</extension>
+	<taskIdentifier>42aa9f43-64c5-41a6-814c-b58b9ea4e204</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>Reconciliation</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/reconciliation/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex2/midpoint-objects/functionLibraries/function-library-grouper.xml b/demo/complex2/midpoint-objects/functionLibraries/function-library-grouper.xml
new file mode 100644
index 0000000..8ac9b0e
--- /dev/null
+++ b/demo/complex2/midpoint-objects/functionLibraries/function-library-grouper.xml
@@ -0,0 +1,177 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<functionLibrary oid="2eef4181-25fa-420f-909d-846a36ca90f3"
+				 xmlns='http://midpoint.evolveum.com/xml/ns/public/common/common-3'
+				 xmlns:c='http://midpoint.evolveum.com/xml/ns/public/common/common-3'
+				 xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3'
+				 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+				 xmlns:xsd='http://www.w3.org/2001/XMLSchema'
+				 xmlns:piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'>
+	<name>grouper</name>
+	<description>Functions for Grouper AMQP connector</description>
+	<function>
+
+		<!-- Some examples:
+	{
+	  encrypted=false,
+	  esbEvent=[
+	  {
+		sourceId=ldap,
+		membershipType=flattened,
+		fieldName=members,
+		groupId=00000000000000000000000000000001,
+		changeOccurred=false,
+		createdOnMicros=1551884863420000,
+		subjectId=banderson,
+		id=94320942304930294023940329403294,
+		sequenceNumber=1000,
+		eventType=MEMBERSHIP_ADD,
+		groupName=etc:midpointGroups
+	  }
+	]}
+
+
+	 {
+	  "encrypted": false,
+	  "esbEvent": [
+		{
+		  "displayName": "ref:alumni",
+		  "changeOccurred": false,
+		  "createdOnMicros": 1551884850499000,
+		  "parentStemId": "9a7ce40af6c546148b41eec81b8ca18d",
+		  "id": "00000000000000000000000000000002",
+		  "sequenceNumber": "110",
+		  "eventType": "GROUP_ADD",
+		  "name": "ref:alumni"
+		}
+	  ]
+	}
+	 -->
+
+
+		<name>createUcfChange</name>
+		<parameter>
+			<name>message</name>
+			<type>c:AsyncUpdateMessageType</type>
+		</parameter>
+		<parameter>
+			<name>superGroup</name>
+			<type>xsd:string</type>
+		</parameter>
+		<parameter>
+			<name>groupIncludePattern</name>
+			<type>xsd:anyType</type>
+		</parameter>
+		<parameter>
+			<name>groupExcludePattern</name>
+			<type>xsd:anyType</type>
+		</parameter>
+		<parameter>
+			<name>relevantSourceId</name>
+			<type>xsd:string</type>
+		</parameter>
+		<script>
+			<code>
+				import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+				import com.evolveum.prism.xml.ns._public.types_3.*
+				import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
+				import com.evolveum.midpoint.schema.util.*
+				import com.evolveum.midpoint.prism.path.*
+
+				esbEvent = midpoint.getMessageBodyAsMap(message)['esbEvent'][0]
+				log.info('esbEvent = {}', esbEvent)
+				eventType = esbEvent['eventType']
+				if (eventType == 'MEMBERSHIP_ADD' || eventType == 'MEMBERSHIP_DELETE') {
+					groupName = esbEvent['groupName']
+					if (groupName == null) {
+						log.warn('No group name in membership change message, ignoring it: {}', esbEvent)
+						return null
+					}
+					isExported = matches(groupName, groupIncludePattern, groupExcludePattern)
+					isSuper = groupName == superGroup
+					if (!isExported &amp;&amp; !isSuper) {
+						log.info('Irrelevant group membership change, ignoring it: {}', groupName)
+						return null
+					}
+					sourceId = esbEvent['sourceId']
+					if (sourceId != relevantSourceId) {
+						log.info('Irrelevant subject source ID in membership change message, ignoring it: {}', sourceId)
+						return null
+					}
+					subjectId = esbEvent['subjectId']
+					log.info('### {} - {} - {}', subjectId, eventType, groupName)
+					identifiers = new HashMap()
+					identifiers.put(ICFS_NAME, subjectId)
+					identifiers.put(ICFS_UID, subjectId)
+					ObjectDeltaType delta
+					if (isExported) {
+						itemDelta = new ItemDeltaType()
+						itemDelta.modificationType = eventType == 'MEMBERSHIP_ADD' ? ModificationTypeType.ADD : ModificationTypeType.DELETE
+						itemDelta.path = new ItemPathType(ItemPath.create(ShadowType.F_ATTRIBUTES, 'group'))
+						itemDelta.value.add(RawType.fromPropertyRealValue(groupName, null, prismContext))
+						delta = new ObjectDeltaType()
+						delta.changeType = ChangeTypeType.MODIFY
+						delta.itemDelta.add(itemDelta)
+					} else {
+						delta = null
+					}
+					return UcfChangeUtil.create(RI_ACCOUNT_OBJECT_CLASS, identifiers, delta, prismContext)
+				} else if (eventType == 'GROUP_ADD' || eventType == 'GROUP_DELETE') {
+					groupName = esbEvent['name']
+					groupId = esbEvent['id']
+					isExported = matches(groupName, groupIncludePattern, groupExcludePattern)
+					if (!isExported) {
+						log.info('Irrelevant group add/delete event, ignoring it: {}', groupName)
+						return null
+					}
+					identifiers = new HashMap()
+					identifiers.put(ICFS_NAME, groupName)
+					identifiers.put(ICFS_UID, groupId)
+					ObjectDeltaType delta
+					if (eventType == 'GROUP_DELETE') {
+						delta = new ObjectDeltaType()
+						delta.changeType = ChangeTypeType.DELETE
+					} else {
+						delta = null
+					}
+					return UcfChangeUtil.create(RI_GROUP_OBJECT_CLASS, identifiers, delta, prismContext)
+				} else {
+					log.warn('Unsupported event type: {} -> {}', eventType, esbEvent)
+					return null
+				}
+
+				def matches(String name, Collection includes, Collection excludes) {
+					matches(name, includes) &amp;&amp; !matches(name, excludes)
+				}
+
+				def matches(String name, Collection patterns) {
+					if (name == null || patterns == null) {
+						false
+					} else {
+						for (pattern in patterns) {
+							if (name ==~ pattern) {
+								return true
+							}
+						}
+						false
+					}
+				}
+			</code>
+		</script>
+		<returnType>c:UcfChangeType</returnType>
+	</function>
+</functionLibrary>
diff --git a/demo/complex2/midpoint-objects/objectTemplates/template-org-affiliation.xml b/demo/complex2/midpoint-objects/objectTemplates/template-org-affiliation.xml
new file mode 100644
index 0000000..672f948
--- /dev/null
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-org-affiliation.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d87aa04f-189c-4d6f-b6e1-216dad622142">
+    <name>template-org-affiliation</name>
+    <mapping>
+        <name>metarole</name>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>fecae27b-d1d3-40ae-95fa-8f7e44e2ee70</oid>     <!--  metarole-affiliation -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <name>identifier</name>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        grouperName?.substring(16)           // from ref:affiliation:xxx
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <name>name</name>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'affiliation_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <name>displayName</name>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'Affiliation: ' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+</objectTemplate>
diff --git a/demo/complex2/midpoint-objects/objectTemplates/template-org-course.xml b/demo/complex2/midpoint-objects/objectTemplates/template-org-course.xml
new file mode 100644
index 0000000..bec4c40
--- /dev/null
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-org-course.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d35bdec6-643b-41d8-ad5d-8eeb701169d1">
+    <name>template-org-course</name>
+    <mapping>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>8aa99e7b-f7d3-4585-9800-14bab4d26a43</oid>     <!--  metarole-course -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        grouperName?.substring(11)           // from ref:course:xxx
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'course_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>
+</objectTemplate>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/objectTemplates/template-org-department.xml b/demo/complex2/midpoint-objects/objectTemplates/template-org-department.xml
new file mode 100644
index 0000000..6320e23
--- /dev/null
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-org-department.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="0caf2f69-7c72-4946-b218-d84e78b2a057">
+    <name>template-org-department</name>
+    <mapping>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>ffa9eaec-9539-4d15-97aa-24cd5b92ca5b</oid>     <!--  metarole-department -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        grouperName?.substring(9)           // from ref:dept:xxx
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'department_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>    
+</objectTemplate>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/objectTemplates/template-org-generic-group.xml b/demo/complex2/midpoint-objects/objectTemplates/template-org-generic-group.xml
new file mode 100644
index 0000000..3492c5a
--- /dev/null
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-org-generic-group.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="e2a6193a-8981-4143-9da1-9a7b32c0b819">
+    <name>template-org-generic-group</name>
+    <mapping>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>48e231be-8474-4ed0-a85e-6acf4c5e8d52</oid>     <!--  metarole-generic-group -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'generic_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>    
+</objectTemplate>
diff --git a/demo/complex2/midpoint-objects/objectTemplates/template-org-mailing-list.xml b/demo/complex2/midpoint-objects/objectTemplates/template-org-mailing-list.xml
new file mode 100644
index 0000000..04c339e
--- /dev/null
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-org-mailing-list.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="be84a39a-c004-490b-9b78-a871b837f6df">
+    <name>template-org-mailing-list</name>
+    <mapping>
+        <strength>strong</strength>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>RoleType</targetType>
+                <oid>1c7beff4-cdf6-4e9f-b54c-79d0766f6fbe</oid>     <!--  metarole-mailing-list -->
+            </assignmentTargetSearch>
+        </expression>
+        <target>
+            <path>assignment</path>
+        </target>
+    </mapping>
+    <item>
+        <ref>identifier</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>extension/grouperName</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        grouperName?.substring(16)           // from app:mailinglist:xxx
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>name</ref>
+        <mapping>
+            <strength>strong</strength>
+            <source>
+                <path>identifier</path>
+            </source>
+            <expression>
+                <script>
+                    <code>
+                        'mailinglist_' + identifier
+                    </code>
+                </script>
+            </expression>
+        </mapping>
+    </item>
+    <item>
+        <ref>displayName</ref>
+        <mapping>
+            <strength>strong</strength>
+            <expression>
+                <script>
+                    <code>
+                        'Mailing list: ' + identifier
+                    </code>
+                </script>
+            </expression>
+            <source>
+                <path>identifier</path>
+            </source>
+        </mapping>
+    </item>    
+</objectTemplate>
\ No newline at end of file
diff --git a/demo/complex/midpoint-objects/objectTemplates/template-org-group.xml b/demo/complex2/midpoint-objects/objectTemplates/template-role-midpoint-group.xml
similarity index 68%
rename from demo/complex/midpoint-objects/objectTemplates/template-org-group.xml
rename to demo/complex2/midpoint-objects/objectTemplates/template-role-midpoint-group.xml
index 0cd047f..62296e9 100644
--- a/demo/complex/midpoint-objects/objectTemplates/template-org-group.xml
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-role-midpoint-group.xml
@@ -1,18 +1,17 @@
 <?xml version="1.0"?>
 <objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
-    oid="e2a6193a-8981-4143-9da1-9a7b32c0b819">
-    <name>template-org-group</name>
+    oid="804f8658-0828-4dab-a2ed-f13985e4f80b">
+    <name>template-role-midpoint-group</name>
     <mapping>
         <strength>strong</strength>
         <expression>
             <assignmentTargetSearch>
                 <targetType>RoleType</targetType>
-                <oid>48e231be-8474-4ed0-a85e-6acf4c5e8d52</oid>     <!--  metarole-group -->
+                <oid>c691e15a-f30b-4e15-8445-532db07ceeeb</oid>     <!--  metarole-midpoint-group -->
             </assignmentTargetSearch>
         </expression>
         <target>
             <path>assignment</path>
         </target>
     </mapping>
-    
 </objectTemplate>
diff --git a/demo/complex2/midpoint-objects/objectTemplates/template-user.xml b/demo/complex2/midpoint-objects/objectTemplates/template-user.xml
new file mode 100644
index 0000000..d381aaa
--- /dev/null
+++ b/demo/complex2/midpoint-objects/objectTemplates/template-user.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" oid="8098b124-c20c-4965-8adf-e528abedf7a4">
+    <name>User Template</name>
+    <mapping>
+        <strength>strong</strength>
+        <source>
+            <path>extension/grouperGroup</path>
+        </source>
+        <expression>
+            <assignmentTargetSearch>
+                <targetType>OrgType</targetType>
+                <filter>
+                    <q:equal>
+                        <q:path>extension/grouperName</q:path>                       
+                        <expression>
+                            <script>
+                                <code>
+                                    grouperGroup
+                                </code>
+                            </script>
+                        </expression>
+                    </q:equal>
+                </filter>
+                <assignmentProperties>
+                    <subtype>grouper-group</subtype>
+                </assignmentProperties>
+                <createOnDemand>true</createOnDemand>
+                <populateObject>
+                    <populateItem>
+                        <target>
+                            <path>subtype</path>
+                        </target>
+                        <expression>
+                            <script>
+                                <code>
+                                    switch (grouperGroup) {
+                                        case ~/ref:affiliation:.*/: return 'affiliation'
+                                        case ~/ref:dept:.*/: return 'department'
+                                        case ~/ref:course:.*/: return 'course'
+                                        case ~/app:mailinglist:.*/: return 'mailing-list'
+                                        default: return 'generic-group'
+                                    }
+                                </code>
+                            </script>
+                        </expression>
+                    </populateItem>
+                    <populateItem>
+                        <expression>
+                            <script>
+                                <code>
+                                    grouperGroup
+                                </code>
+                            </script>
+                        </expression>
+                        <target>
+                            <path>extension/grouperName</path>
+                        </target>
+                    </populateItem>
+                </populateObject>
+            </assignmentTargetSearch>       
+        </expression>
+        <target>
+            <path>assignment</path>
+            <set>
+                <condition>
+                    <script>
+                        <code>
+                            assignment?.subtype.contains('grouper-group')
+                        </code>
+                    </script>
+                </condition>
+            </set>
+        </target>
+    </mapping>
+</objectTemplate>
diff --git a/demo/complex2/midpoint-objects/orgs/org-affiliations.xml b/demo/complex2/midpoint-objects/orgs/org-affiliations.xml
new file mode 100644
index 0000000..618f9ee
--- /dev/null
+++ b/demo/complex2/midpoint-objects/orgs/org-affiliations.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1d7c0e3a-4456-409c-9f50-95407b2eb785">
+    <name>affiliations</name>
+    <displayName>Affiliations</displayName>
+</org>
diff --git a/demo/complex2/midpoint-objects/orgs/org-courses.xml b/demo/complex2/midpoint-objects/orgs/org-courses.xml
new file mode 100644
index 0000000..71d1f7e
--- /dev/null
+++ b/demo/complex2/midpoint-objects/orgs/org-courses.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="225e9360-0639-40ba-8a31-7f31bef067be">
+    <name>courses</name>
+    <displayName>Courses</displayName>
+</org>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/orgs/org-departments.xml b/demo/complex2/midpoint-objects/orgs/org-departments.xml
new file mode 100644
index 0000000..5320c1e
--- /dev/null
+++ b/demo/complex2/midpoint-objects/orgs/org-departments.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="bee44c51-2469-411d-bac7-695728e9c241">
+    <name>departments</name>
+    <displayName>Departments</displayName>
+</org>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/orgs/org-generic-groups.xml b/demo/complex2/midpoint-objects/orgs/org-generic-groups.xml
new file mode 100644
index 0000000..fa39bbc
--- /dev/null
+++ b/demo/complex2/midpoint-objects/orgs/org-generic-groups.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d">
+    <name>generic-groups</name>
+    <displayName>Generic groups</displayName>
+</org>
diff --git a/demo/complex2/midpoint-objects/orgs/org-mailing-lists.xml b/demo/complex2/midpoint-objects/orgs/org-mailing-lists.xml
new file mode 100644
index 0000000..136c3ee
--- /dev/null
+++ b/demo/complex2/midpoint-objects/orgs/org-mailing-lists.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d81fb46c-20c7-44d3-8402-fef404ea1264">
+    <name>mailing-lists</name>
+    <displayName>Mailing lists</displayName>
+</org>
diff --git a/demo/complex2/midpoint-objects/resources/ldap-main.xml b/demo/complex2/midpoint-objects/resources/ldap-main.xml
new file mode 100644
index 0000000..fdb66ec
--- /dev/null
+++ b/demo/complex2/midpoint-objects/resources/ldap-main.xml
@@ -0,0 +1,635 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ Copyright (c) 2010-2017 Evolveum ~ ~ Licensed under the Apache License, 
+	Version 2.0 (the "License"); ~ you may not use this file except in compliance 
+	with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 
+	~ ~ Unless required by applicable law or agreed to in writing, software ~ 
+	distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT 
+	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the 
+	License for the specific language governing permissions and ~ limitations 
+	under the License. -->
+
+
+<resource oid="0a37121f-d515-4a23-9b6d-554c5ef61272"
+        xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3' xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+	xmlns:my="http://whatever.com/my" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
+	xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+
+		<name>OpenLDAP (directory)</name>
+
+		<connectorRef type="ConnectorType">
+			<filter>
+				<q:equal>
+					<q:path>c:connectorType</q:path>
+					<q:value>com.evolveum.polygon.connector.ldap.LdapConnector</q:value>
+				</q:equal>
+			</filter>
+		</connectorRef>
+
+		<connectorConfiguration
+			xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+			xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
+			<icfc:configurationProperties
+				xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
+                <icfcldap:port>389</icfcldap:port>
+                <icfcldap:host>directory</icfcldap:host>
+				<icfcldap:baseContext>dc=internet2,dc=edu</icfcldap:baseContext>
+				<icfcldap:bindDn>cn=Directory Manager</icfcldap:bindDn>
+				<icfcldap:bindPassword>
+					<t:clearValue>password</t:clearValue>
+				</icfcldap:bindPassword>
+				<icfcldap:uidAttribute>nsUniqueId</icfcldap:uidAttribute>
+				<icfcldap:pagingStrategy>auto</icfcldap:pagingStrategy> <!-- spr? -->
+				<icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute>
+				<icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes>
+				<icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
+				<icfcldap:operationalAttributes>nsAccountLock</icfcldap:operationalAttributes>
+				<!-- >icfcldap:usePermissiveModify>always</icfcldap:usePermissiveModify>
+				<icfcldap:passwordHashAlgorithm>SSHA</icfcldap:passwordHashAlgorithm  -->
+				<!-- >icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute> <icfcldap:vlvSortOrderingRule>2.5.13.3</icfcldap:vlvSortOrderingRule -->
+			</icfc:configurationProperties>
+			<icfc:resultsHandlerConfiguration>
+				<icfc:enableNormalizingResultsHandler>false</icfc:enableNormalizingResultsHandler>
+				<icfc:enableFilteredResultsHandler>false</icfc:enableFilteredResultsHandler>
+				<icfc:enableAttributesToGetSearchResultsHandler>false</icfc:enableAttributesToGetSearchResultsHandler>
+			</icfc:resultsHandlerConfiguration>
+		</connectorConfiguration>
+
+		<schema>
+			<generationConstraints>
+				<generateObjectClass>ri:inetOrgPerson</generateObjectClass>
+				<generateObjectClass>ri:eduPerson</generateObjectClass>
+				<generateObjectClass>ri:groupOfUniqueNames</generateObjectClass>
+				<generateObjectClass>ri:groupOfNames</generateObjectClass>
+				<generateObjectClass>ri:organizationalUnit</generateObjectClass>
+			</generationConstraints>
+		</schema>
+
+		<schemaHandling>
+			<objectType>
+				<kind>account</kind>
+				<displayName>Normal Account</displayName>
+				<default>true</default>
+				<objectClass>ri:inetOrgPerson</objectClass>
+				<auxiliaryObjectClass>ri:eduPerson</auxiliaryObjectClass>
+				<attribute>
+					<ref>ri:dn</ref>
+					<displayName>Distinguished Name</displayName>
+                    <limitations>
+                        <minOccurs>0</minOccurs>
+                    </limitations>
+                    <tolerant>false</tolerant>
+					<matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>name</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    'uid=' + name + ',ou=People,dc=internet2,dc=edu'
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:cn</ref>
+					<displayName>Common Name</displayName>
+					<limitations>
+						<minOccurs>0</minOccurs>
+					</limitations>
+                    <tolerant>false</tolerant>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>fullName</path>
+                        </source>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:sn</ref>
+					<displayName>Surname</displayName>
+                    <limitations>
+                        <minOccurs>0</minOccurs>
+                    </limitations>
+                    <tolerant>false</tolerant>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>familyName</path>
+                        </source>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:givenName</ref>
+					<displayName>Given Name</displayName>
+                    <limitations>
+                        <minOccurs>0</minOccurs>
+                    </limitations>
+                    <tolerant>false</tolerant>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>givenName</path>
+                        </source>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:uid</ref>
+					<displayName>Login Name</displayName>
+                    <tolerant>false</tolerant>
+					<matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>name</path>
+                        </source>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:mail</ref>
+					<displayName>Mail</displayName>
+					<matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <tolerant>false</tolerant>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>emailAddress</path>
+                        </source>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:employeeNumber</ref>
+                    <tolerant>false</tolerant>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>employeeNumber</path>
+                        </source>
+                    </outbound>
+				</attribute>
+				<attribute>
+					<ref>ri:businessCategory</ref>
+                    <tolerant>false</tolerant>
+				</attribute>
+				<attribute>
+					<ref>ri:eduPersonAffiliation</ref>
+					<outbound>
+						<strength>strong</strength>
+						<source>
+							<path>extension/rawAffiliation</path>
+						</source>
+					</outbound>
+                    <tolerant>false</tolerant>
+				</attribute>
+                <association>
+                    <tolerant>false</tolerant>
+                    <ref>ri:group</ref>
+                    <kind>entitlement</kind>
+                    <intent>affiliation-group</intent>
+                    <intent>course-group</intent>
+                    <intent>midpoint-group</intent>
+                    <intent>generic-group</intent>
+                    <direction>objectToSubject</direction>
+                    <associationAttribute>ri:uniqueMember</associationAttribute>
+                    <valueAttribute>ri:dn</valueAttribute>
+                </association>
+				<protected>
+					<filter>
+						<q:equal>
+							<q:matching>http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase</q:matching>
+							<q:path>attributes/ri:dn</q:path>
+							<q:value>cn=root,dc=internet2,dc=edu</q:value>
+						</q:equal>
+					</filter>
+				</protected>
+                <credentials>
+                    <password>
+                        <outbound>
+                            <expression>
+                                <asIs />
+                            </expression>
+                        </outbound>
+                    </password>
+                </credentials>
+			</objectType>
+            
+            <objectType>
+                <kind>entitlement</kind>
+                <intent>affiliation-group</intent>
+                <displayName>LDAP Group for affiliations</displayName>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <attribute>
+                    <ref>ri:uniqueMember</ref>
+                    <matchingRule>mr:distinguishedName</matchingRule>
+                    <fetchStrategy>minimal</fetchStrategy>
+                </attribute>
+                <attribute>
+                    <ref>ri:dn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    basic.composeDnWithSuffix('cn', identifier, 'ou=Affiliations,ou=Groups,dc=internet2,dc=edu')
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+                </attribute>
+                <attribute>
+                    <ref>ri:cn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>weak</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                    </outbound>
+                </attribute>
+            </objectType>
+            <objectType>
+                <kind>entitlement</kind>
+                <intent>course-group</intent>
+                <displayName>LDAP Group for courses</displayName>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <attribute>
+                    <ref>ri:uniqueMember</ref>
+                    <matchingRule>mr:distinguishedName</matchingRule>
+                    <fetchStrategy>minimal</fetchStrategy>
+                </attribute>
+                <attribute>
+                    <ref>ri:dn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    basic.composeDnWithSuffix('cn', identifier, 'ou=Courses,ou=Groups,dc=internet2,dc=edu')
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+                </attribute>
+                <attribute>
+                    <ref>ri:cn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>weak</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                    </outbound>
+                </attribute>
+            </objectType>
+            <objectType>
+                <kind>entitlement</kind>
+                <intent>midpoint-group</intent>
+                <displayName>LDAP Group</displayName>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <attribute>
+                    <ref>ri:uniqueMember</ref>
+                    <matchingRule>mr:distinguishedName</matchingRule>
+                    <fetchStrategy>minimal</fetchStrategy>
+                </attribute>
+                <attribute>
+                    <ref>ri:dn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <trace>true</trace>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    basic.composeDnWithSuffix('cn', identifier, 'ou=midpoint,ou=Groups,dc=internet2,dc=edu')
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+                </attribute>
+                <attribute>
+                    <ref>ri:cn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>weak</strength>
+                        <source>
+                            <path>identifier</path>
+                        </source>
+                    </outbound>
+                </attribute>
+            </objectType>
+            <objectType>
+                <kind>entitlement</kind>
+                <intent>generic-group</intent>
+                <displayName>LDAP Group</displayName>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <attribute>
+                    <ref>ri:uniqueMember</ref>
+                    <matchingRule>mr:distinguishedName</matchingRule>
+                    <fetchStrategy>minimal</fetchStrategy>
+                </attribute>
+                <attribute>
+                    <ref>ri:dn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>strong</strength>
+                        <trace>true</trace>
+                        <source>
+                            <path>extension/grouperName</path>
+                        </source>
+                        <expression>
+                            <script>
+                                <code>
+                                    basic.composeDnWithSuffix('cn', grouperName, 'ou=generic,ou=Groups,dc=internet2,dc=edu')
+                                </code>
+                            </script>
+                        </expression>
+                    </outbound>
+                </attribute>
+                <attribute>
+                    <ref>ri:cn</ref>
+                    <matchingRule>mr:stringIgnoreCase</matchingRule>
+                    <outbound>
+                        <strength>weak</strength>
+                        <source>
+                            <path>extension/grouperName</path>
+                        </source>
+                    </outbound>
+                </attribute>
+            </objectType>
+		</schemaHandling>
+
+		<synchronization>
+			<objectSynchronization>
+				<enabled>true</enabled>
+				<correlation>
+					<q:equal>
+						<q:path>name</q:path>
+						<expression>
+							<path>
+								declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
+								$account/attributes/ri:uid
+							</path>
+						</expression>
+					</q:equal>
+				</correlation>
+				<reaction>
+					<situation>linked</situation>
+					<synchronize>true</synchronize>
+				</reaction>
+				<reaction>
+					<situation>deleted</situation>
+					<synchronize>true</synchronize>
+					<action>
+						<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+					</action>
+				</reaction>
+				<reaction>
+					<situation>unlinked</situation>
+					<synchronize>true</synchronize>
+					<action>
+						<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+					</action>
+				</reaction>
+				<reaction>
+					<situation>unmatched</situation>
+					<synchronize>true</synchronize>
+					<action>
+						<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+					</action>
+				</reaction>
+			</objectSynchronization>
+            <objectSynchronization>
+                <name>affiliation-group sync</name>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <kind>entitlement</kind>
+                <intent>affiliation-group</intent>
+                <focusType>OrgType</focusType>
+                <enabled>true</enabled>
+                <condition>
+                    <script>
+                        <code>
+                            import javax.naming.ldap.*
+                            dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                            log.info('affiliation-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=Affiliations,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=Affiliations,ou=Groups,dc=internet2,dc=edu'))
+                        </code>
+                    </script>
+                </condition>
+                <correlation>
+                    <q:and>
+                        <q:equal>
+                            <q:path>identifier</q:path>
+                            <expression>
+                                <path>$shadow/attributes/ri:cn</path>
+                            </expression>
+                        </q:equal>
+                        <q:equal>
+                            <q:path>subtype</q:path>
+                            <q:value>affiliation</q:value>
+                        </q:equal>
+                    </q:and>
+                </correlation>
+                <reaction>
+                    <situation>linked</situation>
+                    <synchronize>true</synchronize>
+                </reaction>
+                <reaction>
+                    <situation>deleted</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unlinked</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unmatched</situation>
+                </reaction>
+            </objectSynchronization>
+            <objectSynchronization>
+                <name>course-group sync</name>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <kind>entitlement</kind>
+                <intent>course-group</intent>
+                <focusType>OrgType</focusType>
+                <enabled>true</enabled>
+                <condition>
+                    <script>
+                        <code>
+                            import javax.naming.ldap.*
+                            dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                            log.info('course-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=Courses,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=Courses,ou=Groups,dc=internet2,dc=edu'))
+                        </code>
+                    </script>
+                </condition>
+                <correlation>
+                    <q:and>
+                        <q:equal>
+                            <q:path>identifier</q:path>
+                            <expression>
+                                <path>$shadow/attributes/ri:cn</path>
+                            </expression>
+                        </q:equal>
+                        <q:equal>
+                            <q:path>subtype</q:path>
+                            <q:value>course</q:value>
+                        </q:equal>
+                    </q:and>
+                </correlation>
+                <reaction>
+                    <situation>linked</situation>
+                    <synchronize>true</synchronize>
+                </reaction>
+                <reaction>
+                    <situation>deleted</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unlinked</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unmatched</situation>
+                </reaction>
+            </objectSynchronization>
+            <objectSynchronization>
+                <name>midpoint-group sync</name>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <kind>entitlement</kind>
+                <intent>midpoint-group</intent>
+                <focusType>RoleType</focusType>
+                <enabled>true</enabled>
+                <condition>
+                    <script>
+                        <code>
+                            import javax.naming.ldap.*
+                            dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                            log.info('midpoint-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=midpoint,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=midpoint,ou=Groups,dc=internet2,dc=edu'))
+                        </code>
+                    </script>
+                </condition>
+                <correlation>
+                    <q:and>
+                        <q:equal>
+                            <q:path>identifier</q:path>
+                            <expression>
+                                <path>$shadow/attributes/ri:cn</path>
+                            </expression>
+                        </q:equal>
+                        <q:equal>
+                            <q:path>subtype</q:path>
+                            <q:value>midpoint-group</q:value>
+                        </q:equal>
+                    </q:and>
+                </correlation>
+                <reaction>
+                    <situation>linked</situation>
+                    <synchronize>true</synchronize>
+                </reaction>
+                <reaction>
+                    <situation>deleted</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unlinked</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unmatched</situation>
+                </reaction>
+            </objectSynchronization>
+            <objectSynchronization>
+                <name>generic-group sync</name>
+                <objectClass>ri:groupOfUniqueNames</objectClass>
+                <kind>entitlement</kind>
+                <intent>generic-group</intent>
+                <focusType>OrgType</focusType>
+                <enabled>true</enabled>
+                <condition>
+                    <script>
+                        <code>
+                            import javax.naming.ldap.*
+                            dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                            log.info('generic-group sync: considering {}; dn.size={}, dn.startsWith={}', dn, dn.size(), dn.startsWith(new LdapName('ou=Generic,ou=Groups,dc=internet2,dc=edu')))
+                            dn.size() == 5 &amp;&amp; dn.startsWith(new LdapName('ou=Generic,ou=Groups,dc=internet2,dc=edu'))
+                        </code>
+                    </script>
+                </condition>
+                <correlation>
+                    <q:and>
+                        <q:equal>
+                            <q:path>identifier</q:path>
+                            <expression>
+                                <path>$shadow/attributes/ri:cn</path>
+                            </expression>
+                        </q:equal>
+                        <q:equal>
+                            <q:path>subtype</q:path>
+                            <q:value>generic-group</q:value>
+                        </q:equal>
+                    </q:and>
+                </correlation>
+                <reaction>
+                    <situation>linked</situation>
+                    <synchronize>true</synchronize>
+                </reaction>
+                <reaction>
+                    <situation>deleted</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unlinked</situation>
+                    <synchronize>true</synchronize>
+                    <action>
+                        <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                    </action>
+                </reaction>
+                <reaction>
+                    <situation>unmatched</situation>
+                </reaction>
+            </objectSynchronization>
+		</synchronization>
+        <consistency>
+            <avoidDuplicateValues>true</avoidDuplicateValues>
+        </consistency>
+</resource>
diff --git a/demo/complex2/midpoint-objects/resources/resource-grouper.xml b/demo/complex2/midpoint-objects/resources/resource-grouper.xml
new file mode 100644
index 0000000..702f6dc
--- /dev/null
+++ b/demo/complex2/midpoint-objects/resources/resource-grouper.xml
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resource oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233"
+		  xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+          xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+          xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+          xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+          xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+		  xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+		  xmlns:rest="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-grouper-rest/com.evolveum.polygon.connector.grouper.rest.GrouperConnector"
+		  xmlns:conf="http://midpoint.evolveum.com/xml/ns/public/connector/builtin-1/bundle/com.evolveum.midpoint.provisioning.ucf.impl.builtin.async/AsyncUpdateConnector"
+          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+	<name>Grouper Resource</name>
+	<connectorRef type="c:ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.grouper.rest.GrouperConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+	<connectorConfiguration>
+		<icfc:configurationProperties>
+			<rest:baseUrl>https://grouper-ws:443</rest:baseUrl>
+			<rest:username>banderson</rest:username>
+			<rest:password>password</rest:password>
+			<rest:superGroup>etc:midpointGroups</rest:superGroup>
+			<rest:groupIncludePattern>midpoint:.*</rest:groupIncludePattern>
+			<rest:groupIncludePattern>app:.*</rest:groupIncludePattern>
+			<rest:groupIncludePattern>test:.*</rest:groupIncludePattern>
+			<rest:groupIncludePattern>ref:.*</rest:groupIncludePattern>
+			<rest:groupExcludePattern>.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)</rest:groupExcludePattern>
+			<rest:subjectSource>ldap</rest:subjectSource>
+			<rest:groupSource>g:gsa</rest:groupSource>
+			<rest:ignoreSslValidation>true</rest:ignoreSslValidation>
+		</icfc:configurationProperties>
+	</connectorConfiguration>
+	<additionalConnector>
+		<name>AMQP async update connector</name>
+		<connectorRef type="c:ConnectorType">
+			<filter>
+				<q:equal>
+					<q:path>connectorType</q:path>
+					<q:value>AsyncUpdateConnector</q:value>
+				</q:equal>
+			</filter>
+		</connectorRef>
+		<connectorConfiguration>
+			<conf:sources>
+				<amqp091>
+					<uri>amqp://mq:5672</uri>
+					<username>guest</username>
+					<password>guest</password>
+					<queue>sampleQueue</queue>
+				</amqp091>
+			</conf:sources>
+			<conf:transformExpression>
+				<script>
+					<code>
+						// ------------------ START OF CONFIGURATION ------------------
+
+						parameters = [
+							superGroup: 'etc:midpointGroups',
+							groupIncludePattern: [ 'midpoint:.*', 'app:.*', 'test:.*', 'ref:.*' ],
+							groupExcludePattern: [ '.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)' ],
+							relevantSourceId: 'ldap'
+						]
+
+						// ------------------ END OF CONFIGURATION ------------------
+
+						parameters.put('message', message)
+						grouper.execute('createUcfChange', parameters)
+					</code>
+				</script>
+			</conf:transformExpression>
+		</connectorConfiguration>
+	</additionalConnector>
+	<schemaHandling>
+		<objectType>
+			<kind>account</kind>
+			<intent>subject</intent>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<default>true</default>
+			<attribute>
+				<ref>icfs:name</ref>
+				<inbound>
+                    <strength>strong</strength>
+					<target>
+						<path>name</path>
+					</target>
+				</inbound>
+			</attribute>
+			<attribute>
+				<ref>ri:group</ref>
+				<displayName>Subject Groups</displayName>
+				<inbound>
+			        <strength>strong</strength>
+					<target>
+						<path>extension/grouperGroup</path>
+					</target>
+				</inbound>
+			</attribute>
+		</objectType>
+		<objectType>
+			<kind>entitlement</kind>
+			<intent>group</intent>
+			<objectClass>ri:GroupObjectClass</objectClass>
+			<default>true</default>
+			<attribute>
+				<ref>icfs:name</ref>
+				<inbound>
+			        <strength>strong</strength>
+					<target>
+						<path>extension/grouperName</path>
+					</target>
+				</inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>
+                                switch (input) {
+                                    case ~/ref:affiliation:.*/: return 'affiliation'
+                                    case ~/ref:dept:.*/: return 'department'
+                                    case ~/ref:course:.*/: return 'course'
+                                    case ~/app:mailinglist:.*/: return 'mailing-list'
+                                    default: return 'generic-group'
+                                }
+                            </code>
+                        </script>
+                    </expression>
+                    <target>
+                        <path>subtype</path>
+                    </target>
+                </inbound>
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<kind>account</kind>
+			<intent>subject</intent>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<focusType>UserType</focusType>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/name
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<kind>entitlement</kind>
+			<intent>group</intent>
+			<objectClass>ri:GroupObjectClass</objectClass>
+			<focusType>OrgType</focusType>
+			<correlation>
+				<q:equal>
+					<q:path>extension/grouperName</q:path>
+                    <expression>
+                        <path>
+                            $account/attributes/name
+                        </path>
+                    </expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#deleteFocus</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+	<caching>
+		<cachingStategy>passive</cachingStategy>
+	</caching>
+</resource>
diff --git a/demo/complex2/midpoint-objects/resources/scriptedsql-sis-persons.xml b/demo/complex2/midpoint-objects/resources/scriptedsql-sis-persons.xml
new file mode 100644
index 0000000..6fe8355
--- /dev/null
+++ b/demo/complex2/midpoint-objects/resources/scriptedsql-sis-persons.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<c:resource oid="4d70a0da-02dd-41cf-b0a1-00e75d3eaa15" 
+    xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+    xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+    xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+    xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
+    xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+
+	<c:name>SQL SIS persons (sources)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>connectorType</q:path>
+				<q:value>net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<c:connectorConfiguration>
+
+		<icfc:configurationProperties 
+			xmlns:icscscriptedsql="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/net.tirasa.connid.bundles.db.scriptedsql/net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector">
+			<icscscriptedsql:host>sources</icscscriptedsql:host>
+			<icscscriptedsql:port>3306</icscscriptedsql:port>
+			<icscscriptedsql:quoting></icscscriptedsql:quoting>
+			<icscscriptedsql:user>root</icscscriptedsql:user>
+			<icscscriptedsql:password>
+				<clearValue>123321</clearValue>
+			</icscscriptedsql:password>
+			<icscscriptedsql:database>sis</icscscriptedsql:database>
+			<!-- >icscscriptedsql:clearTextPasswordToScript>true</icscscriptedsql:clearTextPasswordToScript -->
+			<icscscriptedsql:scriptingLanguage>GROOVY</icscscriptedsql:scriptingLanguage>
+
+			<icscscriptedsql:searchScriptFileName>/opt/midpoint/var/res/sis-persons/SearchScript.groovy</icscscriptedsql:searchScriptFileName>
+			<icscscriptedsql:testScriptFileName>/opt/midpoint/var/res/sis-persons/TestScript.groovy</icscscriptedsql:testScriptFileName>
+			<icscscriptedsql:schemaScriptFileName>/opt/midpoint/var/res/sis-persons/SchemaScript.groovy</icscscriptedsql:schemaScriptFileName>
+			
+			<icscscriptedsql:reloadScriptOnExecution>true</icscscriptedsql:reloadScriptOnExecution>
+			<!-- >icscscriptedsql:syncScriptFileName>/opt/midpoint/var/res/SyncScript.groovy</icscscriptedsql:syncScriptFileName -->
+
+			<icscscriptedsql:validConnectionQuery></icscscriptedsql:validConnectionQuery>
+			<icscscriptedsql:jndiProperties></icscscriptedsql:jndiProperties>
+
+			<icscscriptedsql:jdbcDriver>org.mariadb.jdbc.Driver</icscscriptedsql:jdbcDriver>
+			<icscscriptedsql:jdbcUrlTemplate>jdbc:mysql://%h:%p/%d?useUnicode=true&amp;characterEncoding=utf8&amp;connectionCollation=utf8_bin</icscscriptedsql:jdbcUrlTemplate>
+			<icscscriptedsql:enableEmptyString>true</icscscriptedsql:enableEmptyString>
+			<icscscriptedsql:rethrowAllSQLExceptions>true</icscscriptedsql:rethrowAllSQLExceptions>
+			<icscscriptedsql:nativeTimestamps>false</icscscriptedsql:nativeTimestamps>
+			<icscscriptedsql:allNative>false</icscscriptedsql:allNative>
+			<!--<icscscriptedsql:changeLogColumn>timestamp</icscscriptedsql:changeLogColumn> -->
+			<icscscriptedsql:datasource></icscscriptedsql:datasource>
+		</icfc:configurationProperties>
+
+		<!-- Generic ICF configuration -->
+
+	</c:connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<kind>account</kind>
+			<displayName>Normal Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<displayName>UID</displayName>
+                <inbound>
+                    <target>
+                        <path>name</path>
+                    </target>
+                </inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <assignmentTargetSearch>
+                            <targetType>RoleType</targetType>
+                            <oid>c89f31dd-8d4f-4e0a-82cb-58ff9d8c1b2f</oid>     <!--  role-ldap-basic -->
+                            <assignmentProperties>
+                                <subtype>grouper-basic</subtype>
+                            </assignmentProperties>
+                        </assignmentTargetSearch>
+                    </expression>                            
+                    <target>
+                        <path>assignment</path>
+                        <set>
+                            <condition>
+                                <script>
+                                    <code>
+                                        assignment.subtype.contains('grouper-basic')
+                                    </code>
+                                </script>
+                            </condition>
+                        </set>
+                    </target>
+                </inbound>
+			</attribute>
+            <attribute>
+                <ref>ri:fullName</ref>
+                <displayName>Full Name</displayName>
+                <inbound>
+                    <target>
+                        <path>fullName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:surname</ref>
+                <displayName>Surname</displayName>
+                <inbound>
+                    <target>
+                        <path>familyName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <displayName>Given Name</displayName>
+                <inbound>
+                    <target>
+                        <path>givenName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:mail</ref>
+                <displayName>Mail</displayName>
+                <matchingRule>mr:stringIgnoreCase</matchingRule>
+                <inbound>
+                    <target>
+                        <path>emailAddress</path>
+                    </target>
+                </inbound>
+            </attribute>
+		</objectType>
+	</schemaHandling>
+
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
+							$account/attributes/ri:uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+				</action>
+			</reaction>
+
+			<reaction>
+				<situation>unlinked</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+
+</c:resource>
+
diff --git a/demo/complex2/midpoint-objects/resources/target-cs-portal.xml b/demo/complex2/midpoint-objects/resources/target-cs-portal.xml
new file mode 100644
index 0000000..7706bcb
--- /dev/null
+++ b/demo/complex2/midpoint-objects/resources/target-cs-portal.xml
@@ -0,0 +1,111 @@
+<c:resource oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Computer science portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/cs-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>identifier</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:identifier</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:name</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:courses</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-course -->
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/identifier
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/resources/target-faculty-portal.xml b/demo/complex2/midpoint-objects/resources/target-faculty-portal.xml
new file mode 100644
index 0000000..f3e7aed
--- /dev/null
+++ b/demo/complex2/midpoint-objects/resources/target-faculty-portal.xml
@@ -0,0 +1,120 @@
+<c:resource oid="e417225d-8a08-46f3-9b5d-624990b52386" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Faculty portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/faculty-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>givenName</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:familyName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>familyName</path>
+                    </source>
+                </outbound>
+            </attribute>
+			<attribute>
+				<ref>ri:fullName</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/resources/target-mailing-lists.xml b/demo/complex2/midpoint-objects/resources/target-mailing-lists.xml
new file mode 100644
index 0000000..4d60d27
--- /dev/null
+++ b/demo/complex2/midpoint-objects/resources/target-mailing-lists.xml
@@ -0,0 +1,101 @@
+<c:resource oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Mailing lists (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/mailing-lists.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:lists</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-mailing-list -->
+            </attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex2/midpoint-objects/roles/metarole-affiliation.xml b/demo/complex2/midpoint-objects/roles/metarole-affiliation.xml
new file mode 100644
index 0000000..aaef986
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/metarole-affiliation.xml
@@ -0,0 +1,54 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="fecae27b-d1d3-40ae-95fa-8f7e44e2ee70">
+    <name>metarole-affiliation</name>
+    <inducement id="1">
+        <targetRef oid="1d7c0e3a-4456-409c-9f50-95407b2eb785" relation="org:default" type="c:OrgType" />     <!-- affiliations -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>affiliation-group</intent>
+        </construction>
+    </inducement>
+    <inducement id="3">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>affiliation-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <resourceRef oid="e417225d-8a08-46f3-9b5d-624990b52386" relation="org:default" type="c:ResourceType" />     <!-- Faculty CSV -->
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier == 'faculty'</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</role>
diff --git a/demo/complex2/midpoint-objects/roles/metarole-course.xml b/demo/complex2/midpoint-objects/roles/metarole-course.xml
new file mode 100644
index 0000000..b1acba8
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/metarole-course.xml
@@ -0,0 +1,66 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="8aa99e7b-f7d3-4585-9800-14bab4d26a43">
+    <name>metarole-course</name>
+    <inducement id="1">
+        <targetRef oid="225e9360-0639-40ba-8a31-7f31bef067be" type="c:OrgType"/>            <!-- courses -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>course-group</intent>
+        </construction>
+    </inducement>
+    <inducement id="3">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>course-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <strength>weak</strength>
+            <resourceRef oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" relation="org:default" type="c:ResourceType" />     <!-- CS CSV -->
+            <attribute>
+                <c:ref>ri:courses</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier?.startsWith('CS')</code>
+                </script>
+            </expression>
+        </condition>
+        <order>2</order>
+    </inducement>
+</role>
diff --git a/demo/complex2/midpoint-objects/roles/metarole-department.xml b/demo/complex2/midpoint-objects/roles/metarole-department.xml
new file mode 100644
index 0000000..4b8ed2b
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/metarole-department.xml
@@ -0,0 +1,32 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="ffa9eaec-9539-4d15-97aa-24cd5b92ca5b">
+    <name>metarole-department</name>
+    <inducement id="1">
+        <targetRef oid="bee44c51-2469-411d-bac7-695728e9c241" type="c:OrgType"/>            <!-- departments -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
+            <attribute>
+                <ref>ri:businessCategory</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</role>
diff --git a/demo/complex2/midpoint-objects/roles/metarole-grouper-group.xml b/demo/complex2/midpoint-objects/roles/metarole-grouper-group.xml
new file mode 100644
index 0000000..34df300
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/metarole-grouper-group.xml
@@ -0,0 +1,55 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="48e231be-8474-4ed0-a85e-6acf4c5e8d52">
+    <name>metarole-grouper-group</name>
+    <inducement id="1">
+        <targetRef oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d" relation="org:default" type="c:OrgType" />     <!-- groups -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>generic-group</intent>
+        </construction>
+        <order>1</order>
+    </inducement>
+    <inducement id="3">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>generic-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <resourceRef oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" relation="org:default" type="c:ResourceType" />     <!-- CS CSV -->
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier == 'app:cs'</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</role>
diff --git a/demo/complex2/midpoint-objects/roles/metarole-mailing-list.xml b/demo/complex2/midpoint-objects/roles/metarole-mailing-list.xml
new file mode 100644
index 0000000..e5a680c
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/metarole-mailing-list.xml
@@ -0,0 +1,59 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="1c7beff4-cdf6-4e9f-b54c-79d0766f6fbe">
+    <name>metarole-mailing-list</name>
+    <inducement id="1">
+        <targetRef oid="d81fb46c-20c7-44d3-8402-fef404ea1264" relation="org:default" type="c:OrgType" />     <!-- mailing-lists -->
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <kind>entitlement</kind>
+            <intent>generic-group</intent>
+        </construction>
+        <order>1</order>
+    </inducement>
+    <inducement id="3">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>generic-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+    <inducement id="4">
+        <construction>
+            <resourceRef oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" relation="org:default" type="c:ResourceType" />     <!-- Mailing lists CSV -->
+            <attribute>
+                <c:ref>ri:lists</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</role>
diff --git a/demo/complex2/midpoint-objects/roles/metarole-midpoint-group.xml b/demo/complex2/midpoint-objects/roles/metarole-midpoint-group.xml
new file mode 100644
index 0000000..a2a2c9a
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/metarole-midpoint-group.xml
@@ -0,0 +1,38 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="c691e15a-f30b-4e15-8445-532db07ceeeb">
+    <name>metarole-midpoint-group</name>
+    <inducement id="1">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
+            <kind>entitlement</kind>
+            <intent>midpoint-group</intent>
+        </construction>
+    </inducement>
+    <inducement id="2">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP for Grouper (i-data) -->
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>midpoint-group</intent>
+                            </projectionDiscriminator>
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>2</order>
+    </inducement>
+</role>
diff --git a/demo/complex2/midpoint-objects/roles/role-grouper-sysadmin.xml b/demo/complex2/midpoint-objects/roles/role-grouper-sysadmin.xml
new file mode 100644
index 0000000..cb81a23
--- /dev/null
+++ b/demo/complex2/midpoint-objects/roles/role-grouper-sysadmin.xml
@@ -0,0 +1,17 @@
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="d48ec05b-fffd-4262-acd3-d9ff63365b62">
+    <name>role-grouper-sysadmin</name>
+    <assignment id="1">
+        <targetRef oid="c691e15a-f30b-4e15-8445-532db07ceeeb" type="RoleType"/>         <!--  metarole-midpoint-group -->
+    </assignment>
+    <subtype>midpoint-group</subtype>
+    <identifier>sysadmingroup</identifier>
+</role>
diff --git a/demo/complex/midpoint-objects/roles/metarole-group.xml b/demo/complex2/midpoint-objects/roles/role-ldap-basic.xml
similarity index 71%
rename from demo/complex/midpoint-objects/roles/metarole-group.xml
rename to demo/complex2/midpoint-objects/roles/role-ldap-basic.xml
index bdf7113..3efa968 100644
--- a/demo/complex/midpoint-objects/roles/metarole-group.xml
+++ b/demo/complex2/midpoint-objects/roles/role-ldap-basic.xml
@@ -7,10 +7,12 @@
       xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
       xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-      oid="48e231be-8474-4ed0-a85e-6acf4c5e8d52">
-    <name>metarole-group</name>
+      oid="c89f31dd-8d4f-4e0a-82cb-58ff9d8c1b2f">
+    <name>role-ldap-basic</name>
     <inducement id="1">
-        <targetRef oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d" relation="org:default" type="c:OrgType" />     <!-- groups -->
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- OpenLDAP -->
+        </construction>
+        <order>1</order>
     </inducement>
-
 </role>
diff --git a/demo/complex2/midpoint-objects/systemConfigurations/SystemConfiguration.xml b/demo/complex2/midpoint-objects/systemConfigurations/SystemConfiguration.xml
new file mode 100644
index 0000000..2845715
--- /dev/null
+++ b/demo/complex2/midpoint-objects/systemConfigurations/SystemConfiguration.xml
@@ -0,0 +1,251 @@
+<systemConfiguration xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oid="00000000-0000-0000-0000-000000000001" version="2">
+      <name>SystemConfiguration</name>
+      <metadata>
+         <requestTimestamp>2018-08-15T13:30:55.282+02:00</requestTimestamp>
+         <createTimestamp>2018-08-15T13:30:55.372+02:00</createTimestamp>
+         <createChannel>http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#init</createChannel>
+      </metadata>
+      <operationExecution id="17">
+         <timestamp>2018-08-15T13:30:55.562+02:00</timestamp>
+         <operation>
+            <objectDelta>
+               <t:changeType>add</t:changeType>
+               <t:objectType>c:SystemConfigurationType</t:objectType>
+            </objectDelta>
+            <executionResult>
+               <operation>com.evolveum.midpoint.model.impl.lens.ChangeExecutor.executeDelta</operation>
+               <status>handled_error</status>
+               <token>1000000000000000009</token>
+               <message>Object of type 'SystemConfigurationType' with oid '00000000-0000-0000-0000-000000000001' was not found.</message>
+            </executionResult>
+            <objectName>SystemConfiguration</objectName>
+         </operation>
+         <status>handled_error</status>
+         <channel>http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#init</channel>
+      </operationExecution>
+      <globalSecurityPolicyRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="00000000-0000-0000-0000-000000000120" relation="org:default" type="tns:SecurityPolicyType"/>
+      <logging>
+         <classLogger id="1">
+            <level>ERROR</level>
+            <package>ro.isdc.wro.extensions.processor.css.Less4jProcessor</package>
+         </classLogger>
+         <classLogger id="2">
+            <level>OFF</level>
+            <package>org.hibernate.engine.jdbc.spi.SqlExceptionHelper</package>
+         </classLogger>
+         <classLogger id="3">
+            <level>OFF</level>
+            <package>org.hibernate.engine.jdbc.batch.internal.BatchingBatch</package>
+         </classLogger>
+         <classLogger id="4">
+            <level>WARN</level>
+            <package>org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl</package>
+         </classLogger>
+         <classLogger id="5">
+            <level>OFF</level>
+            <package>org.hibernate.internal.ExceptionMapperStandardImpl</package>
+         </classLogger>
+         <classLogger id="6">
+            <level>OFF</level>
+            <package>net.sf.jasperreports.engine.fill.JRFillDataset</package>
+         </classLogger>
+         <classLogger id="7">
+            <level>WARN</level>
+            <package>org.apache.wicket.resource.PropertiesFactory</package>
+         </classLogger>
+         <classLogger id="8">
+            <level>ERROR</level>
+            <package>org.springframework.context.support.ResourceBundleMessageSource</package>
+         </classLogger>
+         <classLogger id="9">
+            <level>INFO</level>
+            <package>com.evolveum.midpoint.model.impl.lens.projector.Projector</package>
+         </classLogger>
+         <classLogger id="10">
+            <level>INFO</level>
+            <package>com.evolveum.midpoint.model.impl.lens.Clockwork</package>
+         </classLogger>
+         <appender id="11" xsi:type="c:FileAppenderConfigurationType">
+            <pattern>%date [%X{subsystem}] [%thread] %level \(%logger\): %msg%n</pattern>
+            <name>MIDPOINT_LOG</name>
+            <fileName>${midpoint.home}/log/midpoint.log</fileName>
+            <filePattern>${midpoint.home}/log/midpoint-%d{yyyy-MM-dd}.%i.log</filePattern>
+            <maxHistory>10</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <append>true</append>
+         </appender>
+         <appender id="12" xsi:type="c:FileAppenderConfigurationType">
+            <pattern>%date %level: %msg%n</pattern>
+            <name>MIDPOINT_PROFILE_LOG</name>
+            <fileName>${midpoint.home}/log/midpoint-profile.log</fileName>
+            <filePattern>${midpoint.home}/log/midpoint-profile-%d{yyyy-MM-dd}.%i.log</filePattern>
+            <maxHistory>10</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <append>true</append>
+         </appender>
+         <rootLoggerAppender>MIDPOINT_LOG</rootLoggerAppender>
+         <rootLoggerLevel>INFO</rootLoggerLevel>
+         <auditing>
+            <enabled>false</enabled>
+            <details>false</details>
+         </auditing>
+      </logging>
+      <defaultObjectPolicyConfiguration id="18">
+         <type>OrgType</type>
+         <subtype>affiliation</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="d87aa04f-189c-4d6f-b6e1-216dad622142" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="19">
+         <type>OrgType</type>
+         <subtype>department</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="0caf2f69-7c72-4946-b218-d84e78b2a057" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="20">
+         <type>OrgType</type>
+         <subtype>course</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="d35bdec6-643b-41d8-ad5d-8eeb701169d1" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="110">
+         <type>OrgType</type>
+         <subtype>mailing-list</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="be84a39a-c004-490b-9b78-a871b837f6df" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="100">
+         <type>OrgType</type>
+         <subtype>generic-group</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="e2a6193a-8981-4143-9da1-9a7b32c0b819" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="21">
+         <type>RoleType</type>
+         <subtype>midpoint-group</subtype>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="804f8658-0828-4dab-a2ed-f13985e4f80b" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <defaultObjectPolicyConfiguration id="101">
+         <type>UserType</type>
+         <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="8098b124-c20c-4965-8adf-e528abedf7a4" relation="org:default" type="tns:ObjectTemplateType"/>
+      </defaultObjectPolicyConfiguration>
+      <cleanupPolicy>
+         <auditRecords>
+            <maxAge>P3M</maxAge>
+         </auditRecords>
+         <closedTasks>
+            <maxAge>P1M</maxAge>
+         </closedTasks>
+      </cleanupPolicy>
+      <internals>
+         <enableExperimentalCode>true</enableExperimentalCode>
+         <operationExecutionRecording>
+             <skipWhenSuccess>true</skipWhenSuccess>
+         </operationExecutionRecording>
+         <focusConstraintsChecking>
+             <skipWhenNoChange>true</skipWhenNoChange>
+             <skipWhenNoIteration>true</skipWhenNoIteration>
+         </focusConstraintsChecking>
+         <projectionConstraintsChecking>
+             <skipWhenNoChange>true</skipWhenNoChange>
+             <skipWhenNoIteration>true</skipWhenNoIteration>
+         </projectionConstraintsChecking>
+         <synchronizationSituationUpdating>
+             <skipWhenNoChange>true</skipWhenNoChange>
+         </synchronizationSituationUpdating>
+         <caching>
+             <profile>
+                 <global>true</global>
+                 <localRepoCache>
+                     <statistics>
+                         <classification>perCacheAndObjectType</classification>
+                     </statistics>
+                 </localRepoCache>
+                 <globalRepoCache>
+                     <timeToLive>60</timeToLive>
+                     <objectTypeSettings>
+                         <objectType>SystemConfigurationType</objectType>
+                         <objectType>ArchetypeType</objectType>
+                         <objectType>ObjectTemplateType</objectType>
+                         <objectType>SecurityPolicyType</objectType>
+                         <objectType>ValuePolicyType</objectType>
+                         <objectType>ResourceType</objectType>
+                         <objectType>RoleType</objectType>
+                         <objectType>OrgType</objectType>
+                         <objectType>ServiceType</objectType>
+                         <objectType>ShadowType</objectType>
+                     </objectTypeSettings>
+                     <statistics>
+                         <classification>perCacheAndObjectType</classification>
+                     </statistics>
+                 </globalRepoCache>
+             </profile>
+         </caching>
+         <repository>
+             <statistics>
+                <classification>perOperationAndObjectType</classification>
+             </statistics>
+         </repository>
+         <tracing>
+             <profile>
+                 <name>performance</name>
+                 <displayName>Performance tracing</displayName>
+                 <visible>true</visible>
+                 <default>true</default>
+                 <fileNamePattern>performance-trace %{timestamp} %{focusName} %{milliseconds}</fileNamePattern>
+                 <createRepoObject>true</createRepoObject>
+                 <compressOutput>true</compressOutput>
+             </profile>
+             <profile>
+                 <name>functional</name>
+                 <displayName>Functional tracing</displayName>
+                 <visible>true</visible>
+                 <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                 <createRepoObject>true</createRepoObject>
+                 <compressOutput>true</compressOutput>
+                 <collectLogEntries>true</collectLogEntries>
+                 <tracingTypeProfile>
+                     <level>normal</level>
+                 </tracingTypeProfile>
+             </profile>
+         </tracing>
+      </internals>
+      <adminGuiConfiguration>
+         <userDashboardLink id="13">
+            <targetUrl>/self/profile</targetUrl>
+            <label>Profile</label>
+            <description>View/edit your profile</description>
+            <icon>
+               <cssClass>fa fa-user</cssClass>
+            </icon>
+            <color>green</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfProfile</authorization>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll</authorization>
+         </userDashboardLink>
+         <userDashboardLink id="14">
+            <targetUrl>/self/credentials</targetUrl>
+            <label>Credentials</label>
+            <description>View/edit your credentials</description>
+            <icon>
+               <cssClass>fa fa-shield</cssClass>
+            </icon>
+            <color>blue</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfCredentials</authorization>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll</authorization>
+         </userDashboardLink>
+         <userDashboardLink id="15">
+            <targetUrl>/admin/users</targetUrl>
+            <label>List users</label>
+            <icon>
+               <cssClass>fa fa-users</cssClass>
+            </icon>
+            <color>red</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#users</authorization>
+         </userDashboardLink>
+         <userDashboardLink id="16">
+            <targetUrl>/admin/resources</targetUrl>
+            <label>List resources</label>
+            <icon>
+               <cssClass>fa fa-database</cssClass>
+            </icon>
+            <color>purple</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#resources</authorization>
+         </userDashboardLink>
+         <enableExperimentalFeatures>false</enableExperimentalFeatures>
+      </adminGuiConfiguration>
+   </systemConfiguration>
diff --git a/demo/complex2/midpoint-objects/users/user-banderson.xml b/demo/complex2/midpoint-objects/users/user-banderson.xml
new file mode 100644
index 0000000..fa1316a
--- /dev/null
+++ b/demo/complex2/midpoint-objects/users/user-banderson.xml
@@ -0,0 +1,20 @@
+<user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      oid="e897468f-20bd-419c-8fc5-1fe60e2600de">
+    <name>banderson</name>
+    <assignment id="1">
+        <targetRef oid="d48ec05b-fffd-4262-acd3-d9ff63365b62" relation="org:default" type="c:RoleType">
+            <!-- role-grouper-sysadmin -->
+        </targetRef>
+    </assignment>
+    <fullName>Bob Anderson</fullName>
+    <givenName>Bob</givenName>
+    <familyName>Anderson</familyName>
+    <credentials>
+        <password>
+            <value>password</value>
+        </password>
+    </credentials>
+</user>
+	
diff --git a/demo/complex2/midpoint_server/Dockerfile b/demo/complex2/midpoint_server/Dockerfile
new file mode 100644
index 0000000..43dac56
--- /dev/null
+++ b/demo/complex2/midpoint_server/Dockerfile
@@ -0,0 +1,9 @@
+FROM tier/midpoint:laboratory
+
+MAINTAINER info@evolveum.com
+
+ENV MP_DIR /opt/midpoint
+
+VOLUME ${MP_DIR}/var
+
+COPY container_files/mp-home/ ${MP_DIR}/var/
diff --git a/demo/complex2/midpoint_server/container_files/httpd/host-cert.pem b/demo/complex2/midpoint_server/container_files/httpd/host-cert.pem
new file mode 100644
index 0000000..9b1021b
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/httpd/host-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAMOSkn4oS2aAMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXbWlkcG9pbnQuc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU1OTQ1WhcNMTkwOTE0MDU1OTQ1WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF21pZHBvaW50LnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApj/b7MEUSfu3oXMfNgRwTse7
+a5UV7Jswf1M/ZN/ZZkAkIxNBevZgozjesvLPWrmsTgONi7XigJUJvCjdjmlW9eDM
+lri/rkD8HuOR1DQCVKL9nvoS2c3D7sq5Emda3V8Tlj82VqfEmePd3sajx7mcTfbH
+8jwAL9NhkC+WMib5IpjLGpG0FEAC0ha7Lxb+7jIiqHVJaqLXJGCyGN4mh6c1Q9S1
+f8RVTiW2a8x22G+9wnZYbkiA2Kxls177imHlhSz8EdvV4IpGw1amrEWhhuDEum7B
+vZ1xQDLatgRqh4qAKLIVYeRnJ8H1FelMa90qB4G08MIPifmTsQwqJyBYaEdgWQID
+AQABo1MwUTAdBgNVHQ4EFgQUqb9BteODF6wv5R57aEON/wGXMiowHwYDVR0jBBgw
+FoAUqb9BteODF6wv5R57aEON/wGXMiowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAAcKhxI+tSItrXmqC0PSmgWyAYpqbkz6W/cefTutXqhIgY09f
+h0LSv7ogTahoGpyiZk9vy6u3OE9bYwxapEfa4KBjO6HxBMIVBBb3RegVjoPzjElN
+BDwAx0VGFcZTXwMxDWycWdG8ql7rCZBvS50w04uTaIgnGmqXAdWWmBgfJ9cRbxW+
+JwO/mOl1QM1lR/5142NpvuUVWlmZSKEGydE5A1qPz2wpDbBR1ym1BQNS4NEqw6Kp
+GSB8jKyCS1Ve0v2wVze2038Wukz02dq9uKPTIO3T+B+ibZmxn6Op/kFCc1/kK5NS
+Q6JdO1B6KquGAYdGmKAcQ19mv+jqGktqWEEf0g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2/midpoint_server/container_files/httpd/host-key.pem b/demo/complex2/midpoint_server/container_files/httpd/host-key.pem
new file mode 100644
index 0000000..5746e59
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmP9vswRRJ+7eh
+cx82BHBOx7trlRXsmzB/Uz9k39lmQCQjE0F69mCjON6y8s9auaxOA42LteKAlQm8
+KN2OaVb14MyWuL+uQPwe45HUNAJUov2e+hLZzcPuyrkSZ1rdXxOWPzZWp8SZ493e
+xqPHuZxN9sfyPAAv02GQL5YyJvkimMsakbQUQALSFrsvFv7uMiKodUlqotckYLIY
+3iaHpzVD1LV/xFVOJbZrzHbYb73CdlhuSIDYrGWzXvuKYeWFLPwR29XgikbDVqas
+RaGG4MS6bsG9nXFAMtq2BGqHioAoshVh5GcnwfUV6Uxr3SoHgbTwwg+J+ZOxDCon
+IFhoR2BZAgMBAAECggEAEIRBpjjceiku6jRUwnoYaks/nIWYQwR8AfpUTwJKR/VR
+Yca097Fokm7A+UhUP3A45RtHQb0VPq8P44iv0kk24YCu8r5yFK7SHYOAZnOwU5ZJ
+2jSAEPF3aM7tKh3okhuzB3dKP7u1NZDE5zAW723KUJiW7sL1RcsbY0bHBj6G+9/H
+NplmsjuGt684vRBB0qOBfKF7EiG7mT69tHuNj4gRza9SMY31UtKbZdt2fNY6mp5V
+HscMba7egZP+Ke0pVX4+go9j7K8GG8hYaQDLjrzlPqrxZ2c5X9cC+CRDI/CHuL/s
+V/2yGZJ6n6UabwZoH83RdFrbQ94rU8Hkli6EvxXvMQKBgQDRpheNW5jDG5TfeJKh
+yfKTDQqH2Tk3BsBYYBN7Hf3m7vbkzlxnAKJAoSLmtRMuoeXvI5MrhzaHGsNIUS76
+LDIZnvB7DLUxhFUZsCPkpAA1QHuTWY96oR3PHnPjpk8lSUvtbOPwDLdzVApeFJgZ
+VqMNArZ7AHsK3Kkyi+f4WVQjbQKBgQDLAWiGb5dx6fAM2W6B6HjNmzjBWOuVEXa2
+76to9jzupBZmETfZgxtWUaWUDuNS+f7dtVUTE+p6v/w8clrHEhEZYkqunIOLo/UA
+LFPiuoTfEsWb1rh+nsCjCgy4uimixj/bSkf7NC6NyKTvCygA1mGnVVJUEPegYlDy
+LXCkaKWxHQKBgQCmyHSKL2lrJkEcOwakEU2acNCE3Gno/cT9SYmV83kvQ8JEqmrW
+QqnRsp9aXIljGscapPmKsmnNt5vNp1AxFAHTYh88NRLczsMIyZj0ZwgHVUI6KhC7
+5Psa78YQQBlMt2/g9TSsnuE+rYgF6mpKFiNm0Vasqeg47uzn2mdzqlUGTQKBgE04
+JutkTUY+h1pL5vYxWKpVDfy19z7H2tFxT1FowPrBneeLSyRI88Ac5I/yLdRlVeY9
+0LOmEr5Igwj3MsKgg7KVKfVLgdo/LrW3Jt2Kt3onKNXDkoBPoNUjwH0QC0Boiue+
+VK0gR0kVdm+bXccbxR+im+NwZNE0NLg6Qqu3RredAoGBALuVoqbPPmTCZXYG328H
+bzOs2aiR7BzPSVByV+qG6jW7w03RAnFPJZp7HMU+ViI5VY0wabUscMSvz5163+gM
+4KwY3v9ZjZzZGukIfLuudkdqtaiVOx/KeAC0n+nG21YU+wpZww8gkfHh1/sa2CME
+CWYCgOnmiTHcj83UaTqEXtmv
+-----END PRIVATE KEY-----
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/cs-portal.csv b/demo/complex2/midpoint_server/container_files/mp-home/cs-portal.csv
new file mode 100644
index 0000000..dfe12f9
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/cs-portal.csv
@@ -0,0 +1 @@
+identifier,name,mail,courses
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/faculty-portal.csv b/demo/complex2/midpoint_server/container_files/mp-home/faculty-portal.csv
new file mode 100644
index 0000000..68a2307
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/faculty-portal.csv
@@ -0,0 +1 @@
+uid,givenName,familyName,fullName,mail
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.2.jar b/demo/complex2/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.2.jar
new file mode 100644
index 0000000..fbc575b
Binary files /dev/null and b/demo/complex2/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.2.jar differ
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar b/demo/complex2/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar
new file mode 100644
index 0000000..88fcb54
Binary files /dev/null and b/demo/complex2/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar differ
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/mailing-lists.csv b/demo/complex2/midpoint_server/container_files/mp-home/mailing-lists.csv
new file mode 100644
index 0000000..f9ee89b
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/mailing-lists.csv
@@ -0,0 +1 @@
+uid,mail,lists
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy b/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy
new file mode 100644
index 0000000..0e0a52f
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy
@@ -0,0 +1,57 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import org.identityconnectors.framework.common.objects.AttributeInfo;
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags;
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder;
+import org.identityconnectors.framework.common.objects.ObjectClassInfo;
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder;
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+// This sample shows how to create 3 basic ObjectTypes: __ACCOUNT__, __GROUP__ and organization.
+// Each of them contains one required attribute and normal String attributes
+
+
+log.info("Entering "+action+" Script");
+
+uidAIB = new AttributeInfoBuilder("uid",String.class);
+uidAIB.setRequired(true);
+
+accAttrsInfo = new HashSet<AttributeInfo>();
+accAttrsInfo.add(uidAIB.build());
+accAttrsInfo.add(AttributeInfoBuilder.build("surname", String.class));
+accAttrsInfo.add(AttributeInfoBuilder.build("givenName", String.class));
+accAttrsInfo.add(AttributeInfoBuilder.build("fullName", String.class));
+accAttrsInfo.add(AttributeInfoBuilder.build("mail", String.class));
+ociAccount = new ObjectClassInfoBuilder().setType("__ACCOUNT__").addAllAttributeInfo(accAttrsInfo).build();
+builder.defineObjectClass(ociAccount);
+
+log.info("Schema script done");
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy b/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy
new file mode 100644
index 0000000..9e16b51
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy
@@ -0,0 +1,78 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used.
+//
+// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+log.info("Entering "+action+" Script");
+
+def sql = new Sql(connection);
+def result = []
+def where = "";
+
+switch ( objectClass ) {
+    case "__ACCOUNT__":
+    sql.eachRow("select uid, surname, givenName, fullName, mail from SIS_PERSONS", {result.add([
+	__UID__:it.uid, 
+	__NAME__:it.uid, 
+	uid:it.uid,
+	surname:it.surname,
+	givenName:it.givenName,
+	fullName:it.fullName,
+	mail:it.mail])} );
+    break
+
+    default:
+    result;
+}
+
+return result;
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy b/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy
new file mode 100644
index 0000000..c887660
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy
@@ -0,0 +1,38 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering "+action+" Script");
+def sql = new Sql(connection);
+
+sql.eachRow("select * from SIS_PERSONS limit 10", { println it.uid } );
+
+
diff --git a/demo/complex2/midpoint_server/container_files/mp-home/schema/internet2.xsd b/demo/complex2/midpoint_server/container_files/mp-home/schema/internet2.xsd
new file mode 100644
index 0000000..4c8e3af
--- /dev/null
+++ b/demo/complex2/midpoint_server/container_files/mp-home/schema/internet2.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<xsd:schema elementFormDefault="qualified"
+  targetNamespace="http://grouper-demo.tier.internet2.edu"
+  xmlns:tns="http://grouper-demo.tier.internet2.edu"
+  xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3"
+  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+  <xsd:complexType name="UserExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:UserType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperGroup" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="rawAffiliation" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="OrgExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:OrgType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperName" type="xsd:string" minOccurs="0"/>
+    </xsd:sequence>
+  </xsd:complexType>  
+</xsd:schema>
+
diff --git a/demo/complex2/mq/Dockerfile b/demo/complex2/mq/Dockerfile
new file mode 100644
index 0000000..1593b80
--- /dev/null
+++ b/demo/complex2/mq/Dockerfile
@@ -0,0 +1,13 @@
+FROM tier/rabbitmq:latest
+
+COPY container_files/etc-rabbitmq/* /etc/rabbitmq/
+COPY container_files/usr-local-bin/* /usr/local/bin/
+
+ENV RABBITMQ_PID_FILE=/var/run/rabbitmq/pid
+
+# Must be on /var/lib/rabbitmq (this is the same place where queues are defined)
+ENV RABBITMQ_INIT_DONE_FILE=/var/lib/rabbitmq/initialization.done
+
+ENTRYPOINT ["/usr/local/bin/demo-entrypoint.sh"]
+
+CMD ["rabbitmq-server"]
diff --git a/demo/complex2/mq/container_files/etc-rabbitmq/rabbitmq.conf b/demo/complex2/mq/container_files/etc-rabbitmq/rabbitmq.conf
new file mode 100644
index 0000000..4c789ba
--- /dev/null
+++ b/demo/complex2/mq/container_files/etc-rabbitmq/rabbitmq.conf
@@ -0,0 +1,2 @@
+# Allow guest access from anywhere (change this in production!)
+loopback_users = none
diff --git a/demo/complex2/mq/container_files/usr-local-bin/demo-entrypoint.sh b/demo/complex2/mq/container_files/usr-local-bin/demo-entrypoint.sh
new file mode 100755
index 0000000..7355248
--- /dev/null
+++ b/demo/complex2/mq/container_files/usr-local-bin/demo-entrypoint.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [ ! -e $RABBITMQ_INIT_DONE_FILE ]; then
+    /usr/local/bin/initialize-rabbitmq.sh &
+else
+    echo "RabbitMQ was already initialized"
+fi
+/usr/local/bin/entrypoint.sh "$@"
diff --git a/demo/complex2/mq/container_files/usr-local-bin/initialize-rabbitmq.sh b/demo/complex2/mq/container_files/usr-local-bin/initialize-rabbitmq.sh
new file mode 100755
index 0000000..3660e80
--- /dev/null
+++ b/demo/complex2/mq/container_files/usr-local-bin/initialize-rabbitmq.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+echo "Executing RabbitMQ initialization"
+echo "Waiting for the server to start up..."
+rabbitmqctl -t 30 wait $RABBITMQ_PID_FILE
+echo "OK, creating sampleQueue..."
+rabbitmqadmin declare queue name=sampleQueue
+echo "Done"
+touch $RABBITMQ_INIT_DONE_FILE
diff --git a/demo/complex2/recompute.sh b/demo/complex2/recompute.sh
new file mode 100755
index 0000000..920ca78
--- /dev/null
+++ b/demo/complex2/recompute.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+recompute roles d48ec05b-fffd-4262-acd3-d9ff63365b62
+recompute users e897468f-20bd-419c-8fc5-1fe60e2600de
diff --git a/demo/complex2/show-queue-size.sh b/demo/complex2/show-queue-size.sh
new file mode 100755
index 0000000..7749953
--- /dev/null
+++ b/demo/complex2/show-queue-size.sh
@@ -0,0 +1 @@
+docker exec complex2_mq_1 rabbitmqctl list_queues
diff --git a/demo/complex2/sources/Dockerfile b/demo/complex2/sources/Dockerfile
new file mode 100644
index 0000000..c76ff73
--- /dev/null
+++ b/demo/complex2/sources/Dockerfile
@@ -0,0 +1,10 @@
+FROM tier/mariadb:mariadb10
+
+COPY container_files/seed-data/ /seed-data/
+
+ENV MYSQL_DATABASE sis
+ENV MYSQL_USER sis_user
+ENV MYSQL_PASSWORD 49321420423
+ENV MYSQL_DATADIR /var/lib/mysql
+ENV AFTER_FIRST_TIME_SQL /seed-data/persons-and-courses.sql
+
diff --git a/demo/complex2/sources/container_files/seed-data/persons-and-courses.sql b/demo/complex2/sources/container_files/seed-data/persons-and-courses.sql
new file mode 100644
index 0000000..65f8376
--- /dev/null
+++ b/demo/complex2/sources/container_files/seed-data/persons-and-courses.sql
@@ -0,0 +1,531 @@
+USE sis;
+
+CREATE TABLE SIS_PERSONS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE SIS_AFFILIATIONS (
+    uid VARCHAR(255) NOT NULL,
+    affiliation VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , affiliation)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex2/targets/Dockerfile b/demo/complex2/targets/Dockerfile
new file mode 100644
index 0000000..6099cce
--- /dev/null
+++ b/demo/complex2/targets/Dockerfile
@@ -0,0 +1,7 @@
+FROM tier/mariadb:mariadb10
+
+#TODO better name for the target database
+ENV MYSQL_DATABASE target
+ENV MYSQL_USER target_user
+ENV MYSQL_PASSWORD fdjskjrkwqjrw
+ENV MYSQL_DATADIR /var/lib/mysql
diff --git a/demo/complex2/targets/container_files/seed-data/target.tmp b/demo/complex2/targets/container_files/seed-data/target.tmp
new file mode 100644
index 0000000..01fa4ef
--- /dev/null
+++ b/demo/complex2/targets/container_files/seed-data/target.tmp
@@ -0,0 +1,531 @@
+USE target;
+
+CREATE TABLE FACULTY_PORTAL_MEMBERS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE MAILING_LIST_MEMBERS (
+    list VARCHAR(255) NOT NULL,
+    member VARCHAR(255) NOT NULL,
+    PRIMARY KEY (list, member)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex2/test-resource-grouper.sh b/demo/complex2/test-resource-grouper.sh
new file mode 100755
index 0000000..c0d5a65
--- /dev/null
+++ b/demo/complex2/test-resource-grouper.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+test_resource 1eff65de-5bb6-483d-9edf-8cc2c2ee0233
diff --git a/demo/complex2/test-resources-1.sh b/demo/complex2/test-resources-1.sh
new file mode 100755
index 0000000..989ad9f
--- /dev/null
+++ b/demo/complex2/test-resources-1.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
+test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+test_resource a343fc2e-3954-4034-ba1a-2b72c21e577a
+test_resource e417225d-8a08-46f3-9b5d-624990b52386
+test_resource fe805d13-481b-43ec-97d8-9d2df72cd38e
diff --git a/demo/complex2/tests/main.bats b/demo/complex2/tests/main.bats
new file mode 100755
index 0000000..ecfb6be
--- /dev/null
+++ b/demo/complex2/tests/main.bats
@@ -0,0 +1,355 @@
+#!/usr/bin/env bats
+
+load ../../../common
+load ../../../library
+
+@test "000 Cleanup before running the tests" {
+    (cd ../simple ; docker-compose down -v)
+    (cd ../shibboleth ; docker-compose down -v)
+    (cd ../postgresql ; docker-compose down -v)
+    docker-compose down -v
+}
+
+@test "010 Initialize and start the composition" {
+    # We want to fail cleanly if there's any interference
+    docker ps
+    ! (docker ps | grep -E "shibboleth_(idp|directory)_1|(complex|simple|shibboleth|postgresql)_(midpoint_server|midpoint_data)_1")
+    docker-compose build --pull grouper_daemon grouper_ui grouper_data directory sources targets midpoint_data idp mq
+    # Sometimes the tier/midpoint:xyz is not yet in the repository, causing issues with --pull
+    docker-compose build midpoint_server
+    docker-compose up -d
+}
+
+@test "020 Wait until components are started" {
+    touch $BATS_TMPDIR/not-started
+    wait_for_midpoint_start complex_midpoint_server_1 complex_midpoint_data_1
+    wait_for_shibboleth_idp_start complex_idp_1
+    wait_for_grouper_ui_start complex_grouper_ui_1
+    rm $BATS_TMPDIR/not-started
+}
+
+@test "040 Check midPoint health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+}
+
+@test "050 Check Shibboleth IDP health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health_shibboleth_idp
+}
+
+@test "060 Check Grouper health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    skip TODO
+}
+
+@test "100 Get 'administrator'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    get_and_check_object users 00000000-0000-0000-0000-000000000002 administrator
+}
+
+@test "110 And and get 'test110'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    echo "<user><name>test110</name></user>" >/tmp/test110.xml
+    add_object users /tmp/test110.xml
+    rm /tmp/test110.xml
+    search_and_check_object users test110
+    delete_object_by_name users test110
+}
+
+@test "200 Upload objects" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    # reduce data in SIS database so imports will take reasonable time
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_COURSES where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_AFFILIATIONS where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_PERSONS where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+
+    check_health
+    ./upload-objects.sh
+
+    search_and_check_object objectTemplates template-org-course
+    search_and_check_object objectTemplates template-org-department
+    search_and_check_object objectTemplates template-role-affiliation
+    search_and_check_object objectTemplates template-role-generic-group
+    
+    search_and_check_object orgs courses
+    search_and_check_object orgs departments
+
+    search_and_check_object resources "OpenLDAP (directory)"
+    search_and_check_object resources "Grouper Resource"
+    search_and_check_object resources "SQL SIS courses (sources)"
+    search_and_check_object resources "SQL SIS persons (sources)"
+
+    search_and_check_object roles metarole-affiliation
+    search_and_check_object roles metarole-course
+    search_and_check_object roles metarole-department 
+    search_and_check_object roles metarole-generic-group
+    search_and_check_object roles role-grouper-sysadmin
+    search_and_check_object roles role-ldap-basic
+}
+
+@test "210 Test LDAP and SQL resources" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
+    test_resource 13660d60-071b-4596-9aa1-5efcd1256c04
+    test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+}
+
+@test "220 Import SIS_PERSONS" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-import-sis-persons.xml
+    search_and_check_object tasks "Import from SIS persons"
+    wait_for_task_completion 22c2a3d0-0961-4255-9eec-c550a79aeaaa 6 10
+    assert_task_success 22c2a3d0-0961-4255-9eec-c550a79aeaaa
+
+    search_and_check_object users jsmith
+    search_and_check_object users banderson
+    search_and_check_object users kwhite
+    search_and_check_object users whenderson
+    search_and_check_object users ddavis
+    search_and_check_object users cmorrison
+    search_and_check_object users danderson
+    search_and_check_object users amorrison
+    search_and_check_object users wprice
+    search_and_check_object users mroberts
+
+    check_ldap_account_by_user_name jsmith complex_directory_1
+    check_ldap_account_by_user_name banderson complex_directory_1
+    check_ldap_account_by_user_name kwhite complex_directory_1
+    check_ldap_account_by_user_name whenderson complex_directory_1
+    check_ldap_account_by_user_name ddavis complex_directory_1
+    check_ldap_account_by_user_name cmorrison complex_directory_1
+    check_ldap_account_by_user_name danderson complex_directory_1
+    check_ldap_account_by_user_name amorrison complex_directory_1
+    check_ldap_account_by_user_name wprice complex_directory_1
+    check_ldap_account_by_user_name mroberts complex_directory_1
+}
+
+@test "230 Import SIS_COURSES" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-import-sis-courses.xml
+    search_and_check_object tasks "Import from SIS courses"
+    wait_for_task_completion b73a2e66-8233-4c20-928f-acb30027b33e 8 10
+    assert_task_success b73a2e66-8233-4c20-928f-acb30027b33e
+
+    search_and_check_object orgs course_ACCT101
+    search_and_check_object orgs course_ACCT201
+    search_and_check_object orgs course_CS251
+    search_and_check_object orgs course_CS252
+    search_and_check_object orgs course_MATH100
+    search_and_check_object orgs course_MATH101
+    search_and_check_object orgs course_SCI123
+    search_and_check_object orgs course_SCI404
+
+    check_ldap_courses_by_name course_ACCT101 complex_directory_1
+    check_ldap_courses_by_name course_ACCT201 complex_directory_1
+    check_ldap_courses_by_name course_CS251 complex_directory_1
+    check_ldap_courses_by_name course_CS252 complex_directory_1
+    check_ldap_courses_by_name course_MATH100 complex_directory_1
+    check_ldap_courses_by_name course_MATH101 complex_directory_1
+    check_ldap_courses_by_name course_SCI123 complex_directory_1
+    check_ldap_courses_by_name course_SCI404 complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership whenderson "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership ddavis "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "CS252" complex_directory_1
+
+    check_of_ldap_membership danderson "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership ddavis "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership wprice "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+
+    check_of_ldap_membership danderson "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI123" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI123" complex_directory_1
+
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI404" complex_directory_1
+    check_of_ldap_membership wprice "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI404" complex_directory_1
+}
+
+@test "240 Check 'TestUser240' in Midpoint and LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    echo "<user><name>TestUser240</name><fullName>Test User240</fullName><givenName>Test</givenName><familyName>User240</familyName><credentials><password><value><clearValue>password</clearValue></value></password></credentials></user>" >/tmp/testuser240.xml
+    add_object users /tmp/testuser240.xml
+    rm /tmp/testuser240.xml
+    search_and_check_object users TestUser240
+
+    execute_bulk_action tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml complex_midpoint_server_1
+    execute_bulk_action tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml complex_midpoint_server_1
+
+    check_ldap_account_by_user_name TestUser240 complex_directory_1
+    check_of_ldap_membership TestUser240 "ou=groups,dc=internet2,dc=edu" "sysadmingroup" complex_directory_1
+    
+    delete_object_by_name users TestUser240
+}
+
+@test "250 Make 'banderson' Grouper administrator" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    recompute roles d48ec05b-fffd-4262-acd3-d9ff63365b62
+    execute_bulk_action tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml complex_midpoint_server_1
+    recompute users e897468f-20bd-419c-8fc5-1fe60e2600de # for some reason this looks necessary (TODO)
+    check_of_ldap_membership banderson "ou=groups,dc=internet2,dc=edu" "sysadmingroup" complex_directory_1
+}
+
+#@test "255 Wait 120 seconds for changes to be propagated to Grouper" {
+#    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+#
+#    sleep 120
+#}
+
+@test "260 Export ref groups" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    ./add-ref-groups.sh
+}
+
+@test "265 Wait 120 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 120
+}
+
+@test "300 Test Grouper resource" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    test_resource 1eff65de-5bb6-483d-9edf-8cc2c2ee0233
+}
+
+@test "310 Import Grouper-to-midPoint async update task" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    check_health
+    add_object tasks midpoint-objects-manual/tasks/task-async-update-grouper.xml
+    search_and_check_object tasks "Grouper async updates"
+}
+
+@test "320 Wait for the queue to become empty" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    ATTEMPT=0
+    MAX_ATTEMPTS=20
+    DELAY=10
+
+    get_messages sampleQueue
+    echo "Messages: $MESSAGES"
+
+    until [[ $ATTEMPT = $MAX_ATTEMPTS ]]; do
+        ATTEMPT=$((ATTEMPT+1))
+        get_messages sampleQueue
+        echo "Messages: $MESSAGES"
+        if [ "$MESSAGES" = "0" ]; then return 0; fi
+        echo "Waiting $DELAY seconds for the queue to become empty (attempt $ATTEMPT) ..."
+        sleep $DELAY
+    done
+    return 1
+}
+
+@test "330 Add wprice to 'midpoint:test' and 'ref:affiliation:alum_includes' groups" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t330.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t330.gsh"
+}
+
+@test "335 Wait 80 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 80
+}
+
+@test "340 Assert wprice membership in LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    assert_ldap_user_has_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_value wprice Entitlement "ref:affiliation:alum" complex_directory_1
+}
+
+@test "350 Add kwhite to 'midpoint:test', remove wprice from 'ref:affiliation:alum_includes'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t350.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t350.gsh"
+}
+
+@test "355 Wait 80 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 80
+}
+
+@test "360 Assert wprice and kwhite membership in LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    assert_ldap_user_has_value kwhite Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_no_value wprice Entitlement "ref:affiliation:alum" complex_directory_1
+}
+
+@test "400 Suspend async update task" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    suspend_task 47fc57bd-8c34-4555-9b9f-7087ff179860 complex_midpoint_server_1
+    wait_for_task_completion 47fc57bd-8c34-4555-9b9f-7087ff179860 5 10
+}
+
+@test "410 Remove kwhite and wprice from 'midpoint:test'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t410.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t410.gsh"
+}
+
+@test "420 Reconcile Grouper" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
+    search_and_check_object tasks "Grouper reconciliation (users)"
+    wait_for_task_completion 42aa9f43-64c5-41a6-814c-b58b9ea4e204 6 10
+    assert_task_success 42aa9f43-64c5-41a6-814c-b58b9ea4e204
+
+    search_and_check_object users jsmith
+    search_and_check_object users banderson
+    search_and_check_object users kwhite
+    search_and_check_object users whenderson
+    search_and_check_object users ddavis
+    search_and_check_object users cmorrison
+    search_and_check_object users danderson
+    search_and_check_object users amorrison
+    search_and_check_object users wprice
+    search_and_check_object users mroberts
+
+    check_ldap_account_by_user_name jsmith complex_directory_1
+    check_ldap_account_by_user_name banderson complex_directory_1
+    check_ldap_account_by_user_name kwhite complex_directory_1
+    check_ldap_account_by_user_name whenderson complex_directory_1
+    check_ldap_account_by_user_name ddavis complex_directory_1
+    check_ldap_account_by_user_name cmorrison complex_directory_1
+    check_ldap_account_by_user_name danderson complex_directory_1
+    check_ldap_account_by_user_name amorrison complex_directory_1
+    check_ldap_account_by_user_name wprice complex_directory_1
+    check_ldap_account_by_user_name mroberts complex_directory_1
+
+    assert_ldap_user_has_no_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_no_value kwhite Entitlement "midpoint:test" complex_directory_1
+}
+
+@test "999 Clean up" {
+    docker-compose down -v
+}
diff --git a/demo/complex2/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml b/demo/complex2/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml
new file mode 100644
index 0000000..9ec69a2
--- /dev/null
+++ b/demo/complex2/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml
@@ -0,0 +1,22 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+   			  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+			  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+			  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+                    <s:type>c:UserType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>c:name</q:path>
+                            <q:value>banderson</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>assign</s:type>
+                        <s:parameter>
+                            <s:name>role</s:name>
+							<c:value xsi:type="xsd:string">d48ec05b-fffd-4262-acd3-d9ff63365b62</c:value>
+                        </s:parameter>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex2/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml b/demo/complex2/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml
new file mode 100644
index 0000000..0cb1a6b
--- /dev/null
+++ b/demo/complex2/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml
@@ -0,0 +1,22 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+   			  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+			  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+			  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+                    <s:type>c:UserType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>c:name</q:path>
+                            <q:value>TestUser240</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>assign</s:type>
+                        <s:parameter>
+                            <s:name>role</s:name>
+							<c:value xsi:type="xsd:string">d48ec05b-fffd-4262-acd3-d9ff63365b62</c:value>
+                        </s:parameter>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex2/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml b/demo/complex2/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml
new file mode 100644
index 0000000..1356484
--- /dev/null
+++ b/demo/complex2/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml
@@ -0,0 +1,16 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3"
+		     xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+		     xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
+                    <s:type>c:RoleType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>name</q:path>
+                            <q:value>role-grouper-sysadmin</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>recompute</s:type>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex2/tests/resources/grouper/t300.gsh b/demo/complex2/tests/resources/grouper/t300.gsh
new file mode 100644
index 0000000..d2b63e3
--- /dev/null
+++ b/demo/complex2/tests/resources/grouper/t300.gsh
@@ -0,0 +1,15 @@
+System.out.println("************** t300.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+exportedGroups = GroupFinder.findByName(gs, 'etc:exportedGroups')
+alumSubject = SubjectFinder.findByIdentifier('ref:affiliation:alum', 'group', 'g:gsa')
+exportedGroups.addMember(alumSubject, false)
+
+alumIncludes = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+testGroup = GroupFinder.findByName(gs, 'etc:testGroup')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+alumIncludes.addMember(wprice, false)
+testGroup.addMember(wprice, false)
+
+System.out.println("************** t300.gsh done **************");
diff --git a/demo/complex2/tests/resources/grouper/t330.gsh b/demo/complex2/tests/resources/grouper/t330.gsh
new file mode 100644
index 0000000..cb8f158
--- /dev/null
+++ b/demo/complex2/tests/resources/grouper/t330.gsh
@@ -0,0 +1,11 @@
+System.out.println("************** t330.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+alumIncludesGroup = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.addMember(wprice, false)
+alumIncludesGroup.addMember(wprice, false)
+
+System.out.println("************** t330.gsh done **************");
diff --git a/demo/complex2/tests/resources/grouper/t350.gsh b/demo/complex2/tests/resources/grouper/t350.gsh
new file mode 100644
index 0000000..d0d2d3e
--- /dev/null
+++ b/demo/complex2/tests/resources/grouper/t350.gsh
@@ -0,0 +1,12 @@
+System.out.println("************** t350.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+alumIncludes = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+kwhite = SubjectFinder.findById('kwhite', 'person', 'ldap')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.addMember(kwhite, false)
+alumIncludes.deleteMember(wprice, false)
+
+System.out.println("************** t350.gsh done **************");
diff --git a/demo/complex2/tests/resources/grouper/t410.gsh b/demo/complex2/tests/resources/grouper/t410.gsh
new file mode 100644
index 0000000..69e4b18
--- /dev/null
+++ b/demo/complex2/tests/resources/grouper/t410.gsh
@@ -0,0 +1,11 @@
+System.out.println("************** t410.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+kwhite = SubjectFinder.findById('kwhite', 'person', 'ldap')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.deleteMember(kwhite, false)
+testGroup.deleteMember(wprice, false)
+
+System.out.println("************** t410.gsh done **************");
diff --git a/demo/complex2/tests/resources/rabbitmq/check-samplequeue.sh b/demo/complex2/tests/resources/rabbitmq/check-samplequeue.sh
new file mode 100755
index 0000000..e336a63
--- /dev/null
+++ b/demo/complex2/tests/resources/rabbitmq/check-samplequeue.sh
@@ -0,0 +1,8 @@
+count=$(rabbitmqctl list_queues | grep sampleQueue | awk '{print $2}')
+if [[ -z $count || $count -eq 0 ]]; then
+    echo "ERROR: sampleQueue does not exist or is empty"
+    exit 1
+else
+    echo "OK: sampleQueue has $count message(s)"
+    exit 0
+fi
diff --git a/demo/complex2/tests/resources/tasks/task-livesync-grouper-single.xml b/demo/complex2/tests/resources/tasks/task-livesync-grouper-single.xml
new file mode 100644
index 0000000..365d007
--- /dev/null
+++ b/demo/complex2/tests/resources/tasks/task-livesync-grouper-single.xml
@@ -0,0 +1,29 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+      oid="87ffce52-717a-4205-ba01-0a698f0deaee">
+   <name>LiveSync from Grouper</name>
+   <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+              xmlns:gen437="http://midpoint.evolveum.com/xml/ns/public/provisioning/liveSync-3"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:type="c:ExtensionType">
+      <mext:kind>account</mext:kind>
+      <mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+   </extension>
+   <taskIdentifier>1535465478027-0-1</taskIdentifier>
+   <ownerRef oid="00000000-0000-0000-0000-000000000002"
+             relation="org:default"
+             type="c:UserType"><!-- administrator --></ownerRef>
+   <executionStatus>runnable</executionStatus>
+   <category>LiveSynchronization</category>
+   <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/live-sync/handler-3</handlerUri>
+   <objectRef oid="6dcb84f5-bf82-4931-9072-fbdf87f96442"
+              relation="org:default"
+              type="c:ResourceType"><!-- Grouper SQL NEW --></objectRef>
+   <recurrence>single</recurrence>
+   <binding>loose</binding>
+</task>
diff --git a/demo/complex2/tests/resources/users/user-grouper-admin.xml b/demo/complex2/tests/resources/users/user-grouper-admin.xml
new file mode 100644
index 0000000..d785e47
--- /dev/null
+++ b/demo/complex2/tests/resources/users/user-grouper-admin.xml
@@ -0,0 +1,20 @@
+<user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      oid="a0c7c01e-c203-4777-9b21-27a4735da3ae">
+    <name>grouper-admin</name>
+    <assignment id="1">
+        <targetRef oid="d48ec05b-fffd-4262-acd3-d9ff63365b62" relation="org:default" type="c:RoleType">
+            <!-- role-grouper-sysadmin -->
+        </targetRef>
+    </assignment>
+    <fullName>Grouper admin</fullName>
+    <givenName>Grouper</givenName>
+    <familyName>Admin</familyName>
+    <credentials>
+        <password>
+            <value>password</value>
+        </password>
+    </credentials>
+</user>
+	
diff --git a/demo/complex2/update-bgasper-in-grouper.gsh b/demo/complex2/update-bgasper-in-grouper.gsh
new file mode 100644
index 0000000..b0ed0b2
--- /dev/null
+++ b/demo/complex2/update-bgasper-in-grouper.gsh
@@ -0,0 +1,13 @@
+
+def add(gs,groupName,subject) {
+	GroupFinder.findByName(gs, groupName, true).addMember(subject, false)
+}
+
+gs = GrouperSession.startRootSession()
+
+def bgasper = SubjectFinder.findById('bgasper', 'user', 'ldap')
+add(gs, 'ref:affiliation:alum_excludes', bgasper)
+add(gs, 'ref:affiliation:faculty_includes', bgasper)
+add(gs, 'app:mailinglist:chess', bgasper)
+add(gs, 'app:mailinglist:idm-fans', bgasper)
+add(gs, 'test:volunteers', bgasper)
diff --git a/demo/complex2/update-bgasper-in-grouper.sh b/demo/complex2/update-bgasper-in-grouper.sh
new file mode 100755
index 0000000..b849cbb
--- /dev/null
+++ b/demo/complex2/update-bgasper-in-grouper.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+execute_gsh complex2_grouper_daemon_1 update-bgasper-in-grouper.gsh
diff --git a/demo/complex2/upload-async-update-task.sh b/demo/complex2/upload-async-update-task.sh
new file mode 100755
index 0000000..bdf8ba2
--- /dev/null
+++ b/demo/complex2/upload-async-update-task.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-async-update-grouper.xml
diff --git a/demo/complex2/upload-import-sis-persons.sh b/demo/complex2/upload-import-sis-persons.sh
new file mode 100755
index 0000000..058c9af
--- /dev/null
+++ b/demo/complex2/upload-import-sis-persons.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-import-sis-persons.xml
diff --git a/demo/complex2/upload-objects.sh b/demo/complex2/upload-objects.sh
new file mode 100755
index 0000000..3f1c9b8
--- /dev/null
+++ b/demo/complex2/upload-objects.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+function upload () {
+  local filename=$1
+  local regex="midpoint-objects/(.*)/(.*)"
+  if [[ $filename =~ $regex ]]
+  then
+    type="${BASH_REMATCH[1]}"
+    oid=`cat $filename | sed -n 's:.*oid=\"\([A-Za-z0-9\-]*\)\".*:\1:p' | sed -n '1 p'`
+    echo "Uploading $filename ($type, $oid)"
+    curl -k --user administrator:5ecr3t -H "Content-Type: application/xml" -X PUT "https://localhost:8443/midpoint/ws/rest/$type/$oid?options=overwrite&options=raw" --data-binary @$filename
+  else
+    echo "Skipping $filename"
+  fi
+}
+
+find midpoint-objects -name "*.xml" | while read filename; do upload $filename; done
diff --git a/demo/complex2/upload-reconcile-grouper-groups.sh b/demo/complex2/upload-reconcile-grouper-groups.sh
new file mode 100755
index 0000000..94deb18
--- /dev/null
+++ b/demo/complex2/upload-reconcile-grouper-groups.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
diff --git a/demo/complex2/upload-reconcile-grouper-users.sh b/demo/complex2/upload-reconcile-grouper-users.sh
new file mode 100755
index 0000000..f6089ac
--- /dev/null
+++ b/demo/complex2/upload-reconcile-grouper-users.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
diff --git a/demo/complex2s/.env b/demo/complex2s/.env
new file mode 100644
index 0000000..75949b1
--- /dev/null
+++ b/demo/complex2s/.env
@@ -0,0 +1,14 @@
+AUTHENTICATION=internal
+ENV=demo
+REPO_DATABASE_TYPE=mariadb
+REPO_JDBC_URL=default
+REPO_HOST=midpoint_data
+REPO_PORT=default
+REPO_DATABASE=registry
+REPO_USER=registry_user
+REPO_MISSING_SCHEMA_ACTION=create
+REPO_UPGRADEABLE_SCHEMA_ACTION=stop
+MP_MEM_MAX=2048m
+MP_MEM_INIT=1024m
+SSO_HEADER=uid
+TIMEZONE=UTC
diff --git a/demo/complex2s/README.md b/demo/complex2s/README.md
new file mode 100644
index 0000000..9b7f0f6
--- /dev/null
+++ b/demo/complex2s/README.md
@@ -0,0 +1,9 @@
+This is a demonstration of using midPoint dockerization for TIER environment in a broader context. It is a work in progress.
+
+# Building and execution
+```
+$ ../../build.sh
+$ docker-compose up --build
+```
+
+Please see a detailed description [here](https://spaces.at.internet2.edu/display/MID/Complex+midPoint+integration+demo).
diff --git a/demo/complex2s/add-ref-groups.gsh b/demo/complex2s/add-ref-groups.gsh
new file mode 100644
index 0000000..7697f99
--- /dev/null
+++ b/demo/complex2s/add-ref-groups.gsh
@@ -0,0 +1,26 @@
+
+def addGroups(gs,stem,owner,regexp) {
+	for (group in stem.childGroups) {
+		if (!group.name.endsWith('_includes') &&
+		    !group.name.endsWith('_excludes') &&
+		    !group.name.endsWith('_systemOfRecord') &&
+		    !group.name.endsWith('_systemOfRecordAndIncludes') &&
+		    (regexp == null || group.extension ==~ regexp)) {
+			println 'Adding: ' + group
+			def s = SubjectFinder.findById(group.getId(), 'group', 'g:gsa')
+			owner.addMember(s, false)
+		} else {
+			println 'Ignoring: ' + group
+		}
+	}
+}
+
+gs = GrouperSession.startRootSession()
+def supergroup = GroupFinder.findByName(gs, "etc:midpointGroups", true)
+def cs = GroupFinder.findByName(gs, "app:cs", true)
+
+addGroups(gs, StemFinder.findByName(gs, 'ref:affiliation'), supergroup, null)
+addGroups(gs, StemFinder.findByName(gs, 'ref:dept'), supergroup, null)
+addGroups(gs, StemFinder.findByName(gs, 'ref:course'), supergroup, null)
+
+addGroups(gs, StemFinder.findByName(gs, 'ref:course'), cs, /CS.*/)
diff --git a/demo/complex2s/add-ref-groups.sh b/demo/complex2s/add-ref-groups.sh
new file mode 100755
index 0000000..a60c2f1
--- /dev/null
+++ b/demo/complex2s/add-ref-groups.sh
@@ -0,0 +1,3 @@
+source ../../library.bash
+
+execute_gsh complex2s_grouper_daemon_1 add-ref-groups.gsh
diff --git a/demo/complex2s/after-installation.sh b/demo/complex2s/after-installation.sh
new file mode 100755
index 0000000..68582e3
--- /dev/null
+++ b/demo/complex2s/after-installation.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+B='\033[1;33m'
+N='\033[0m'
+
+echo -e "${B} * Uploading objects...${N}"
+$(dirname "$0")/upload-objects.sh
+
+echo -e "${B} * Testing LDAP and SQL resources...${N}"
+$(dirname "$0")/test-resources-1.sh
+
+echo -e "${B} * Recomputing Grouper admin group and user object...${N}"
+$(dirname "$0")/recompute.sh
+
+echo -e "${B} * Waiting 120 seconds for changes to propagate to Grouper...${N}"
+sleep 120
+
+echo -e "${B} * Testing Grouper resource...${N}"
+$(dirname "$0")/test-resource-grouper.sh
+
+echo -e "${B} * Done${N}"
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/database_password.txt b/demo/complex2s/configs-and-secrets/grouper/application/database_password.txt
new file mode 100644
index 0000000..e69de29
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/grouper-loader.properties b/demo/complex2s/configs-and-secrets/grouper/application/grouper-loader.properties
new file mode 100644
index 0000000..62ef5f0
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/application/grouper-loader.properties
@@ -0,0 +1,71 @@
+#################################
+## LDAP connections
+#################################
+# specify the ldap connection with user, pass, url
+# the string after "ldap." is the ID of the connection, and it should not have
+# spaces or other special chars in it.  In this case is it "personLdap"
+
+#note the URL should start with ldap: or ldaps: if it is SSL.  
+#It should contain the server and port (optional if not default), and baseDn,
+#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu
+ldap.demo.url = ldap://directory:389/dc=internet2,dc=edu
+ 
+#optional, if authenticated
+ldap.demo.user = cn=admin,dc=internet2,dc=edu
+#ldap.demo.user = cn=admin
+ 
+#optional, if authenticated note the password can be stored encrypted in an external file
+#ldap.demo.pass = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+ldap.demo.pass = password
+ 
+#optional, if you are using tls, set this to true.  Generally you will not be using an SSL URL to use TLS...
+ldap.demo.tls = false
+ 
+#optional, if using sasl
+#ldap.personLdap.saslAuthorizationId =
+#ldap.personLdap.saslRealm =
+ 
+#optional (note, time limit is for search operations, timeout is for connection timeouts),
+#most of these default to vt-ldap defaults.  times are in millis
+#validateOnCheckout defaults to true if all other validate methods are false
+#ldap.personLdap.batchSize =
+#ldap.personLdap.countLimit =
+#ldap.personLdap.timeLimit =
+#ldap.personLdap.timeout =
+#ldap.personLdap.minPoolSize =
+#ldap.personLdap.maxPoolSize =
+#ldap.personLdap.validateOnCheckIn =
+#ldap.personLdap.validateOnCheckOut =
+#ldap.personLdap.validatePeriodically =
+#ldap.personLdap.validateTimerPeriod =
+#ldap.personLdap.pruneTimerPeriod =
+#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes)
+#ldap.personLdap.expirationTime =
+
+#make the paths fully qualified and not relative to the loader group.
+loader.ldap.requireTopStemAsStemFromConfigGroup=false
+
+
+db.sis.user = sis_user
+db.sis.pass = 49321420423
+db.sis.url = jdbc:mysql://sources:3306/sis
+db.sis.driver = com.mysql.jdbc.Driver
+
+
+#####################################
+## Messaging integration with change log
+#####################################
+changeLog.consumer.rabbitMqMessagingSample.quartzCron = 0 * * * * ?                                                          
+
+# note, change "messagingSample" in key to be the name of the consumer.  e.g. changeLog.consumer.someNameAnyName.class
+changeLog.consumer.rabbitMqMessagingSample.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer
+
+changeLog.consumer.rabbitMqMessagingSample.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher
+changeLog.consumer.rabbitMqMessagingSample.publisher.messagingSystemName = rabbitmq
+# note, routingKey property is valid only for rabbitmq. For other messaging systems, it is ignored.
+changeLog.consumer.rabbitMqMessagingSample.publisher.routingKey = 
+## queue or topic
+changeLog.consumer.rabbitMqMessagingSample.publisher.messageQueueType = queue
+changeLog.consumer.rabbitMqMessagingSample.publisher.queueOrTopicName = sampleQueue
+## this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml
+#changeLog.consumer.rabbitMqMessagingSample.publisher.addSubjectAttributes = email
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/grouper.client.properties b/demo/complex2s/configs-and-secrets/grouper/application/grouper.client.properties
new file mode 100644
index 0000000..d25ad96
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/application/grouper.client.properties
@@ -0,0 +1,112 @@
+#
+# Copyright 2014 Internet2
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Grouper client configuration
+# $Id: grouper.client.example.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $
+#
+
+# The grouper client uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.client.base.properties
+# (which should not be edited), and the grouper.client.properties overlays
+# the base settings.  See the grouper.client.base.properties for the possible
+# settings that can be applied to the grouper.client.properties
+
+########################################
+## LDAP connection settings
+########################################
+
+# url of directory, including the base DN (distinguished name)
+# e.g. ldap://server.school.edu/dc=school,dc=edu
+# e.g. ldaps://server.school.edu/dc=school,dc=edu
+grouperClient.ldap.url =
+
+# kerberos principal used to connect to ldap
+grouperClient.ldap.login =
+
+# password for shared secret authentication to ldap
+# or you can put a filename with an encrypted password
+grouperClient.ldap.password =
+
+########################################
+## Web service Connection settings
+########################################
+
+# url of web service, should include everything up to the first resource to access
+# e.g. http://groups.school.edu:8090/grouper-ws/servicesRest
+# e.g. https://groups.school.edu/grouper-ws/servicesRest
+grouperClient.webService.url = https://grouper_ws/grouper-ws/servicesRest
+
+# kerberos principal used to connect to web service
+grouperClient.webService.login = banderson
+
+# password for shared secret authentication to web service
+# or you can put a filename with an encrypted password
+grouperClient.webService.password.elConfig = ${java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('GROUPER_CLIENT_WEBSERVICE_PASSWORD') }
+
+
+################################
+## Grouper Messaging System
+################################
+ 
+# name of messaging system which is the default
+grouper.messaging.default.name.of.messaging.system = rabbitmq
+ 
+# name of a messaging system.  note, "grouperBuiltinMessaging" can be arbitrary
+# grouper.messaging.system.grouperBuiltinMessaging.name = grouperBuiltinMessaging
+ 
+# class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem
+# grouper.messaging.system.grouperBuiltinMessaging.class = edu.internet2.middleware.grouper.messaging.GrouperBuiltinMessagingSystem
+ 
+# name of a messaging system.  note, "grouperBuiltinMessaging" can be arbitrary
+grouper.messaging.system.rabbitmqSystem.name = rabbitmqSystem
+ 
+# class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem
+grouper.messaging.system.rabbitmqSystem.class = edu.internet2.middleware.grouperMessagingRabbitmq.GrouperMessagingRabbitmqSystem
+ 
+# host address of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.host = mq
+ 
+# virtual host of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.virtualhost =
+ 
+# port of rabbitmq queue
+grouper.messaging.system.rabbitmqSystem.port =
+ 
+grouper.messaging.system.rabbitmqSystem.defaultPageSize = 10
+ 
+grouper.messaging.system.rabbitmqSystem.maxPageSize = 50
+ 
+ 
+# name of a messaging system, required
+grouper.messaging.system.rabbitmq.name = rabbitmq
+ 
+# default system settings to this messaging system, note, there is only one level of inheritance
+grouper.messaging.system.rabbitmq.defaultSystemName = rabbitmqSystem
+
+grouper.messaging.system.rabbitmq.user = guest
+
+#pass
+grouper.messaging.system.rabbitmq.password.elConfig = ${java.lang.System.getenv().get('RABBITMQ_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('RABBITMQ_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('RABBITMQ_PASSWORD') }
+# set the following three properties if you want to use TLS connection to rabbitmq. All three need to be populated.
+# TLS Version
+#grouper.messaging.system.rabbitmqSystem.tlsVersion = TLSv1.1
+ 
+# path to trust store file
+#grouper.messaging.system.rabbitmqSystem.pathToTrustStore =
+ 
+# trust passphrase
+#grouper.messaging.system.rabbitmqSystem.trustPassphrase =
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/grouper.hibernate.properties b/demo/complex2s/configs-and-secrets/grouper/application/grouper.hibernate.properties
new file mode 100644
index 0000000..deb0d75
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/application/grouper.hibernate.properties
@@ -0,0 +1,29 @@
+#
+# Grouper Hibernate Configuration
+# $Id: grouper.hibernate.example.properties,v 1.9 2009-08-11 20:18:09 mchyzer Exp $
+#
+
+# The grouper hibernate config uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.hibernate.base.properties
+# (which should not be edited), and the grouper.hibernate.properties overlays
+# the base settings.  See the grouper.hibernate.base.properties for the possible
+# settings that can be applied to the grouper.hibernate.properties
+
+########################################
+## DB settings
+########################################
+
+# e.g. mysql:           jdbc:mysql://localhost:3306/grouper
+# e.g. p6spy (log sql): [use the URL that your DB requires]
+# e.g. oracle:          jdbc:oracle:thin:@server.school.edu:1521:sid
+# e.g. hsqldb (a):      jdbc:hsqldb:dist/run/grouper;create=true
+# e.g. hsqldb (b):      jdbc:hsqldb:hsql://localhost:9001/grouper
+# e.g. postgres:        jdbc:postgresql://localhost:5432/database
+# e.g. mssql:           jdbc:sqlserver://localhost:3280;databaseName=grouper
+hibernate.connection.url = jdbc:mysql://grouper_data:3306/grouper?CharSet=utf8&useUnicode=true&characterEncoding=utf8
+
+hibernate.connection.username         = root
+# If you are using an empty password, depending upon your version of
+# Java and Ant you may need to specify a password of "".
+# Note: you can keep passwords external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122
+hibernate.connection.password.elConfig = ${java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('GROUPER_DATABASE_PASSWORD') }
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/grouper.properties b/demo/complex2s/configs-and-secrets/grouper/application/grouper.properties
new file mode 100644
index 0000000..c931287
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/application/grouper.properties
@@ -0,0 +1,25 @@
+#
+# Grouper Configuration
+# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $
+#
+
+# Grouper uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.base.properties
+# (which should not be edited), and the grouper.properties overlays
+# the base settings.  See the grouper.base.properties for the possible
+# settings that can be applied to the grouper.properties
+
+#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on)
+configuration.autocreate.system.groups = true
+
+# A wheel group allows you to enable non-GrouperSystem subjects to act
+# like a root user when interacting with the registry.
+groups.wheel.use                      = true
+
+# Set to the name of the group you want to treat as the wheel group.
+# The members of this group will be treated as root-like users.
+groups.wheel.group                    = etc:sysadmingroup
+
+# Used to allow Include Exclude groups
+grouperIncludeExclude.use = true
+grouperIncludeExclude.requireGroups.use = true
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/rabbitmq_password.txt b/demo/complex2s/configs-and-secrets/grouper/application/rabbitmq_password.txt
new file mode 100644
index 0000000..158f675
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/application/rabbitmq_password.txt
@@ -0,0 +1 @@
+guest
\ No newline at end of file
diff --git a/demo/complex2s/configs-and-secrets/grouper/application/subject.properties b/demo/complex2s/configs-and-secrets/grouper/application/subject.properties
new file mode 100644
index 0000000..577db03
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/application/subject.properties
@@ -0,0 +1,78 @@
+#subject.sources.xml.location =
+
+subjectApi.source.ldap.param.ldapServerId.value = demo
+
+subjectApi.source.ldap.id = ldap
+subjectApi.source.ldap.name = EDU Ldap 
+subjectApi.source.ldap.types = person
+subjectApi.source.ldap.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter
+#subjectApi.source.ldap.param.INITIAL_CONTEXT_FACTORY.value = com.sun.jndi.ldap.LdapCtxFactory
+#subjectApi.source.ldap.param.PROVIDER_URL.value = ldap://directory:389
+#subjectApi.source.ldap.param.SECURITY_AUTHENTICATION.value = simple
+#subjectApi.source.ldap.param.SECURITY_PRINCIPAL.value = cn=admin,dc=internet2,dc=edu
+#subjectApi.source.ldap.param.SECURITY_CREDENTIALS.value.elConfig = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+#subjectApi.source.ldap.param.VTLDAP_VALIDATOR.value = ConnectLdapValidator
+
+subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid
+subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false
+subjectApi.source.ldap.param.Name_AttributeType.value = cn
+subjectApi.source.ldap.param.Description_AttributeType.value = cn
+subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")}
+subjectApi.source.ldap.param.sortAttribute0.value = cn
+subjectApi.source.ldap.param.searchAttribute0.value = searchAttribute0
+
+# STATUS SECTION for searches to filter out inactives and allow
+# the user to filter by status with e.g. status=all
+# this is optional, and advanced
+#
+# field in database or ldap or endpoint that is the status field
+#subjectApi.source.example.param.statusDatastoreFieldName.value = status
+
+# search string from user which represents the status.  e.g. status=active
+#subjectApi.source.example.param.statusLabel.value = status
+
+# available statuses from screen (if not specified, any will be allowed). comma separated list.
+# Note, this is optional and you probably dont want to configure it, it is mostly necessary
+# when you have multiple sources with statuses...  if someone types an invalid status
+# and you have this configured, it will not filter by it
+#subjectApi.source.example.param.statusesFromUser.value = Active, Inactive, Pending, All
+
+# all label from the user
+#subjectApi.source.example.param.statusAllFromUser.value = All
+
+# if no status is specified, this will be used (e.g. for active only).  Note, the value should be of the
+# form the user would type in
+#subjectApi.source.example.param.statusSearchDefault.value = status=active
+
+# translate between screen values of status, and the data store value.  Increment the 0 to 1, 2, etc for more translations.
+# so the user could enter: status=active, and that could translate to status_col=A.  The 'user' is what the user types in,
+# the 'datastore' is what is in the datastore.  The user part is not case-sensitive.  Note, this could be a many to one
+#subjectApi.source.example.param.statusTranslateUser0.value = active
+#subjectApi.source.example.param.statusTranslateDatastore0.value = A
+
+# subject identifier to store in grouper's member table.  this is used to increase speed of loader and perhaps for provisioning
+# you can have up to max 1 subject identifier
+#subjectApi.source.example.param.subjectIdentifierAttribute0.value = uid
+
+#searchSubject: find a subject by ID.  ID is generally an opaque and permanent identifier, e.g. 12345678.
+#  Each subject has one and only on ID.  Returns one result when searching for one ID.
+subjectApi.source.ldap.search.searchSubject.param.filter.value = (&(uid=%TERM%)(objectclass=person))
+subjectApi.source.ldap.search.searchSubject.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubject.param.base.value = ou=people
+
+#searchSubjectByIdentifier: find a subject by identifier.  Identifier is anything that uniquely
+#  identifies the user, e.g. jsmith or jsmith@institution.edu.
+#  Subjects can have multiple identifiers.  Note: it is nice to have if identifiers are unique
+#  even across sources.  Returns one result when searching for one identifier.
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.filter.value = (&(|(uid=%TERM%)(employeeNumber=%TERM%))(objectclass=person))
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.base.value = ou=people
+
+#   search: find subjects by free form search.  Returns multiple results.
+
+subjectApi.source.ldap.search.search.param.filter.value = (&(|(|(uid=%TERM%)(cn=*%TERM%*))(uid=%TERM%*))(objectclass=person))
+subjectApi.source.ldap.search.search.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.search.param.base.value = ou=people
+
+subjectApi.source.ldap.attributes = givenName, sn, uid, mail, employeeNumber
+subjectApi.source.ldap.internalAttributes = searchAttribute0
diff --git a/demo/complex2s/configs-and-secrets/grouper/httpd/cachain-cer.pem b/demo/complex2s/configs-and-secrets/grouper/httpd/cachain-cer.pem
new file mode 100644
index 0000000..e69de29
diff --git a/demo/complex2s/configs-and-secrets/grouper/httpd/host-cert.pem b/demo/complex2s/configs-and-secrets/grouper/httpd/host-cert.pem
new file mode 100644
index 0000000..9cc228a
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/httpd/host-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/configs-and-secrets/grouper/httpd/host-key.pem b/demo/complex2s/configs-and-secrets/grouper/httpd/host-key.pem
new file mode 100644
index 0000000..1b0b579
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEzSZrDaU6UeDa
+wycDoCv6N1GJTXYtXOsQX5bfpYiwLEHNetEEXleHUkhivC2bzefGvwUyLB/HS4UJ
+VEPKkFGNgH6JVazcW+1mrpnofzzs2FE0cpZ6BqVN1mxjBD8RPwHYD+VP2nWL8ruF
+yOXqb+8I2STk6nFWoNeUmpWPmrKPmQv+ZflM0cZlgWcSk7Ei9cuzxXoWOP2Zd2N6
+BlbFZf87KbeZbXqGUHnlcVF9vUtwH9dch2OMaRKfu67wM2P55bE4hwLFKAhSvzRU
+Nnr70kcedgfRZNXFj9TA1Q5tkI0Kg/cQRmEp1+m4UHo1ceyVCR5W5btkOaeV3VtA
+YoYBZbqBAgMBAAECggEAA/5t0ypZug9DUu0283niqpdIzlKGHXGPS6vE8hD37ytW
+wobFiyMm/5YJ5gcPnePV2lCyGEyQ8Ih10LSnE4tOPGLpLnxQn8A11ymf8fnzEJNr
+Qnc42o0b+bJqTLAfX4g5z1qzOqWiUQ7CA3sKP3G6FiHh/8tKNYnaFif09Q8cpJFb
+YDDkvm48NJgsrIoCgmaFIQIn+yDzGQKWwTNMIks+RByWpc67j1x1kiyQM1RfrEev
+Yyq/ZkP66IYZzmZKpFCWGs5qbRZdxyXNpq85DjwA99lAH7vxtMJHQM4z1h1eDH4L
+Ma5hEnmmHu4D5lF2GDQYflvuFdDGH5tThO6MV0IrSQKBgQD+kvEtNxJCMxLOVFyV
+NWF3pk/i2nkD+53t/VPXjMPtW7IesouEGzU82I/fT2wUTkNwFdkVpv37qoLypKZm
+npJFxr6abQNjiDh2Fsh8/iuJfvdZUFJbCEY6NS58qgjix8XCQKRD06EugK7uekIZ
+zJnttF3qVBBD8Z8Uwxz8i+jF1wKBgQDF51y/5XB6Bz47cdxw7P8NsfnTz2V3H0HU
+OnlEBANbhmBadjU8dqbM54Nxbn7VOdooXPuSnAKJ9vPDg1n5Y/GO+lgldNzfyK6g
+HnbldSu0zBvAaGvmAjLjetEtOkBqYkrHJlT6JAems/Kc/YX5uooAz9/jNJFXP9++
+KbjH3CzHZwKBgQC6ppxEDZPKi83nD/2NvMTIyFzcNFj0LaEepFW7vc7NkiSn0zrt
+0lEXWqUqEv5oaPWTEcHH2VdxFRTLuSL0LKGMnWqUqQcKDA9xrcSzuFvNhRTwHC81
+5XwwI1wBNV4sgFKj2WdW/6y2/szDt0oNxnC50zvkmlwOpPKBc4kmNaKmowKBgBmC
+uXIDIXyZcmw3QTNNWZNqXcnv8iRo4xN4dilOWyBxMfp3QmWI5feD4G2+0Jqr2nNZ
+iRRdB/bA3qtVQ0PinkDQBIzPg6lVNS1uv+TUNc4YgXtL+pyrq+Om8U/jMmqEQR9q
+0YltG49houSZyatnYGK6aSHgpNuaYD0jI66fsyYBAoGAMefyD0I/ncArjuf58hVQ
+zSjxfcvlja9okrC8ZgqsVluezcm4rQNcSjBnESGTCjJC7O29AofGLHkvnsBQDiGk
+hE38IRisd+okXdApr41ifWDhmtASud5q6wlhOpMmQxg+OALf1rTvFYhbnFEXV/KY
+e5A4iXLRIbxbmXZDa35Rebw=
+-----END PRIVATE KEY-----
diff --git a/demo/complex2s/configs-and-secrets/grouper/shibboleth/idp-metadata.xml b/demo/complex2s/configs-and-secrets/grouper/shibboleth/idp-metadata.xml
new file mode 100644
index 0000000..4fa67a7
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/shibboleth/idp-metadata.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex2s/configs-and-secrets/grouper/shibboleth/shibboleth2.xml b/demo/complex2s/configs-and-secrets/grouper/shibboleth/shibboleth2.xml
new file mode 100644
index 0000000..0c38f82
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/shibboleth/shibboleth2.xml
@@ -0,0 +1,136 @@
+<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"    
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    clockSkew="180">
+
+    <!--
+    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
+    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
+    -->
+
+    <!--
+    To customize behavior for specific resources on Apache, and to link vhosts or
+    resources to ApplicationOverride settings below, use web server options/commands.
+    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
+    
+    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
+    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
+    -->
+    <TCPListener address="127.0.0.1" port="1600"/> 
+
+
+    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
+    <ApplicationDefaults entityID="https://grouperdemo/shibboleth"
+                         REMOTE_USER="uid">
+
+        <!--
+        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
+        You MUST supply an effectively unique handlerURL value for each of your applications.
+        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
+        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
+        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
+        Note that while we default checkAddress to "false", this has a negative impact on the
+        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
+        -->
+        <Sessions lifetime="28800" timeout="28800" relayState="ss:mem"
+                  checkAddress="false" handlerSSL="true" cookieProps="https">
+
+            <!--
+            Configures SSO for a default IdP. To allow for >1 IdP, remove
+            entityID property and adjust discoveryURL to point to discovery service.
+            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
+            You can also override entityID on /Login query string, or in RequestMap/htaccess.
+            -->
+		<SSO entityID="https://idptestbed/idp/shibboleth">
+			SAML2
+		</SSO>
+
+            <!-- SAML and local-only logout. -->
+            <Logout>SAML2 Local</Logout>
+            
+            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
+            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
+
+            <!-- Status reporting service. -->
+            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
+
+            <!-- Session diagnostic service. -->
+            <Handler type="Session" Location="/Session" showAttributeValues="true"/>
+
+            <!-- JSON feed of discovery information. -->
+            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
+        </Sessions>
+
+        <!--
+        Allows overriding of error template information/filenames. You can
+        also add attributes with values that can be plugged into the templates.
+        -->
+        <Errors supportContact="root@localhost"
+            helpLocation="/about.html"
+            styleSheet="/shibboleth-sp/main.css"/>
+        
+        <!-- Example of remotely supplied batch of signed metadata. -->
+        <!--
+        <MetadataProvider type="XML" validate="true"
+	      uri="http://example.org/federation-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <MetadataProvider type="XML" validate="true" file="idp-metadata.xml"/>
+
+        <!--
+        InCommon
+	  <MetadataProvider type="XML" validate="true"
+		uri="http://md.incommon.org/InCommon/InCommon-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+		<MetdataFilter type="Signature" certificate="inc-md-cert.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <!-- Map to extract attributes from SAML assertions. -->
+        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
+        
+        <!-- Use a SAML query if no attributes are supplied during SSO. -->
+        <AttributeResolver type="Query" subjectMatch="true"/>
+
+        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
+        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
+
+        <!-- Simple file-based resolver for using a single keypair. -->
+        <CredentialResolver type="File" key="sp-key.pem" certificate="sp-cert.pem"/>
+
+        <!--
+        The default settings can be overridden by creating ApplicationOverride elements (see
+        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
+        Resource requests are mapped by web server commands, or the RequestMapper, to an
+        applicationId setting.
+        
+        Example of a second application (for a second vhost) that has a different entityID.
+        Resources on the vhost would map to an applicationId of "admin":
+        -->
+        <!--
+        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
+        -->
+    </ApplicationDefaults>
+    
+    <!-- Policies that determine how to process and authenticate runtime messages. -->
+    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
+
+    <!-- Low-level configuration about protocols and bindings available for use. -->
+    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
+
+</SPConfig>
diff --git a/demo/complex2s/configs-and-secrets/grouper/shibboleth/sp-cert.pem b/demo/complex2s/configs-and-secrets/grouper/shibboleth/sp-cert.pem
new file mode 100644
index 0000000..9cc228a
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/shibboleth/sp-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/configs-and-secrets/grouper/shibboleth/sp-key.pem b/demo/complex2s/configs-and-secrets/grouper/shibboleth/sp-key.pem
new file mode 100644
index 0000000..1b0b579
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/grouper/shibboleth/sp-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEzSZrDaU6UeDa
+wycDoCv6N1GJTXYtXOsQX5bfpYiwLEHNetEEXleHUkhivC2bzefGvwUyLB/HS4UJ
+VEPKkFGNgH6JVazcW+1mrpnofzzs2FE0cpZ6BqVN1mxjBD8RPwHYD+VP2nWL8ruF
+yOXqb+8I2STk6nFWoNeUmpWPmrKPmQv+ZflM0cZlgWcSk7Ei9cuzxXoWOP2Zd2N6
+BlbFZf87KbeZbXqGUHnlcVF9vUtwH9dch2OMaRKfu67wM2P55bE4hwLFKAhSvzRU
+Nnr70kcedgfRZNXFj9TA1Q5tkI0Kg/cQRmEp1+m4UHo1ceyVCR5W5btkOaeV3VtA
+YoYBZbqBAgMBAAECggEAA/5t0ypZug9DUu0283niqpdIzlKGHXGPS6vE8hD37ytW
+wobFiyMm/5YJ5gcPnePV2lCyGEyQ8Ih10LSnE4tOPGLpLnxQn8A11ymf8fnzEJNr
+Qnc42o0b+bJqTLAfX4g5z1qzOqWiUQ7CA3sKP3G6FiHh/8tKNYnaFif09Q8cpJFb
+YDDkvm48NJgsrIoCgmaFIQIn+yDzGQKWwTNMIks+RByWpc67j1x1kiyQM1RfrEev
+Yyq/ZkP66IYZzmZKpFCWGs5qbRZdxyXNpq85DjwA99lAH7vxtMJHQM4z1h1eDH4L
+Ma5hEnmmHu4D5lF2GDQYflvuFdDGH5tThO6MV0IrSQKBgQD+kvEtNxJCMxLOVFyV
+NWF3pk/i2nkD+53t/VPXjMPtW7IesouEGzU82I/fT2wUTkNwFdkVpv37qoLypKZm
+npJFxr6abQNjiDh2Fsh8/iuJfvdZUFJbCEY6NS58qgjix8XCQKRD06EugK7uekIZ
+zJnttF3qVBBD8Z8Uwxz8i+jF1wKBgQDF51y/5XB6Bz47cdxw7P8NsfnTz2V3H0HU
+OnlEBANbhmBadjU8dqbM54Nxbn7VOdooXPuSnAKJ9vPDg1n5Y/GO+lgldNzfyK6g
+HnbldSu0zBvAaGvmAjLjetEtOkBqYkrHJlT6JAems/Kc/YX5uooAz9/jNJFXP9++
+KbjH3CzHZwKBgQC6ppxEDZPKi83nD/2NvMTIyFzcNFj0LaEepFW7vc7NkiSn0zrt
+0lEXWqUqEv5oaPWTEcHH2VdxFRTLuSL0LKGMnWqUqQcKDA9xrcSzuFvNhRTwHC81
+5XwwI1wBNV4sgFKj2WdW/6y2/szDt0oNxnC50zvkmlwOpPKBc4kmNaKmowKBgBmC
+uXIDIXyZcmw3QTNNWZNqXcnv8iRo4xN4dilOWyBxMfp3QmWI5feD4G2+0Jqr2nNZ
+iRRdB/bA3qtVQ0PinkDQBIzPg6lVNS1uv+TUNc4YgXtL+pyrq+Om8U/jMmqEQR9q
+0YltG49houSZyatnYGK6aSHgpNuaYD0jI66fsyYBAoGAMefyD0I/ncArjuf58hVQ
+zSjxfcvlja9okrC8ZgqsVluezcm4rQNcSjBnESGTCjJC7O29AofGLHkvnsBQDiGk
+hE38IRisd+okXdApr41ifWDhmtASud5q6wlhOpMmQxg+OALf1rTvFYhbnFEXV/KY
+e5A4iXLRIbxbmXZDa35Rebw=
+-----END PRIVATE KEY-----
diff --git a/demo/complex2s/configs-and-secrets/midpoint/application/database_password.txt b/demo/complex2s/configs-and-secrets/midpoint/application/database_password.txt
new file mode 100644
index 0000000..11bff19
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/application/database_password.txt
@@ -0,0 +1 @@
+WJzesbe3poNZ91qIbmR7
diff --git a/demo/complex2s/configs-and-secrets/midpoint/application/keystore_password.txt b/demo/complex2s/configs-and-secrets/midpoint/application/keystore_password.txt
new file mode 100644
index 0000000..1d40192
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/application/keystore_password.txt
@@ -0,0 +1 @@
+changeit
diff --git a/demo/complex2s/configs-and-secrets/midpoint/httpd/host-cert.pem b/demo/complex2s/configs-and-secrets/midpoint/httpd/host-cert.pem
new file mode 100644
index 0000000..9b1021b
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/httpd/host-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAMOSkn4oS2aAMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXbWlkcG9pbnQuc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU1OTQ1WhcNMTkwOTE0MDU1OTQ1WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF21pZHBvaW50LnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApj/b7MEUSfu3oXMfNgRwTse7
+a5UV7Jswf1M/ZN/ZZkAkIxNBevZgozjesvLPWrmsTgONi7XigJUJvCjdjmlW9eDM
+lri/rkD8HuOR1DQCVKL9nvoS2c3D7sq5Emda3V8Tlj82VqfEmePd3sajx7mcTfbH
+8jwAL9NhkC+WMib5IpjLGpG0FEAC0ha7Lxb+7jIiqHVJaqLXJGCyGN4mh6c1Q9S1
+f8RVTiW2a8x22G+9wnZYbkiA2Kxls177imHlhSz8EdvV4IpGw1amrEWhhuDEum7B
+vZ1xQDLatgRqh4qAKLIVYeRnJ8H1FelMa90qB4G08MIPifmTsQwqJyBYaEdgWQID
+AQABo1MwUTAdBgNVHQ4EFgQUqb9BteODF6wv5R57aEON/wGXMiowHwYDVR0jBBgw
+FoAUqb9BteODF6wv5R57aEON/wGXMiowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAAcKhxI+tSItrXmqC0PSmgWyAYpqbkz6W/cefTutXqhIgY09f
+h0LSv7ogTahoGpyiZk9vy6u3OE9bYwxapEfa4KBjO6HxBMIVBBb3RegVjoPzjElN
+BDwAx0VGFcZTXwMxDWycWdG8ql7rCZBvS50w04uTaIgnGmqXAdWWmBgfJ9cRbxW+
+JwO/mOl1QM1lR/5142NpvuUVWlmZSKEGydE5A1qPz2wpDbBR1ym1BQNS4NEqw6Kp
+GSB8jKyCS1Ve0v2wVze2038Wukz02dq9uKPTIO3T+B+ibZmxn6Op/kFCc1/kK5NS
+Q6JdO1B6KquGAYdGmKAcQ19mv+jqGktqWEEf0g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/configs-and-secrets/midpoint/httpd/host-key.pem b/demo/complex2s/configs-and-secrets/midpoint/httpd/host-key.pem
new file mode 100644
index 0000000..5746e59
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmP9vswRRJ+7eh
+cx82BHBOx7trlRXsmzB/Uz9k39lmQCQjE0F69mCjON6y8s9auaxOA42LteKAlQm8
+KN2OaVb14MyWuL+uQPwe45HUNAJUov2e+hLZzcPuyrkSZ1rdXxOWPzZWp8SZ493e
+xqPHuZxN9sfyPAAv02GQL5YyJvkimMsakbQUQALSFrsvFv7uMiKodUlqotckYLIY
+3iaHpzVD1LV/xFVOJbZrzHbYb73CdlhuSIDYrGWzXvuKYeWFLPwR29XgikbDVqas
+RaGG4MS6bsG9nXFAMtq2BGqHioAoshVh5GcnwfUV6Uxr3SoHgbTwwg+J+ZOxDCon
+IFhoR2BZAgMBAAECggEAEIRBpjjceiku6jRUwnoYaks/nIWYQwR8AfpUTwJKR/VR
+Yca097Fokm7A+UhUP3A45RtHQb0VPq8P44iv0kk24YCu8r5yFK7SHYOAZnOwU5ZJ
+2jSAEPF3aM7tKh3okhuzB3dKP7u1NZDE5zAW723KUJiW7sL1RcsbY0bHBj6G+9/H
+NplmsjuGt684vRBB0qOBfKF7EiG7mT69tHuNj4gRza9SMY31UtKbZdt2fNY6mp5V
+HscMba7egZP+Ke0pVX4+go9j7K8GG8hYaQDLjrzlPqrxZ2c5X9cC+CRDI/CHuL/s
+V/2yGZJ6n6UabwZoH83RdFrbQ94rU8Hkli6EvxXvMQKBgQDRpheNW5jDG5TfeJKh
+yfKTDQqH2Tk3BsBYYBN7Hf3m7vbkzlxnAKJAoSLmtRMuoeXvI5MrhzaHGsNIUS76
+LDIZnvB7DLUxhFUZsCPkpAA1QHuTWY96oR3PHnPjpk8lSUvtbOPwDLdzVApeFJgZ
+VqMNArZ7AHsK3Kkyi+f4WVQjbQKBgQDLAWiGb5dx6fAM2W6B6HjNmzjBWOuVEXa2
+76to9jzupBZmETfZgxtWUaWUDuNS+f7dtVUTE+p6v/w8clrHEhEZYkqunIOLo/UA
+LFPiuoTfEsWb1rh+nsCjCgy4uimixj/bSkf7NC6NyKTvCygA1mGnVVJUEPegYlDy
+LXCkaKWxHQKBgQCmyHSKL2lrJkEcOwakEU2acNCE3Gno/cT9SYmV83kvQ8JEqmrW
+QqnRsp9aXIljGscapPmKsmnNt5vNp1AxFAHTYh88NRLczsMIyZj0ZwgHVUI6KhC7
+5Psa78YQQBlMt2/g9TSsnuE+rYgF6mpKFiNm0Vasqeg47uzn2mdzqlUGTQKBgE04
+JutkTUY+h1pL5vYxWKpVDfy19z7H2tFxT1FowPrBneeLSyRI88Ac5I/yLdRlVeY9
+0LOmEr5Igwj3MsKgg7KVKfVLgdo/LrW3Jt2Kt3onKNXDkoBPoNUjwH0QC0Boiue+
+VK0gR0kVdm+bXccbxR+im+NwZNE0NLg6Qqu3RredAoGBALuVoqbPPmTCZXYG328H
+bzOs2aiR7BzPSVByV+qG6jW7w03RAnFPJZp7HMU+ViI5VY0wabUscMSvz5163+gM
+4KwY3v9ZjZzZGukIfLuudkdqtaiVOx/KeAC0n+nG21YU+wpZww8gkfHh1/sa2CME
+CWYCgOnmiTHcj83UaTqEXtmv
+-----END PRIVATE KEY-----
diff --git a/demo/complex2s/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
new file mode 100644
index 0000000..4fa67a7
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex2s/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
new file mode 100644
index 0000000..ee05a97
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
@@ -0,0 +1,139 @@
+<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"    
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    clockSkew="180">
+
+    <!--
+    By default, in-memory StorageService, ReplayCache, ArtifactMap, and SessionCache
+    are used. See example-shibboleth2.xml for samples of explicitly configuring them.
+    -->
+
+    <!--
+    To customize behavior for specific resources on Apache, and to link vhosts or
+    resources to ApplicationOverride settings below, use web server options/commands.
+    See https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPConfigurationElements for help.
+    
+    For examples with the RequestMap XML syntax instead, see the example-shibboleth2.xml
+    file, and the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapHowTo topic.
+    -->
+    <TCPListener address="127.0.0.1" port="1600"/> 
+
+
+    <!-- The ApplicationDefaults element is where most of Shibboleth's SAML bits are defined. -->
+    <ApplicationDefaults entityID="https://midpointdemo/shibboleth"
+                         REMOTE_USER="uid">
+
+        <!--
+        Controls session lifetimes, address checks, cookie handling, and the protocol handlers.
+        You MUST supply an effectively unique handlerURL value for each of your applications.
+        The value defaults to /Shibboleth.sso, and should be a relative path, with the SP computing
+        a relative value based on the virtual host. Using handlerSSL="true", the default, will force
+        the protocol to be https. You should also set cookieProps to "https" for SSL-only sites.
+        Note that while we default checkAddress to "false", this has a negative impact on the
+        security of your site. Stealing sessions via cookie theft is much easier with this disabled.
+        -->
+        <Sessions lifetime="28800" timeout="28800" relayState="ss:mem"
+                  checkAddress="false" handlerSSL="true" cookieProps="https">
+
+            <!--
+            Configures SSO for a default IdP. To allow for >1 IdP, remove
+            entityID property and adjust discoveryURL to point to discovery service.
+            (Set discoveryProtocol to "WAYF" for legacy Shibboleth WAYF support.)
+            You can also override entityID on /Login query string, or in RequestMap/htaccess.
+            -->
+		<SSO entityID="https://idptestbed/idp/shibboleth">
+			SAML2
+		</SSO>
+
+            <!-- SAML and local-only logout. -->
+            <Logout>SAML2 Local</Logout>
+            
+            <!-- Extension service that generates "approximate" metadata based on SP configuration. -->
+            <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
+
+            <!-- Status reporting service. -->
+            <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/>
+
+            <!-- Session diagnostic service. -->
+            <Handler type="Session" Location="/Session" showAttributeValues="true"/>
+
+            <!-- JSON feed of discovery information. -->
+            <Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
+        </Sessions>
+
+        <!--
+        Allows overriding of error template information/filenames. You can
+        also add attributes with values that can be plugged into the templates.
+        -->
+        <Errors supportContact="root@localhost"
+            helpLocation="/about.html"
+            styleSheet="/shibboleth-sp/main.css"/>
+        
+        <!-- Example of remotely supplied batch of signed metadata. -->
+        <!--
+        <MetadataProvider type="XML" validate="true"
+	      uri="http://example.org/federation-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+            <MetadataFilter type="Signature" certificate="fedsigner.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <MetadataProvider type="XML" validate="true" file="idp-metadata.xml"/>
+
+        <!--
+        InCommon
+	  <MetadataProvider type="XML" validate="true"
+		uri="http://md.incommon.org/InCommon/InCommon-metadata.xml"
+              backingFilePath="federation-metadata.xml" reloadInterval="7200">
+            <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
+		<MetdataFilter type="Signature" certificate="inc-md-cert.pem"/>
+            <DiscoveryFilter type="Blacklist" matcher="EntityAttributes" trimTags="true" 
+              attributeName="http://macedir.org/entity-category"
+              attributeNameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
+              attributeValue="http://refeds.org/category/hide-from-discovery" />
+        </MetadataProvider>
+        -->
+
+        <!-- Map to extract attributes from SAML assertions. -->
+        <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
+        
+        <!-- Use a SAML query if no attributes are supplied during SSO. -->
+        <AttributeResolver type="Query" subjectMatch="true"/>
+
+        <!-- Default filtering policy for recognized attributes, lets other data pass. -->
+        <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
+
+        <!-- Simple file-based resolvers for separate signing/encryption keys. -->
+        <CredentialResolver type="File" use="signing"
+            key="sp-signing-key.pem" certificate="sp-signing-cert.pem"/>
+        <CredentialResolver type="File" use="encryption"
+            key="sp-encrypt-key.pem" certificate="sp-encrypt-cert.pem"/>
+
+        <!--
+        The default settings can be overridden by creating ApplicationOverride elements (see
+        the https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApplicationOverride topic).
+        Resource requests are mapped by web server commands, or the RequestMapper, to an
+        applicationId setting.
+        
+        Example of a second application (for a second vhost) that has a different entityID.
+        Resources on the vhost would map to an applicationId of "admin":
+        -->
+        <!--
+        <ApplicationOverride id="admin" entityID="https://admin.example.org/shibboleth"/>
+        -->
+    </ApplicationDefaults>
+    
+    <!-- Policies that determine how to process and authenticate runtime messages. -->
+    <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
+
+    <!-- Low-level configuration about protocols and bindings available for use. -->
+    <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
+
+</SPConfig>
diff --git a/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
new file mode 100644
index 0000000..7a66196
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAmWgAwIBAgIJAINng1bI63LGMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
+BAMTEnNwdGVzdC5leGFtcGxlLmVkdTAeFw0xODEyMjAyMjM4MDJaFw0yODEyMTcy
+MjM4MDJaMB0xGzAZBgNVBAMTEnNwdGVzdC5leGFtcGxlLmVkdTCCAaIwDQYJKoZI
+hvcNAQEBBQADggGPADCCAYoCggGBAOjmPSBzRsjbPBBA6jYVW+QtsYM5fvIuNErG
+VDRvKHyCTNbmdFZ37qEl/fwsrdF4hn4V7fAZ6jW6R1aMGFl1vQyJ289B8l5HOPjf
+GuB2gL9IxulOmrkYVN8nfgjlbFNNktMQJ8NprYEyl3o786xCCxx3AiA5Mgdv400L
+6vlmEfNHIwsOHAUTNRyCwMS9P6jBJ5IIxD0Mef+3oUjAvVsPZu24EJnzTUasZnI0
+F8aC/YzVbxObBNcymtA2Ipec/gLe1B09eDZUduXPL/as57QWvgJrWj8bCK+Ldj0P
+MPSvWzr4BnN58dxaYgCgRH7tnhZudPvCjBakQzkxo/njsRIKtm3lN9UmUYiXbl+e
+bu0DSQFUaFfO2hOOUTNAr/QuC+GQL+U7VAdybTbP+KcH5LbNUSqYkxSwhbFz5aym
+o5KppnYB9K5iySRWvGIhnwXHNv5yFrmUbet2BPJlMzv7NaePaZ76ypobzNjjNBbg
+aNECsQ1ZD9fe2Q8UBe0m2gQP5Yux5QIDAQABo0AwPjAdBgNVHREEFjAUghJzcHRl
+c3QuZXhhbXBsZS5lZHUwHQYDVR0OBBYEFGcLIl5kg+GFIh9HXeZyLzsv5e7qMA0G
+CSqGSIb3DQEBCwUAA4IBgQAf8/iZXUWtWGMBw2OfonDDWbuhgLnNWddpllcVx7v/
+Yu75+wgfIdNXg6XM4WkGkpbhlkpDLRt2c6rMQpxrQtq/5G3OKEXKyjUOl5pZsYkG
+asVENYPSCfuu3rlK85XaW3H1SSJqSax/UKcYXyB1TIW6mNy3OxuvHak6y4LzFnug
+CO7p/W2jvffwmxfqjbO7wQfXUQz3SZS04sHMqQoStOwy2N5xxQ3uTF34EoXBto+n
+XIEOptKPhV2NkEzj+UUIi1588dck8T0SstbSElbTnJ4sNZFriX6JOPFNW08fezot
+izerOHuAFpFQvtugWoZT87YYaFwG+Zr5QNa4fNOcAL+FHvbOfEqIGs+H6GSf0dZV
+lkcJyzWZvuK/4RGqWbLvfAYRm0PAGTQSLdO8QJSYWdJtJvZFEMgddQ2HoIzeO5wo
+B42FKDSHottI9avilApQBdRCtust8XRPtEAzDB/t/1jbO7u2tkzgY3614mX5xgut
+Ileaae5eVCjw4uYbkh+Mt5M=
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
new file mode 100644
index 0000000..1622ef3
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDo5j0gc0bI2zwQ
+QOo2FVvkLbGDOX7yLjRKxlQ0byh8gkzW5nRWd+6hJf38LK3ReIZ+Fe3wGeo1ukdW
+jBhZdb0MidvPQfJeRzj43xrgdoC/SMbpTpq5GFTfJ34I5WxTTZLTECfDaa2BMpd6
+O/OsQgscdwIgOTIHb+NNC+r5ZhHzRyMLDhwFEzUcgsDEvT+owSeSCMQ9DHn/t6FI
+wL1bD2btuBCZ801GrGZyNBfGgv2M1W8TmwTXMprQNiKXnP4C3tQdPXg2VHblzy/2
+rOe0Fr4Ca1o/Gwivi3Y9DzD0r1s6+AZzefHcWmIAoER+7Z4WbnT7wowWpEM5MaP5
+47ESCrZt5TfVJlGIl25fnm7tA0kBVGhXztoTjlEzQK/0LgvhkC/lO1QHcm02z/in
+B+S2zVEqmJMUsIWxc+WspqOSqaZ2AfSuYskkVrxiIZ8Fxzb+cha5lG3rdgTyZTM7
++zWnj2me+sqaG8zY4zQW4GjRArENWQ/X3tkPFAXtJtoED+WLseUCAwEAAQKCAYBM
+3eCC20kbdbAnNSWX4AjKEIKr6sgJKlK78yVLgPx9y4uMydbPyxmJOj7PgfeEUSEi
+cB5txj/Up7xvxiErNX7FqqJPj1Zs41jcWtZGCxaHC4AK9JSATpWEaUZhrUbJX6r7
+2jMlfbV0FLyF7U+JJOsB5A1hkT7/0V/Vx/8vfQ6jmnDobym0SxiWZlk1Fbjy+30R
+567M71c8nOCwYFyet0CjaMKh7PkuQCw3uRW3wPfqCW91qw438E3ENnnITFpRnDUI
+iZIXJSj3Sqcx/W7Q6xei+y95U4tksT3/SQ7hVXp+BhfyjXdK/k0vNzxZfWk9nCD8
+h7HeiQuLPENzrlOwuWtI+gLDIdFplXUJ+/piK3okdstdHJcWcNUelW8yr7JSpv1I
+a2KMgHI2F4UVcTYLZrevzxd5a0cpvFW7vmvdw2vFrCb5JsVsmqBu5OLeaVGDIbIA
+2SLfJqq12fi2rxk28VtwXXgaCTttSM+8VY7dlT/mPCqX3Sx2eM7EPt6RVHuri4EC
+gcEA+3q6Vht60YXNaw7m4BFISntVm4Z2gGFNswLlrgPRHOacaQVMKhpqt3HmNKAT
+1MD/a5C60HkUjMB95m2nE4k1Iade8EzUPXD1FvFbE9/+ifNx2OrC8pKrEmRiTmCY
+oel45uoXsksNGJynfuRp2TpAVSZrXaIbGKZiMJZv0QZAilVBurZnZyV0jKQYkSFM
+FOt60PDJJEqZzG01dvDJxsIYQURtjNscO0R2ncloLXm7qu1/fcP7CAawWgFYyer2
+WEdVAoHBAO0WAhxCvFoev348Wf33lQi9c6w7WN/WEkhNOJ5p4PKsJphSZbt2bjCt
+RdRmvahSXeiGrDPuaxoWaQqcXprcu3ndFYBcK2xZpIl/mf0wr1QTEHCkRXzfxRjC
+Mmy+yTeKT4L18xKgg6pJn+wC3hwsv2BQPkp+NPJhD2bmVUWorqXq5fiBV2b7lTg0
+q1HHXYtxk22bw7xtstFENGTqa22KwD5Wd6nj9DamLzKhUhOdcJ7yGVu9se7YcGGh
+pg57muigUQKBwQD5feH96Zdo5UFN9GPTavH4ivH8sWNBrMeEUNyDTuAYtyX3/zx4
+DOtRAhwsm5/xFGSTV+wvReDAX3zIroLym85ti/phlyd9qWJOl7cPOcvzGuYZGZe9
+RwuX3KW3MphbEiFTnm1SAqmEgG6gMoZc8DDBCbO9GkWdp/yETcuzaWuAkmL6lVpy
+97LwkSCaY5lyq8iWIDy915FMQhCn5u2YVhnwLq4s73jLx/mSQy4q57nrM2Kn6FZV
+uSUetnVbJdOu810CgcBNCzbaWjF9E7rk2dXguwD6Wx5o3MxPyPAeAMIicIPCOIE+
+RKB8n8rFFLm5gT2mokWUF5eENLknPBsccJ4pswtVWavwD4Oo7SST7hxrc9O1/Y/9
+GtTd9JXHKuxZ/FHFM7QM+cHozrKattw6ROBKxZvXP5xOdt7b2QC5TqZtQZinoELl
+U5rEg4MFRdBafe//LYRcPR8Jb5iJeqGQHcGVUl6Qo2a1lbc5vx1dVaEncKU1cbUd
+4/IbjMhQYchlsnMvn1ECgcEAxwT/UvLwhYeFK6UHRwJ/z1eKGAC8R2B9tlmgddZx
+T93qbVq4lZXKw3osqdi+pgWvvmg9aK9r/dO1E93S11msnoTI+W9xTr+y5y9dN/hx
+5deQMUK+3woLog6LsGiKE2IamCNQBFkgd4VvhXgG+2pTPYJ9nyuEA+na+tfE6bSa
+foJ8KQT1rmRFQYRboBY/xxqtsl6Nh84JK7kCw27NNdhssyuiipfa8NLM4m+yeA6n
+/oz8xKl5PKwOrvk2DH+FwaAg
+-----END PRIVATE KEY-----
diff --git a/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
new file mode 100644
index 0000000..73aaaab
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID/TCCAmWgAwIBAgIJAJZqOL69C6nRMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNV
+BAMTEnNwdGVzdC5leGFtcGxlLmVkdTAeFw0xODEyMjAyMjM4NDhaFw0yODEyMTcy
+MjM4NDhaMB0xGzAZBgNVBAMTEnNwdGVzdC5leGFtcGxlLmVkdTCCAaIwDQYJKoZI
+hvcNAQEBBQADggGPADCCAYoCggGBANJ1OC6Ql4te2/7PArBkuM/EF1NcQILv7bJa
+ecJDGYBVoWgL0a2KQ0XMESusgkVmVjj/jcbtvwIiXI/6BEu815OF6eSZIwxWdQBp
+eKbrWTbt07GiGgdXoXot6oMs5a9YXuWLt8pTXrFVMmwXU+ZfWJtuU8OIgm9esAEI
+QBHvDVOJtdKdBMWJFa5nUzkaVvA0Fr8r+/FHUvSCnlKOMaUIfTgtoS9AQnaRQ1dV
+l39Z2KAh87JYvRIxvbaPaKgar2eGQ+PQD8rqsB5K5wgnADAxYM9Vo0YXSpPH+Fvw
+N3EJgURUSEY2E0Jx8JOx368ERNLXx3kfnRxCiZRDkTZF9WP6lBnDwc1WXRwpVCDT
+RnF+SIh6IC1Bj/qpkpCD3nri7tycejoeAtVj1YZHWarf9iqdcLYOAWmeyGbFl3hj
+v6qcXnIfy1KyHLCAdIrg1TymLovXXKW09pEbVLdsHmLz0h+DxPs4FsinK2AQBMn1
+6u8BJJ/+spCzIQ2QNPcGORh6XemBpQIDAQABo0AwPjAdBgNVHREEFjAUghJzcHRl
+c3QuZXhhbXBsZS5lZHUwHQYDVR0OBBYEFPC8rkASWHQxrtCQ4wwtnsJRy6K5MA0G
+CSqGSIb3DQEBCwUAA4IBgQCks2nY7YzdIKV02NHD9STWD3yPtEwPYZZ3NBno0WW2
+0rS6cU+fxFx37nY8ULve4cFQkLR8fOO44e1qIuTgLGCauSGTx/Ts/tbmZXbpGTwV
+7cjZDCfC7yEFAVrfQFOMNKeQEssuLFj+d4STGLorxsM+2YygdOgohJz0e3xOcmCN
+HqEuC9RbzrnLc/A4/mOHKwnwCCg71zA1/Ew9NUoRm2n8IfaONIUaMg9opNiHxX4e
+u3UFaaPmn/mInuWYYMXzbIbdlU/XhKvXrujWYWj7anTDWvGQmNEecsQH92SrO0pf
++9WwcWUQTQiWUdq8/OxjXfzs1PrQnSlp0eizgcdKHDKbCUaSuK1i2wdxfEsu5sbZ
+AIW0+dXJ2IyzM+0sv2g4DOsXsnSvinGqjr82A54mXGSr7edhPdlQhILFkJfhTwLq
++mjnyQSNe3s24VNeGc76jbHIrkEWuA460QGqz1Fa2CsQo5SH1IkxNIKpBZWt+w2L
+dAza/NzYyDruY5IJCrZa9Qw=
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
new file mode 100644
index 0000000..9e979fe
--- /dev/null
+++ b/demo/complex2s/configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDSdTgukJeLXtv+
+zwKwZLjPxBdTXECC7+2yWnnCQxmAVaFoC9GtikNFzBErrIJFZlY4/43G7b8CIlyP
++gRLvNeThenkmSMMVnUAaXim61k27dOxohoHV6F6LeqDLOWvWF7li7fKU16xVTJs
+F1PmX1ibblPDiIJvXrABCEAR7w1TibXSnQTFiRWuZ1M5GlbwNBa/K/vxR1L0gp5S
+jjGlCH04LaEvQEJ2kUNXVZd/WdigIfOyWL0SMb22j2ioGq9nhkPj0A/K6rAeSucI
+JwAwMWDPVaNGF0qTx/hb8DdxCYFEVEhGNhNCcfCTsd+vBETS18d5H50cQomUQ5E2
+RfVj+pQZw8HNVl0cKVQg00ZxfkiIeiAtQY/6qZKQg9564u7cnHo6HgLVY9WGR1mq
+3/YqnXC2DgFpnshmxZd4Y7+qnF5yH8tSshywgHSK4NU8pi6L11yltPaRG1S3bB5i
+89Ifg8T7OBbIpytgEATJ9ervASSf/rKQsyENkDT3BjkYel3pgaUCAwEAAQKCAYEA
+kmBxGQH8RTVO8eTtS95iJC+QwavyOp/BxUDkWtbsj7P/NSyzQ25c59jNQIEVgktx
+QOeNpoSJS2S22HTeNAc+MR781MAl/ljLu+OfxQj/3hKAIJZMYDr01tPEvkOl5NUj
++6e3xwNBYzmMfl2jPyGlsUWFAQSbI/bJl44zccXAkQ/A5KHNRc7Yw5qd6aOGQD8a
+axCehOxEqEeI8oZvxQcogMBL0V9yWqEiI0Ymvq6w2n+CzdKmflcWSjloYzNcODbL
+Ef2+8/fBZhHTS0GLCIqQpK+tZxt4K77DK2p2L9dYuHK7vtWn1j0YIwPqD+QVVtuT
+d7BOOmakPj2E7EXq/GvFw8gB/gRLoLuJSq5vvhPrSVuJqWdxDuxSutGgIoN3mQxd
+2AjuBXvqwYaZ3UGHZlBYAQx5ICiAGjxv/1zmKp+9OJHge/a1e6Z8jgQcpS7OWNhU
+dj6qfs+IiWKEaMM7D8dj4ncoArBpE7/BzlVuJ377cqRx35alMcKlawQWF1YqSDrB
+AoHBAPSipCLz4sr3U2jluXehntYsKevWcBtFkEd49Ay5uZTu/aweKWIozjDt7T3L
+mjYi+QGpt28MdNmpoofYOmpt+lrc0HWrv+UB9k/qFxfwgZKaXa1nm/VLfK77L4IB
+8I9dpjvDi724Xg/JJ1jsGM13+jGEfTQTl4Hi0lZwMydUO+O4oWB4kG9qhF8C+yQc
+12CCFH+Da8uwcwM+zCJwRm3qMKceifhEGAuFJ430Rp7cuqlJYfQZ4pVhRxwP6vns
+cLCz+QKBwQDcPB5bCjci/HMe0V19HxPrKh0hGPLIRCPAakT8Mz8N2lVAtWDXFL5q
+eHskl6cf8RQLfrcUiL+jQvD5VV8I7BkolCv0GZT/q36I/Z1QKlQC1O0IGG/hNqwt
+PS85YM6yC84YIKx0rN6O03/nYcslRv19q+MNiR9sZEeN6cScUc6aUINhWjzQ4mb8
+Z9ErguJrq0sCoAVU+t/yRo/YB/d2xdN9XLe+2cgsM6s0TiHo4v2SeFHKewBw+RLp
+yrShY6COzg0CgcEA0EFwt2ylgiGgeSkvhV8qJ6s7GNDZaO4EUEPwhrDJAredbhvT
+IQQZ29+AWl3sbu/AySCgzsFs7CsT+M8jk50CRr26HKJUXvEXrZpbhH6y34nX+5m7
+U8uqXg/ptqROFM4liLUETkMYmBmnDHUY/DmJ3QOrzlxrWyAr7XfgpDd6MHbpsoWQ
+d7jW7UdNYsXGuBqktpS7fJA+qOGZyCuKWWHHf01pKNdXHN+C976fK/g+U4TsBXDP
+ylkgvwvx/kbA/DyJAoHAQxXA/WRYNT0G6B1ISAO+coTKiLlrwtsWtNbqGpSVoWef
+Tm2xiPKVqiL3B8d2LgGmZHX92LBrB5UtiBWcNECOzVCNLvbX7yVTDvGKCNBL9Ozd
+Ivkmo0ifG8ymZOj7LTrxVWImhgfeZ00/icC9O6arMqu4Jvhc7QyCy1SpAiDdOR5L
+Vs1A9zPvwPTyvzlINRnhaHRMC32717XsvRZ4J+LMsEQc6HK4SdaXUQB3zdPO/93M
+tEvRb5g/TZ3kdcC+OKHFAoHAO9R3y6ZjUM8T8/4XcyRD968V4sZIvVQfpSaH86GO
+TrECZp5SqSWUTqAWTJWS0yIctAML60nWF+OPRUlrq0yk2veN9Re6eWfyoyQOFd92
+U+bxh3QEue5LGOwpqrPV/1cJSFdv88eS+F8q7i/dD765Tio6kJjKzXPN3FJqAvNB
+lAnaO4Apbuzob25Qkmm0NVQHap+TJGJMvX2vVX9CjE6haVWq1lJMakkoQOeIlyi5
+iDjt9rDlIwDYeGWk4KFgsKM7
+-----END PRIVATE KEY-----
diff --git a/demo/complex2s/create-ref-loaders.gsh b/demo/complex2s/create-ref-loaders.gsh
new file mode 100644
index 0000000..0cfdcdf
--- /dev/null
+++ b/demo/complex2s/create-ref-loaders.gsh
@@ -0,0 +1,31 @@
+gs = GrouperSession.startRootSession()
+
+group = new GroupSave(gs).assignName("etc:affiliationLoader").assignCreateParentStemsIfNotExist(true).save()
+group.addType(GroupTypeFinder.find("grouperLoader"))
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderType", "SQL_GROUP_LIST")
+group.setAttribute("grouperLoaderScheduleType", "CRON")
+group.setAttribute("grouperLoaderQuartzCron", "0 * * * * ?")
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderGroupTypes", "addIncludeExclude")
+group.setAttribute("grouperLoaderQuery", "SELECT concat('ref:affiliation:',affiliation,'_systemOfRecord') as GROUP_NAME, uid as SUBJECT_ID, 'ldap' as SUBJECT_SOURCE_ID from SIS_AFFILIATIONS")
+
+group = new GroupSave(gs).assignName("etc:deptLoader").assignCreateParentStemsIfNotExist(true).save()
+group.addType(GroupTypeFinder.find("grouperLoader"))
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderType", "SQL_GROUP_LIST")
+group.setAttribute("grouperLoaderScheduleType", "CRON")
+group.setAttribute("grouperLoaderQuartzCron", "0 * * * * ?")
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderQuery", "SELECT concat('ref:dept:',department) as GROUP_NAME, uid as SUBJECT_ID, 'ldap' as SUBJECT_SOURCE_ID from SIS_PERSONS where department is not null")
+
+group = new GroupSave(gs).assignName("etc:coursesLoader").assignCreateParentStemsIfNotExist(true).save()
+group.addType(GroupTypeFinder.find("grouperLoader"))
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderType", "SQL_GROUP_LIST")
+group.setAttribute("grouperLoaderScheduleType", "CRON")
+group.setAttribute("grouperLoaderQuartzCron", "0 * * * * ?")
+group.setAttribute("grouperLoaderDbName", "sis")
+group.setAttribute("grouperLoaderQuery", "SELECT concat('ref:course:',courseId) as GROUP_NAME, uid as SUBJECT_ID, 'ldap' as SUBJECT_SOURCE_ID from SIS_COURSES")
+
+edu.internet2.middleware.grouper.app.loader.GrouperLoaderType.scheduleLoads()
diff --git a/demo/complex2s/create-ref-loaders.sh b/demo/complex2s/create-ref-loaders.sh
new file mode 100755
index 0000000..39d690e
--- /dev/null
+++ b/demo/complex2s/create-ref-loaders.sh
@@ -0,0 +1,3 @@
+source ../../library.bash
+
+execute_gsh complex2s_grouper_daemon_1 create-ref-loaders.gsh
diff --git a/demo/complex2s/directory/Dockerfile b/demo/complex2s/directory/Dockerfile
new file mode 100644
index 0000000..06df07b
--- /dev/null
+++ b/demo/complex2s/directory/Dockerfile
@@ -0,0 +1,28 @@
+FROM centos:centos7
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+RUN yum install -y epel-release \
+    && yum update -y \
+    && yum install -y 389-ds-base \
+    && yum clean all \
+    && rm -rf /var/cache/yum
+
+COPY container_files/seed-data/ /seed-data/
+
+RUN useradd ldapadmin \
+    && rm -fr /var/lock /usr/lib/systemd/system \
+    # The 389-ds setup will fail because the hostname can't reliable be determined, so we'll bypass it and then install. \
+    && sed -i 's/checkHostname {/checkHostname {\nreturn();/g' /usr/lib64/dirsrv/perl/DSUtil.pm \
+    # Not doing SELinux \
+    && sed -i 's/updateSelinuxPolicy($inf);//g' /usr/lib64/dirsrv/perl/* \
+    # Do not restart at the end \
+    && sed -i '/if (@errs = startServer($inf))/,/}/d' /usr/lib64/dirsrv/perl/* \
+    && setup-ds.pl --silent --file /seed-data/ds-setup.inf \
+    && /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir \
+    && while ! curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to start; sleep 1; done; \
+    ldapadd -H ldap:/// -f /seed-data/users.ldif -x -D "cn=Directory Manager" -w password
+
+EXPOSE 389
+
+CMD rm -rf /var/lock/dirsrv/slapd-dir/server/* && /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-dir && sleep infinity
diff --git a/demo/complex2s/directory/container_files/seed-data/ds-setup.inf b/demo/complex2s/directory/container_files/seed-data/ds-setup.inf
new file mode 100644
index 0000000..96c29a1
--- /dev/null
+++ b/demo/complex2s/directory/container_files/seed-data/ds-setup.inf
@@ -0,0 +1,28 @@
+[General]
+AdminDomain = internet2.edu
+ConfigDirectoryAdminID = admin
+ConfigDirectoryAdminPwd = admin
+ConfigDirectoryLdapURL = ldap://localhost:389/o=NetscapeRoot
+FullMachineName = localhost
+ServerRoot = /usr/lib64/dirsrv
+SuiteSpotGroup = nobody
+SuiteSpotUserID = nobody
+
+[admin]
+Port = 9830
+ServerAdminID = admin
+ServerAdminPwd = admin
+ServerIpAddress = 0.0.0.0
+SysUser = nobody
+
+[slapd]
+AddOrgEntries = No
+AddSampleEntries = No
+InstallLdifFile = suggest
+RootDN = cn=Directory Manager
+RootDNPwd = password
+ServerIdentifier = dir
+ServerPort = 389
+SlapdConfigForMC = yes
+Suffix = dc=internet2,dc=edu
+UseExistingMC = No
diff --git a/demo/complex2s/directory/container_files/seed-data/users.ldif b/demo/complex2s/directory/container_files/seed-data/users.ldif
new file mode 100644
index 0000000..383b1b7
--- /dev/null
+++ b/demo/complex2s/directory/container_files/seed-data/users.ldif
@@ -0,0 +1,35 @@
+dn: cn=admin,dc=internet2,dc=edu
+objectClass: simpleSecurityObject
+objectClass: organizationalRole
+cn: admin
+userPassword: password
+description: LDAP administrator
+
+dn: cn=users,ou=Groups,dc=internet2,dc=edu
+objectClass: groupOfUniqueNames
+objectClass: top
+uniqueMember: uid=banderson,ou=People,dc=internet2,dc=edu
+uniqueMember: uid=jsmith,ou=People,dc=internet2,dc=edu
+cn: users
+
+dn: ou=Affiliations,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Affiliations
+
+dn: ou=Courses,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Courses
+
+dn: ou=midpoint,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: midpoint
+
+dn: ou=Generic,ou=Groups,dc=internet2,dc=edu
+objectClass: top
+objectClass: organizationalUnit
+ou: Generic
+
+
diff --git a/demo/complex2s/docker-compose.yml b/demo/complex2s/docker-compose.yml
new file mode 100644
index 0000000..d35f63e
--- /dev/null
+++ b/demo/complex2s/docker-compose.yml
@@ -0,0 +1,307 @@
+version: "3.3"
+
+services:
+  grouper_daemon:
+    build: ./grouper_daemon/
+    command: bash -c "while ! curl -s grouper_data:3306 > /dev/null; do echo waiting for mysql on grouper_data to start; sleep 3; done; while ! curl -s ldap://directory:389 > /dev/null; do echo waiting for ldap on directory to start; sleep 3; done; exec daemon"
+    depends_on:
+     - grouper_data
+     - directory
+    environment:
+     - ENV
+     - USERTOKEN
+     - GROUPER_CLIENT_WEBSERVICE_PASSWORD_FILE=password
+     - GROUPER_DATABASE_PASSWORD_FILE=/run/secrets/g_database_password.txt
+     - RABBITMQ_PASSWORD_FILE=/run/secrets/rabbitmq_password.txt
+     - SUBJECT_SOURCE_LDAP_PASSWORD=password
+    networks:
+      net:
+        aliases:
+         - grouper-daemon
+    secrets:
+     - g_database_password.txt
+     - rabbitmq_password.txt
+     - source: grouper.hibernate.properties
+       target: grouper_grouper.hibernate.properties
+     - source: grouper-loader.properties
+       target: grouper_grouper-loader.properties
+     - source: subject.properties
+       target: grouper_subject.properties
+    volumes:
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.properties
+       target: /opt/grouper/conf/grouper.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.client.properties
+       target: /opt/grouper/conf/grouper.client.properties
+
+  grouper_ui:
+    build: ./grouper_ui/
+    command: bash -c "while ! curl -s grouper_data:3306 > /dev/null; do echo waiting for mysql on grouper_data to start; sleep 3; done; while ! curl -s ldap://directory:389 > /dev/null; do echo waiting for ldap on directory to start; sleep 3; done; exec ui"
+    depends_on:
+     - grouper_data
+     - directory
+    environment:
+     - ENV
+     - USERTOKEN
+     - GROUPER_DATABASE_PASSWORD_FILE=/run/secrets/g_database_password.txt
+     - SUBJECT_SOURCE_LDAP_PASSWORD=password
+    networks:
+      net:
+        aliases:
+         - grouper-ui
+    ports:
+     - 4443:443
+    secrets:
+     - g_database_password.txt
+     - source: grouper.hibernate.properties
+       target: grouper_grouper.hibernate.properties
+     - source: grouper-loader.properties
+       target: grouper_grouper-loader.properties
+     - source: subject.properties
+       target: grouper_subject.properties
+     - source: g_sp-key.pem
+       target: shib_sp-key.pem
+     - source: g_host-key.pem
+       target: host-key.pem
+    volumes:
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.properties
+       target: /opt/grouper/conf/grouper.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.client.properties
+       target: /opt/grouper/conf/grouper.client.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/shibboleth/sp-cert.pem
+       target: /etc/shibboleth/sp-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/grouper/shibboleth/shibboleth2.xml
+       target: /etc/shibboleth/shibboleth2.xml
+     - type: bind
+       source: ./configs-and-secrets/grouper/shibboleth/idp-metadata.xml
+       target: /etc/shibboleth/idp-metadata.xml
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  grouper_ws:
+    build: ./grouper_ws/
+    command: bash -c "while ! curl -s grouper_data:3306 > /dev/null; do echo waiting for mysql to start; sleep 3; done; while ! curl -s ldap://directory:389 > /dev/null; do echo waiting for ldap to start; sleep 3; done; exec ws"
+    depends_on:
+     - grouper_data
+     - directory
+    environment:
+     - ENV
+     - GROUPER_DATABASE_PASSWORD_FILE=/run/secrets/g_database_password.txt
+     - SUBJECT_SOURCE_LDAP_PASSWORD=password
+     - USERTOKEN
+    networks:
+      net:
+        aliases:
+         - grouper-ws
+    ports:
+     - 9443:443
+    secrets:
+     - g_database_password.txt
+     - source: grouper.hibernate.properties
+       target: grouper_grouper.hibernate.properties
+     - source: grouper-loader.properties
+       target: grouper_grouper-loader.properties
+     - source: subject.properties
+       target: grouper_subject.properties
+     - source: g_sp-key.pem
+       target: shib_sp-key.pem
+     - source: g_host-key.pem
+       target: host-key.pem
+    volumes:
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.properties
+       target: /opt/grouper/conf/grouper.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/application/grouper.client.properties
+       target: /opt/grouper/conf/grouper.client.properties
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/grouper/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  grouper_data:
+    build: ./grouper_data/
+    networks:
+      net:
+        aliases:
+         - grouper-data
+    ports:
+     - 3306:3306
+    volumes:
+     - grouper_data:/var/lib/mysql  
+
+  directory:
+    build: ./directory/
+    ports:
+     - 389:389
+    networks:
+     - net
+    volumes:
+     - ldap:/var/lib/dirsrv
+
+  sources:
+    build: ./sources/
+    ports:
+     - 13306:3306
+    networks:
+     - net
+    volumes:
+     - source_data:/var/lib/mysql
+
+  targets:
+    build: ./targets/
+    ports:
+     - 23306:389
+    networks:
+     - net
+    volumes:
+     - target_data:/var/lib/mysql
+
+  midpoint_data:
+    image: tier/mariadb:mariadb10
+    ports:
+     - 33306:3306
+    networks:
+      net:
+        aliases:
+         - midpoint-data
+    volumes:
+     - midpoint_mysql:/var/lib/mysql
+     - midpoint_data:/var/lib/mysqlmounted
+    environment:
+     - CREATE_NEW_DATABASE=if_needed
+
+  midpoint_server:
+    build: ./midpoint_server/
+    depends_on:
+     - midpoint_data
+    ports:
+     - 8443:443
+    environment:
+     - AUTHENTICATION
+     - ENV
+     - USERTOKEN
+     - REPO_DATABASE_TYPE
+     - REPO_JDBC_URL
+     - REPO_HOST
+     - REPO_PORT
+     - REPO_DATABASE
+     - REPO_USER
+     - REPO_MISSING_SCHEMA_ACTION
+     - REPO_UPGRADEABLE_SCHEMA_ACTION
+     - REPO_SCHEMA_VERSION_IF_MISSING
+     - REPO_SCHEMA_VARIANT
+     - MP_MEM_MAX
+     - MP_MEM_INIT
+     - MP_JAVA_OPTS
+     - SSO_HEADER
+     - TIER_BEACON_OPT_OUT
+     - TIMEZONE
+    networks:
+      net:
+        aliases:
+         - midpoint-server
+    secrets:
+     - mp_database_password.txt
+     - mp_keystore_password.txt
+     - mp_sp-encrypt-key.pem
+     - mp_sp-signing-key.pem
+     - mp_host-key.pem
+    volumes:
+     - midpoint_home:/opt/midpoint/var
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/shibboleth2.xml
+       target: /etc/shibboleth/shibboleth2.xml
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/idp-metadata.xml
+       target: /etc/shibboleth/idp-metadata.xml
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/sp-signing-cert.pem
+       target: /etc/shibboleth/sp-signing-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/shibboleth/sp-encrypt-cert.pem
+       target: /etc/shibboleth/sp-encrypt-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/host-cert.pem
+     - type: bind
+       source: ./configs-and-secrets/midpoint/httpd/host-cert.pem
+       target: /etc/pki/tls/certs/cachain.pem
+
+  idp:
+    build: ./idp/
+    depends_on:
+     - directory
+    environment:
+     - JETTY_MAX_HEAP=64m
+     - JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=password
+     - JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=password
+    networks:
+     - net
+    ports:
+     - 443:443
+
+  mq:
+    build: ./mq/
+    environment:
+     - RABBITMQ_NODENAME=docker-rabbit
+    hostname: rabbitmq
+    networks:
+     - net
+    ports:
+     - 15672:15672
+    volumes:
+     - mq:/var/lib/rabbitmq
+
+networks:
+  net:    
+    driver: bridge
+
+secrets:
+# grouper
+  g_host-key.pem:
+    file: ./configs-and-secrets/grouper/httpd/host-key.pem
+  g_sp-key.pem:
+    file: ./configs-and-secrets/grouper/shibboleth/sp-key.pem
+  g_database_password.txt:
+    file: ./configs-and-secrets/grouper/application/database_password.txt
+  rabbitmq_password.txt:
+    file: ./configs-and-secrets/grouper/application/rabbitmq_password.txt
+  grouper.hibernate.properties:
+    file: ./configs-and-secrets/grouper/application/grouper.hibernate.properties
+  grouper-loader.properties:
+    file: ./configs-and-secrets/grouper/application/grouper-loader.properties
+  subject.properties:
+    file: ./configs-and-secrets/grouper/application/subject.properties
+# midPoint
+  mp_host-key.pem:
+    file: ./configs-and-secrets/midpoint/httpd/host-key.pem
+  mp_sp-signing-key.pem:
+    file: ./configs-and-secrets/midpoint/shibboleth/sp-signing-key.pem
+  mp_sp-encrypt-key.pem:
+    file: ./configs-and-secrets/midpoint/shibboleth/sp-encrypt-key.pem
+  mp_database_password.txt:
+    file: ./configs-and-secrets/midpoint/application/database_password.txt
+  mp_keystore_password.txt:
+    file: ./configs-and-secrets/midpoint/application/keystore_password.txt    
+    
+volumes:
+  grouper_data:
+  source_data:
+  target_data:
+  ldap:
+  midpoint_data:
+  midpoint_mysql:
+  midpoint_home:
+  mq:
diff --git a/demo/complex2s/get-import-sis-persons-status.sh b/demo/complex2s/get-import-sis-persons-status.sh
new file mode 100755
index 0000000..26d3fcd
--- /dev/null
+++ b/demo/complex2s/get-import-sis-persons-status.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+get_task_execution_status "Import from SIS persons"
diff --git a/demo/complex2s/grouper_daemon/Dockerfile b/demo/complex2s/grouper_daemon/Dockerfile
new file mode 100644
index 0000000..4ed3dc7
--- /dev/null
+++ b/demo/complex2s/grouper_daemon/Dockerfile
@@ -0,0 +1,5 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+CMD ["daemon"]
diff --git a/demo/complex2s/grouper_data/Dockerfile b/demo/complex2s/grouper_data/Dockerfile
new file mode 100644
index 0000000..15d196a
--- /dev/null
+++ b/demo/complex2s/grouper_data/Dockerfile
@@ -0,0 +1,40 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+RUN yum install -y epel-release \
+    && yum update -y \
+    && yum install -y mariadb-server mariadb \
+    && yum clean all \
+    && rm -rf /var/cache/yum
+
+COPY container_files/seed-data/ /seed-data/
+COPY container_files/conf/ /opt/grouper/grouper.apiBinary/conf/
+
+RUN mysql_install_db \
+    && chown -R mysql:mysql /var/lib/mysql/ \
+    && sed -i 's/^\(bind-address\s.*\)/# \1/' /etc/my.cnf \
+    && sed -i 's/^\(log_error\s.*\)/# \1/' /etc/my.cnf \
+    && sed -i 's/\[mysqld\]/\[mysqld\]\ncharacter_set_server = utf8/' /etc/my.cnf \
+    && sed -i 's/\[mysqld\]/\[mysqld\]\ncollation_server = utf8_general_ci/' /etc/my.cnf \
+    && sed -i 's/\[mysqld\]/\[mysqld\]\nport = 3306/' /etc/my.cnf \
+    && cat  /etc/my.cnf \
+    && echo "/usr/bin/mysqld_safe &" > /tmp/config \
+    && echo "mysqladmin --silent --wait=30 ping || exit 1" >> /tmp/config \
+    && echo "mysql -e 'GRANT ALL PRIVILEGES ON *.* TO \"root\"@\"%\" WITH GRANT OPTION;'" >> /tmp/config \
+    && echo "mysql -e 'CREATE DATABASE grouper CHARACTER SET utf8 COLLATE utf8_bin;'" >> /tmp/config \
+    && bash /tmp/config \
+    && rm -f /tmp/config
+
+RUN (mysqld_safe & ) \
+    && while ! curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to start; sleep 1; done; \
+    bin/gsh -registry -check -runscript -noprompt && \
+    echo "Running demo.gsh" && \
+    sleep 10 && \
+    bin/gsh /seed-data/demo.gsh && \
+    echo "demo.gsh DONE" && \
+    rm /seed-data/demo.gsh
+
+EXPOSE 3306
+
+CMD mysqld_safe
diff --git a/demo/complex2s/grouper_data/container_files/conf/grouper-loader.properties b/demo/complex2s/grouper_data/container_files/conf/grouper-loader.properties
new file mode 100644
index 0000000..777376c
--- /dev/null
+++ b/demo/complex2s/grouper_data/container_files/conf/grouper-loader.properties
@@ -0,0 +1,64 @@
+#################################
+## LDAP connections
+#################################
+# specify the ldap connection with user, pass, url
+# the string after "ldap." is the ID of the connection, and it should not have
+# spaces or other special chars in it.  In this case is it "personLdap"
+
+#note the URL should start with ldap: or ldaps: if it is SSL.  
+#It should contain the server and port (optional if not default), and baseDn,
+#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu
+ldap.demo.url = ldap://directory:389/dc=internet2,dc=edu
+ 
+#optional, if authenticated
+ldap.demo.user = cn=admin,dc=internet2,dc=edu
+#ldap.demo.user = cn=admin
+ 
+#optional, if authenticated note the password can be stored encrypted in an external file
+#ldap.demo.pass = ${java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE') != null ? org.apache.commons.io.FileUtils.readFileToString(java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD_FILE'), "utf-8") : java.lang.System.getenv().get('SUBJECT_SOURCE_LDAP_PASSWORD')}
+ldap.demo.pass = password
+ 
+#optional, if you are using tls, set this to true.  Generally you will not be using an SSL URL to use TLS...
+ldap.demo.tls = false
+ 
+#optional, if using sasl
+#ldap.personLdap.saslAuthorizationId =
+#ldap.personLdap.saslRealm =
+ 
+#optional (note, time limit is for search operations, timeout is for connection timeouts),
+#most of these default to vt-ldap defaults.  times are in millis
+#validateOnCheckout defaults to true if all other validate methods are false
+#ldap.personLdap.batchSize =
+#ldap.personLdap.countLimit =
+#ldap.personLdap.timeLimit =
+#ldap.personLdap.timeout =
+#ldap.personLdap.minPoolSize =
+#ldap.personLdap.maxPoolSize =
+#ldap.personLdap.validateOnCheckIn =
+#ldap.personLdap.validateOnCheckOut =
+#ldap.personLdap.validatePeriodically =
+#ldap.personLdap.validateTimerPeriod =
+#ldap.personLdap.pruneTimerPeriod =
+#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes)
+#ldap.personLdap.expirationTime =
+
+#make the paths fully qualified and not relative to the loader group.
+loader.ldap.requireTopStemAsStemFromConfigGroup=false
+
+#####################################
+## Messaging integration with change log
+#####################################
+changeLog.consumer.rabbitMqMessagingSample.quartzCron = 0 * * * * ?                                                          
+
+# note, change "messagingSample" in key to be the name of the consumer.  e.g. changeLog.consumer.someNameAnyName.class
+changeLog.consumer.rabbitMqMessagingSample.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer
+
+changeLog.consumer.rabbitMqMessagingSample.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher
+changeLog.consumer.rabbitMqMessagingSample.publisher.messagingSystemName = rabbitmq
+# note, routingKey property is valid only for rabbitmq. For other messaging systems, it is ignored.
+changeLog.consumer.rabbitMqMessagingSample.publisher.routingKey = 
+## queue or topic
+changeLog.consumer.rabbitMqMessagingSample.publisher.messageQueueType = queue
+changeLog.consumer.rabbitMqMessagingSample.publisher.queueOrTopicName = sampleQueue
+## this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml
+#changeLog.consumer.rabbitMqMessagingSample.publisher.addSubjectAttributes = email
diff --git a/demo/complex2s/grouper_data/container_files/conf/grouper.hibernate.properties b/demo/complex2s/grouper_data/container_files/conf/grouper.hibernate.properties
new file mode 100644
index 0000000..154b8eb
--- /dev/null
+++ b/demo/complex2s/grouper_data/container_files/conf/grouper.hibernate.properties
@@ -0,0 +1,29 @@
+#
+# Grouper Hibernate Configuration
+# $Id: grouper.hibernate.example.properties,v 1.9 2009-08-11 20:18:09 mchyzer Exp $
+#
+
+# The grouper hibernate config uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.hibernate.base.properties
+# (which should not be edited), and the grouper.hibernate.properties overlays
+# the base settings.  See the grouper.hibernate.base.properties for the possible
+# settings that can be applied to the grouper.hibernate.properties
+
+########################################
+## DB settings
+########################################
+
+# e.g. mysql:           jdbc:mysql://localhost:3306/grouper
+# e.g. p6spy (log sql): [use the URL that your DB requires]
+# e.g. oracle:          jdbc:oracle:thin:@server.school.edu:1521:sid
+# e.g. hsqldb (a):      jdbc:hsqldb:dist/run/grouper;create=true
+# e.g. hsqldb (b):      jdbc:hsqldb:hsql://localhost:9001/grouper
+# e.g. postgres:        jdbc:postgresql://localhost:5432/database
+# e.g. mssql:           jdbc:sqlserver://localhost:3280;databaseName=grouper
+hibernate.connection.url = jdbc:mysql://localhost:3306/grouper?CharSet=utf8&useUnicode=true&characterEncoding=utf8
+
+hibernate.connection.username         = root
+# If you are using an empty password, depending upon your version of
+# Java and Ant you may need to specify a password of "".
+# Note: you can keep passwords external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122
+hibernate.connection.password =
diff --git a/demo/complex2s/grouper_data/container_files/conf/grouper.properties b/demo/complex2s/grouper_data/container_files/conf/grouper.properties
new file mode 100644
index 0000000..c931287
--- /dev/null
+++ b/demo/complex2s/grouper_data/container_files/conf/grouper.properties
@@ -0,0 +1,25 @@
+#
+# Grouper Configuration
+# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $
+#
+
+# Grouper uses Grouper Configuration Overlays (documented on wiki)
+# By default the configuration is read from grouper.base.properties
+# (which should not be edited), and the grouper.properties overlays
+# the base settings.  See the grouper.base.properties for the possible
+# settings that can be applied to the grouper.properties
+
+#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on)
+configuration.autocreate.system.groups = true
+
+# A wheel group allows you to enable non-GrouperSystem subjects to act
+# like a root user when interacting with the registry.
+groups.wheel.use                      = true
+
+# Set to the name of the group you want to treat as the wheel group.
+# The members of this group will be treated as root-like users.
+groups.wheel.group                    = etc:sysadmingroup
+
+# Used to allow Include Exclude groups
+grouperIncludeExclude.use = true
+grouperIncludeExclude.requireGroups.use = true
diff --git a/demo/complex2s/grouper_data/container_files/conf/subject.properties b/demo/complex2s/grouper_data/container_files/conf/subject.properties
new file mode 100644
index 0000000..4a31712
--- /dev/null
+++ b/demo/complex2s/grouper_data/container_files/conf/subject.properties
@@ -0,0 +1,78 @@
+#subject.sources.xml.location =
+
+subjectApi.source.ldap.param.ldapServerId.value = demo
+
+subjectApi.source.ldap.id = ldap
+subjectApi.source.ldap.name = EDU Ldap 
+subjectApi.source.ldap.types = person
+subjectApi.source.ldap.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter
+#subjectApi.source.ldap.param.INITIAL_CONTEXT_FACTORY.value = com.sun.jndi.ldap.LdapCtxFactory
+#subjectApi.source.ldap.param.PROVIDER_URL.value = ldap://localhost:389
+#subjectApi.source.ldap.param.SECURITY_AUTHENTICATION.value = simple
+#subjectApi.source.ldap.param.SECURITY_PRINCIPAL.value = cn=admin,dc=internet2,dc=edu
+#subjectApi.source.ldap.param.SECURITY_CREDENTIALS.value = password
+#subjectApi.source.ldap.param.VTLDAP_VALIDATOR.value = ConnectLdapValidator
+
+subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid
+subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false
+subjectApi.source.ldap.param.Name_AttributeType.value = cn
+subjectApi.source.ldap.param.Description_AttributeType.value = cn
+subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")}
+subjectApi.source.ldap.param.sortAttribute0.value = cn
+subjectApi.source.ldap.param.searchAttribute0.value = searchAttribute0
+
+# STATUS SECTION for searches to filter out inactives and allow
+# the user to filter by status with e.g. status=all
+# this is optional, and advanced
+#
+# field in database or ldap or endpoint that is the status field
+#subjectApi.source.example.param.statusDatastoreFieldName.value = status
+
+# search string from user which represents the status.  e.g. status=active
+#subjectApi.source.example.param.statusLabel.value = status
+
+# available statuses from screen (if not specified, any will be allowed). comma separated list.
+# Note, this is optional and you probably dont want to configure it, it is mostly necessary
+# when you have multiple sources with statuses...  if someone types an invalid status
+# and you have this configured, it will not filter by it
+#subjectApi.source.example.param.statusesFromUser.value = Active, Inactive, Pending, All
+
+# all label from the user
+#subjectApi.source.example.param.statusAllFromUser.value = All
+
+# if no status is specified, this will be used (e.g. for active only).  Note, the value should be of the
+# form the user would type in
+#subjectApi.source.example.param.statusSearchDefault.value = status=active
+
+# translate between screen values of status, and the data store value.  Increment the 0 to 1, 2, etc for more translations.
+# so the user could enter: status=active, and that could translate to status_col=A.  The 'user' is what the user types in,
+# the 'datastore' is what is in the datastore.  The user part is not case-sensitive.  Note, this could be a many to one
+#subjectApi.source.example.param.statusTranslateUser0.value = active
+#subjectApi.source.example.param.statusTranslateDatastore0.value = A
+
+# subject identifier to store in grouper's member table.  this is used to increase speed of loader and perhaps for provisioning
+# you can have up to max 1 subject identifier
+#subjectApi.source.example.param.subjectIdentifierAttribute0.value = uid
+
+#searchSubject: find a subject by ID.  ID is generally an opaque and permanent identifier, e.g. 12345678.
+#  Each subject has one and only on ID.  Returns one result when searching for one ID.
+subjectApi.source.ldap.search.searchSubject.param.filter.value = (&(uid=%TERM%)(objectclass=person))
+subjectApi.source.ldap.search.searchSubject.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubject.param.base.value = ou=people
+
+#searchSubjectByIdentifier: find a subject by identifier.  Identifier is anything that uniquely
+#  identifies the user, e.g. jsmith or jsmith@institution.edu.
+#  Subjects can have multiple identifiers.  Note: it is nice to have if identifiers are unique
+#  even across sources.  Returns one result when searching for one identifier.
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.filter.value = (&(|(uid=%TERM%)(employeeNumber=%TERM%))(objectclass=person))
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.searchSubjectByIdentifier.param.base.value = ou=people
+
+#   search: find subjects by free form search.  Returns multiple results.
+
+subjectApi.source.ldap.search.search.param.filter.value = (&(|(|(uid=%TERM%)(cn=*%TERM%*))(uid=%TERM%*))(objectclass=person))
+subjectApi.source.ldap.search.search.param.scope.value = SUBTREE_SCOPE
+subjectApi.source.ldap.search.search.param.base.value = ou=people
+
+subjectApi.source.ldap.attributes = givenName, sn, uid, mail, employeeNumber
+subjectApi.source.ldap.internalAttributes = searchAttribute0
diff --git a/demo/complex2s/grouper_data/container_files/seed-data/demo.gsh b/demo/complex2s/grouper_data/container_files/seed-data/demo.gsh
new file mode 100644
index 0000000..c58d289
--- /dev/null
+++ b/demo/complex2s/grouper_data/container_files/seed-data/demo.gsh
@@ -0,0 +1,41 @@
+System.out.println("************** demo.gsh starting...");
+
+gs = GrouperSession.startRootSession();
+
+addStem("", "app", "app")
+addStem("", "basis", "basis")
+addStem("", "bundle", "bundle")
+addStem("", "org", "org")
+addStem("", "test", "test")
+addStem("", "midpoint", "midpoint")
+
+addRootStem("ref", "ref")
+addStem("ref", "course", "course")
+addStem("ref", "affiliation", "affiliation")
+
+group = GroupFinder.findByName(gs, "etc:sysadmingroup", true);
+group.getAttributeDelegate().assignAttribute(LoaderLdapUtils.grouperLoaderLdapAttributeDefName()).getAttributeAssign();
+attributeAssign = group.getAttributeDelegate().retrieveAssignment(null, LoaderLdapUtils.grouperLoaderLdapAttributeDefName(), false, true);
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapQuartzCronName(), "0 * * * * ?");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapTypeName(), "LDAP_SIMPLE");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapFilterName(), "(cn=sysadmingroup)");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSearchDnName(), "ou=midpoint,ou=Groups");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapServerIdName(), "demo");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSourceIdName(), "ldap");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectExpressionName(), '${loaderLdapElUtils.convertDnToSpecificValue(subjectId)}');
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectAttributeName(), "uniqueMember");
+attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectIdTypeName(), "subjectId");
+
+midpointGroupsGroup = new GroupSave(gs).assignName("etc:midpointGroups").assignCreateParentStemsIfNotExist(true).save();
+
+testGroup = new GroupSave(gs).assignName("midpoint:test").assignCreateParentStemsIfNotExist(true).save();
+chess = new GroupSave(gs).assignName("app:mailinglist:chess").assignCreateParentStemsIfNotExist(true).save()
+idmfans = new GroupSave(gs).assignName("app:mailinglist:idm-fans").assignCreateParentStemsIfNotExist(true).save()
+cs = new GroupSave(gs).assignName("app:cs").assignCreateParentStemsIfNotExist(true).save()
+volunteers = new GroupSave(gs).assignName("test:volunteers").assignCreateParentStemsIfNotExist(true).save()
+
+midpointGroupsGroup.addMember(SubjectFinder.findById(testGroup.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(chess.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(idmfans.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(cs.getId(), 'group', 'g:gsa'), false)
+midpointGroupsGroup.addMember(SubjectFinder.findById(volunteers.getId(), 'group', 'g:gsa'), false)
diff --git a/demo/complex2s/grouper_ui/Dockerfile b/demo/complex2s/grouper_ui/Dockerfile
new file mode 100644
index 0000000..3551f04
--- /dev/null
+++ b/demo/complex2s/grouper_ui/Dockerfile
@@ -0,0 +1,7 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+#COPY in custom css, images, etc
+
+CMD ["ui"]
diff --git a/demo/complex2s/grouper_ui/container_files/shibboleth/shibd.logger b/demo/complex2s/grouper_ui/container_files/shibboleth/shibd.logger
new file mode 100644
index 0000000..2589b43
--- /dev/null
+++ b/demo/complex2s/grouper_ui/container_files/shibboleth/shibd.logger
@@ -0,0 +1,69 @@
+# set overall behavior
+log4j.rootCategory=DEBUG, shibd_log, warn_log
+
+# fairly verbose for DEBUG, so generally leave at DEBUG
+log4j.category.XMLTooling.XMLObject=DEBUG
+log4j.category.XMLTooling.KeyInfoResolver=DEBUG
+log4j.category.Shibboleth.IPRange=DEBUG
+log4j.category.Shibboleth.PropertySet=DEBUG
+
+# raise for low-level tracing of SOAP client HTTP/SSL behavior
+log4j.category.XMLTooling.libcurl=DEBUG
+
+# useful categories to tune independently:
+#
+# tracing of SAML messages and security policies
+#log4j.category.OpenSAML.MessageDecoder=DEBUG
+#log4j.category.OpenSAML.MessageEncoder=DEBUG
+#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG
+#log4j.category.XMLTooling.SOAPClient=DEBUG
+# interprocess message remoting
+#log4j.category.Shibboleth.Listener=DEBUG
+# mapping of requests to applicationId
+#log4j.category.Shibboleth.RequestMapper=DEBUG
+# high level session cache operations
+#log4j.category.Shibboleth.SessionCache=DEBUG
+# persistent storage and caching
+#log4j.category.XMLTooling.StorageService=DEBUG
+
+# logs XML being signed or verified if set to DEBUG
+log4j.category.XMLTooling.Signature.Debugger=DEBUG, sig_log
+log4j.additivity.XMLTooling.Signature.Debugger=false
+
+# the tran log blocks the "default" appender(s) at runtime
+# Level should be left at DEBUG for this category
+log4j.category.Shibboleth-TRANSACTION=DEBUG, tran_log
+log4j.additivity.Shibboleth-TRANSACTION=false
+# uncomment to suppress particular event types
+#log4j.category.Shibboleth-TRANSACTION.AuthnRequest=WARN
+#log4j.category.Shibboleth-TRANSACTION.Login=WARN
+#log4j.category.Shibboleth-TRANSACTION.Logout=WARN
+
+# define the appenders
+
+log4j.appender.shibd_log=org.apache.log4j.RollingFileAppender
+log4j.appender.shibd_log.fileName=/var/log/shibboleth/shibd.log
+log4j.appender.shibd_log.maxFileSize=1000000
+log4j.appender.shibd_log.maxBackupIndex=10
+log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.shibd_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.warn_log=org.apache.log4j.RollingFileAppender
+log4j.appender.warn_log.fileName=/var/log/shibboleth/shibd_warn.log
+log4j.appender.warn_log.maxFileSize=1000000
+log4j.appender.warn_log.maxBackupIndex=10
+log4j.appender.warn_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.warn_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+log4j.appender.warn_log.threshold=WARN
+
+log4j.appender.tran_log=org.apache.log4j.RollingFileAppender
+log4j.appender.tran_log.fileName=/var/log/shibboleth/transaction.log
+log4j.appender.tran_log.maxFileSize=1000000
+log4j.appender.tran_log.maxBackupIndex=20
+log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.tran_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.sig_log=org.apache.log4j.FileAppender
+log4j.appender.sig_log.fileName=/var/log/shibboleth/signature.log
+log4j.appender.sig_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.sig_log.layout.ConversionPattern=%m
diff --git a/demo/complex2s/grouper_ws/Dockerfile b/demo/complex2s/grouper_ws/Dockerfile
new file mode 100644
index 0000000..ca4cf1a
--- /dev/null
+++ b/demo/complex2s/grouper_ws/Dockerfile
@@ -0,0 +1,9 @@
+FROM tier/grouper:2.4.0-a2-u1-w0-p0
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+COPY container_files/web.xml /opt/grouper/grouper.ws/WEB-INF/
+COPY container_files/tomcat-users.xml /opt/tomcat/conf/
+COPY container_files/server.xml /opt/tomcat/conf/
+
+CMD ["ws"]
diff --git a/demo/complex2s/grouper_ws/container_files/server.xml b/demo/complex2s/grouper_ws/container_files/server.xml
new file mode 100644
index 0000000..112e7d0
--- /dev/null
+++ b/demo/complex2s/grouper_ws/container_files/server.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- Note:  A "Server" is not itself a "Container", so you may not
+     define subcomponents such as "Valves" at this level.
+     Documentation at /docs/config/server.html
+ -->
+<Server port="8005" shutdown="SHUTDOWN">
+  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
+  <!-- Security listener. Documentation at /docs/config/listeners.html
+  <Listener className="org.apache.catalina.security.SecurityListener" />
+  -->
+  <!--APR library loader. Documentation at /docs/apr.html -->
+  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
+  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
+
+  <!-- Global JNDI resources
+       Documentation at /docs/jndi-resources-howto.html
+  -->
+  <GlobalNamingResources>
+    <!-- Editable user database that can also be used by
+         UserDatabaseRealm to authenticate users
+    -->
+    <Resource name="UserDatabase" auth="Container"
+              type="org.apache.catalina.UserDatabase"
+              description="User database that can be updated and saved"
+              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+              pathname="conf/tomcat-users.xml" />
+  </GlobalNamingResources>
+
+  <!-- A "Service" is a collection of one or more "Connectors" that share
+       a single "Container" Note:  A "Service" is not itself a "Container",
+       so you may not define subcomponents such as "Valves" at this level.
+       Documentation at /docs/config/service.html
+   -->
+  <Service name="Catalina">
+
+    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+    <!--
+    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+        maxThreads="150" minSpareThreads="4"/>
+    -->
+
+
+    <!-- A "Connector" represents an endpoint by which requests are received
+         and responses are returned. Documentation at :
+         Java HTTP Connector: /docs/config/http.html
+         Java AJP  Connector: /docs/config/ajp.html
+         APR (HTTP/AJP) Connector: /docs/apr.html
+         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
+    -->
+    <Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
+               connectionTimeout="20000"
+               redirectPort="8443" />
+    <!-- A "Connector" using the shared thread pool-->
+    <!--
+    <Connector executor="tomcatThreadPool"
+               port="8080" protocol="HTTP/1.1"
+               connectionTimeout="20000"
+               redirectPort="8443" />
+    -->
+    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
+         This connector uses the NIO implementation. The default
+         SSLImplementation will depend on the presence of the APR/native
+         library and the useOpenSSL attribute of the
+         AprLifecycleListener.
+         Either JSSE or OpenSSL style configuration may be used regardless of
+         the SSLImplementation selected. JSSE style configuration is used below.
+    -->
+    <!--
+    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
+               maxThreads="150" SSLEnabled="true">
+        <SSLHostConfig>
+            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
+                         type="RSA" />
+        </SSLHostConfig>
+    </Connector>
+    -->
+    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
+         This connector uses the APR/native implementation which always uses
+         OpenSSL for TLS.
+         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
+         configuration is used below.
+    -->
+    <!--
+    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
+               maxThreads="150" SSLEnabled="true" >
+        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
+        <SSLHostConfig>
+            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
+                         certificateFile="conf/localhost-rsa-cert.pem"
+                         certificateChainFile="conf/localhost-rsa-chain.pem"
+                         type="RSA" />
+        </SSLHostConfig>
+    </Connector>
+    -->
+
+    <!-- Define an AJP 1.3 Connector on port 8009 -->
+    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8" />
+
+
+    <!-- An Engine represents the entry point (within Catalina) that processes
+         every request.  The Engine implementation for Tomcat stand alone
+         analyzes the HTTP headers included with the request, and passes them
+         on to the appropriate Host (virtual host).
+         Documentation at /docs/config/engine.html -->
+
+    <!-- You should set jvmRoute to support load-balancing via AJP ie :
+    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+    -->
+    <Engine name="Catalina" defaultHost="localhost">
+
+      <!--For clustering, please take a look at documentation at:
+          /docs/cluster-howto.html  (simple how to)
+          /docs/config/cluster.html (reference documentation) -->
+      <!--
+      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+      -->
+
+      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
+           via a brute-force attack -->
+      <Realm className="org.apache.catalina.realm.LockOutRealm">
+        <!-- This Realm uses the UserDatabase configured in the global JNDI
+             resources under the key "UserDatabase".  Any edits
+             that are performed against this UserDatabase are immediately
+             available for use by the Realm.  -->
+        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+               resourceName="UserDatabase"/> <!-- we can log in with tomcat-users.xml accounts -->
+
+        <Realm className="org.apache.catalina.realm.JNDIRealm"
+               connectionURL="ldap://directory"
+               userBase="ou=people,dc=internet2,dc=edu"
+               userSearch="(uid={0})"
+               userSubtree="true"
+               connectionName="cn=admin,dc=internet2,dc=edu"
+               connectionPassword="password"
+               allRolesMode="authOnly"  /> <!-- Or we can log in with ldap accounts -->
+      </Realm>
+
+      <!-- Define the default virtual host
+           Note: XML Schema validation will not work with Xerces 2.2.
+       -->
+
+      <Host name="localhost"  appBase="webapps"
+            unpackWARs="true" autoDeploy="true">
+
+        <!-- SingleSignOn valve, share authentication between web applications
+             Documentation at: /docs/config/valve.html -->
+        <!--
+        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+        -->
+
+        <!-- Access log processes all example.
+             Documentation at: /docs/config/valve.html
+             Note: The pattern used is equivalent to using pattern="common" -->
+        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+               prefix="localhost_access_log" suffix=".txt"
+               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
+
+      </Host>
+    </Engine>
+  </Service>
+</Server>
diff --git a/demo/complex2s/grouper_ws/container_files/tomcat-users.xml b/demo/complex2s/grouper_ws/container_files/tomcat-users.xml
new file mode 100644
index 0000000..f5d6945
--- /dev/null
+++ b/demo/complex2s/grouper_ws/container_files/tomcat-users.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<tomcat-users xmlns="http://tomcat.apache.org/xml"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
+              version="1.0">
+<role rolename="grouper_user"/>
+<user username="banderson" password="password1" roles="grouper_user"/>
+<!--
+  NOTE:  By default, no user is included in the "manager-gui" role required
+  to operate the "/manager/html" web application.  If you wish to use this app,
+  you must define such a user - the username and password are arbitrary. It is
+  strongly recommended that you do NOT use one of the users in the commented out
+  section below since they are intended for use with the examples web
+  application.
+-->
+<!--
+  NOTE:  The sample user and role entries below are intended for use with the
+  examples web application. They are wrapped in a comment and thus are ignored
+  when reading this file. If you wish to configure these users for use with the
+  examples web application, do not forget to remove the <!.. ..> that surrounds
+  them. You will also need to set the passwords to something appropriate.
+-->
+<!--
+  <role rolename="tomcat"/>
+  <role rolename="role1"/>
+  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
+  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
+  <user username="role1" password="<must-be-changed>" roles="role1"/>
+-->
+</tomcat-users>
\ No newline at end of file
diff --git a/demo/complex2s/grouper_ws/container_files/web.xml b/demo/complex2s/grouper_ws/container_files/web.xml
new file mode 100644
index 0000000..03d3deb
--- /dev/null
+++ b/demo/complex2s/grouper_ws/container_files/web.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+
+<!DOCTYPE web-app PUBLIC 
+          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+          "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+  <filter>
+    <!-- keeps the request and response in threadlocal so they dont have to be passed around -->
+    <filter-name>Grouper service filter</filter-name>
+    <filter-class>edu.internet2.middleware.grouper.ws.GrouperServiceJ2ee</filter-class>
+  </filter>
+
+  <filter>
+    <!-- logging filter -->
+    <filter-name>Grouper logging filter</filter-name>
+    <filter-class>edu.internet2.middleware.grouper.ws.j2ee.ServletFilterLogger</filter-class>
+  </filter>
+
+  <!-- filter-mapping>
+    <filter-name>Grouper logging filter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping -->
+  <!-- Map the filter to a Servlet or URL -->
+  <filter-mapping>
+    <filter-name>Grouper service filter</filter-name>
+    <url-pattern>/services/*</url-pattern>
+  </filter-mapping>
+  <filter-mapping>
+    <filter-name>Grouper service filter</filter-name>
+    <url-pattern>/servicesRest/*</url-pattern>
+  </filter-mapping>
+	<servlet>
+		<servlet-name>AxisServlet</servlet-name>
+		<display-name>Apache-Axis Servlet</display-name>
+		<servlet-class>edu.internet2.middleware.grouper.ws.GrouperServiceAxisServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+    <!-- hint that this is the wssec servlet -->
+    <!-- init-param>
+      <param-name>wssec</param-name>
+      <param-value>true</param-value>
+    </init-param --> 
+	</servlet>
+  <servlet>
+    <servlet-name>RestServlet</servlet-name>
+    <display-name>WS REST Servlet</display-name>
+    <servlet-class>edu.internet2.middleware.grouper.ws.rest.GrouperRestServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet>
+    <servlet-name>StatusServlet</servlet-name>
+    <display-name>Status Servlet</display-name>
+    <servlet-class>edu.internet2.middleware.grouper.j2ee.status.GrouperStatusServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>StatusServlet</servlet-name>
+    <url-pattern>/status</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>AxisServlet</servlet-name>
+    <url-pattern>/services/*</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>RestServlet</servlet-name>
+    <url-pattern>/servicesRest/*</url-pattern>
+  </servlet-mapping>
+
+	<security-constraint>
+		<web-resource-collection>
+			<web-resource-name>Web services</web-resource-name>
+			<url-pattern>/services/*</url-pattern>
+		</web-resource-collection>
+		<auth-constraint>
+			<role-name>*</role-name>
+		</auth-constraint>
+	</security-constraint>
+
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>Web services</web-resource-name>
+      <url-pattern>/servicesRest/*</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+      <!-- NOTE:  This role is not present in the default users file -->
+      <role-name>*</role-name>
+    </auth-constraint>
+  </security-constraint>
+
+	<!-- Define the Login Configuration for this Application -->
+	<login-config>
+		<auth-method>BASIC</auth-method>
+		<realm-name>Grouper Application</realm-name>
+	</login-config>
+
+	<!-- Security roles referenced by this web application -->
+	<security-role>
+		<description>
+			The role that is required to log in to web service
+		</description>
+		<role-name>*</role-name>
+	</security-role>
+  
+  <session-config>
+    <session-timeout>1</session-timeout> 
+  </session-config>
+  <!--  config to enable ESB listener servlet
+  <servlet>
+    <servlet-name>EsbServlet</servlet-name>
+    <display-name>Esb Servlet</display-name>
+    <servlet-class>edu.internet2.middleware.grouper.esb.EsbHttpHandler</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>EsbServlet</servlet-name>
+    <url-pattern>/servicesEsb/*</url-pattern>
+  </servlet-mapping>
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>Web services</web-resource-name>
+      <url-pattern>/servicesEsb/*</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+      <role-name>grouper_user</role-name>
+    </auth-constraint>
+  </security-constraint> -->  
+</web-app>
diff --git a/demo/complex2s/idp/Dockerfile b/demo/complex2s/idp/Dockerfile
new file mode 100644
index 0000000..0f6f508
--- /dev/null
+++ b/demo/complex2s/idp/Dockerfile
@@ -0,0 +1,5 @@
+FROM tier/shib-idp
+
+LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>"
+
+COPY shibboleth-idp/ /opt/shibboleth-idp/
diff --git a/demo/complex2s/idp/shibboleth-idp/conf/attribute-filter.xml b/demo/complex2s/idp/shibboleth-idp/conf/attribute-filter.xml
new file mode 100644
index 0000000..21ffdb8
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/conf/attribute-filter.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    This file is an EXAMPLE policy file.  While the policy presented in this 
+    example file is illustrative of some simple cases, it relies on the names of
+    non-existent example services and the example attributes demonstrated in the
+    default attribute-resolver.xml file.
+    
+    Deployers should refer to the documentation for a complete list of components
+    and their options.
+-->
+<afp:AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
+        xmlns:afp="urn:mace:shibboleth:2.0:afp"
+        xmlns:basic="urn:mace:shibboleth:2.0:afp:mf:basic"
+        xmlns:saml="urn:mace:shibboleth:2.0:afp:mf:saml"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd
+                            urn:mace:shibboleth:2.0:afp:mf:basic http://shibboleth.net/schema/idp/shibboleth-afp-mf-basic.xsd
+                            urn:mace:shibboleth:2.0:afp:mf:saml http://shibboleth.net/schema/idp/shibboleth-afp-mf-saml.xsd">
+
+    <!-- Release some attributes to an SP. -->
+    <afp:AttributeFilterPolicy id="example1">
+        <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://grouperdemo/shibboleth" />
+
+        <afp:AttributeRule attributeID="eduPersonPrincipalName">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+        <afp:AttributeRule attributeID="uid">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+        <afp:AttributeRule attributeID="mail">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+    </afp:AttributeFilterPolicy>
+
+    <afp:AttributeFilterPolicy id="midpoint">
+        <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://midpointdemo/shibboleth" />
+
+        <afp:AttributeRule attributeID="uid">
+            <afp:PermitValueRule xsi:type="basic:ANY" />
+        </afp:AttributeRule>
+
+    </afp:AttributeFilterPolicy>
+
+</afp:AttributeFilterPolicyGroup>
diff --git a/demo/complex2s/idp/shibboleth-idp/conf/attribute-resolver.xml b/demo/complex2s/idp/shibboleth-idp/conf/attribute-resolver.xml
new file mode 100644
index 0000000..ee9519f
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/conf/attribute-resolver.xml
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    This file is an EXAMPLE configuration file containing lots of commented
+    example attributes, encoders, and a couple of example data connectors.
+    
+    Not all attribute definitions or data connectors are demonstrated, but
+    a variety of LDAP attributes, some common to Shibboleth deployments and
+    many not, are included.
+    
+    Deployers should refer to the Shibboleth 2 documentation for a complete
+    list of components  and their options.
+-->
+<resolver:AttributeResolver
+        xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
+        xmlns:pc="urn:mace:shibboleth:2.0:resolver:pc"
+        xmlns:ad="urn:mace:shibboleth:2.0:resolver:ad"
+        xmlns:dc="urn:mace:shibboleth:2.0:resolver:dc"
+        xmlns:enc="urn:mace:shibboleth:2.0:attribute:encoder"
+        xmlns:sec="urn:mace:shibboleth:2.0:security"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd
+                            urn:mace:shibboleth:2.0:resolver:pc http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-pc.xsd
+                            urn:mace:shibboleth:2.0:resolver:ad http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-ad.xsd
+                            urn:mace:shibboleth:2.0:resolver:dc http://shibboleth.net/schema/idp/shibboleth-attribute-resolver-dc.xsd
+                            urn:mace:shibboleth:2.0:attribute:encoder http://shibboleth.net/schema/idp/shibboleth-attribute-encoder.xsd
+                            urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd">
+
+    <!-- ========================================== -->
+    <!--      Attribute Definitions                 -->
+    <!-- ========================================== -->
+
+    <!-- Schema: Core schema attributes-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="uid" sourceAttributeID="uid">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:uid" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.1" friendlyName="uid" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="mail" sourceAttributeID="mail">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mail" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="homePhone" sourceAttributeID="homePhone">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:homePhone" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.20" friendlyName="homePhone" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="homePostalAddress" sourceAttributeID="homePostalAddress">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:homePostalAddress" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.39" friendlyName="homePostalAddress" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="mobileNumber" sourceAttributeID="mobile">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:mobile" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.41" friendlyName="mobile" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="pagerNumber" sourceAttributeID="pager">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:pager" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.42" friendlyName="pager" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="surname" sourceAttributeID="sn">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:sn" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.4" friendlyName="sn" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="locality" sourceAttributeID="l">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:l" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.7" friendlyName="l" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="stateProvince" sourceAttributeID="st">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:st" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.8" friendlyName="st" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="street" sourceAttributeID="street">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:street" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.9" friendlyName="street" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="organizationName" sourceAttributeID="o">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:o" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.10" friendlyName="o" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="organizationalUnit" sourceAttributeID="ou">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:ou" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.11" friendlyName="ou" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="title" sourceAttributeID="title">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:title" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.12" friendlyName="title" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postalAddress" sourceAttributeID="postalAddress">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postalAddress" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.16" friendlyName="postalAddress" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postalCode" sourceAttributeID="postalCode">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postalCode" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.17" friendlyName="postalCode" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="postOfficeBox" sourceAttributeID="postOfficeBox">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:postOfficeBox" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.18" friendlyName="postOfficeBox" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="telephoneNumber" sourceAttributeID="telephoneNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:telephoneNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.20" friendlyName="telephoneNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="givenName" sourceAttributeID="givenName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:givenName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.42" friendlyName="givenName" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="initials" sourceAttributeID="initials">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:initials" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.5.4.43" friendlyName="initials" encodeType="false" />
+    </resolver:AttributeDefinition>
+     -->
+
+    <!-- Schema: inetOrgPerson attributes-->
+    <!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="departmentNumber" sourceAttributeID="departmentNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:departmentNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.2" friendlyName="departmentNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="displayName" sourceAttributeID="displayName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:displayName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.241" friendlyName="displayName" encodeType="false" />
+    </resolver:AttributeDefinition> 
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="employeeNumber" sourceAttributeID="employeeNumber">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeNumber" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.3" friendlyName="employeeNumber" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="employeeType" sourceAttributeID="employeeType">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:employeeType" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.4" friendlyName="employeeType" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="jpegPhoto" sourceAttributeID="jpegPhoto">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:jpegPhoto" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:0.9.2342.19200300.100.1.60" friendlyName="jpegPhoto" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="preferredLanguage" sourceAttributeID="preferredLanguage">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:preferredLanguage" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:2.16.840.1.113730.3.1.39" friendlyName="preferredLanguage" encodeType="false" />
+    </resolver:AttributeDefinition>
+    -->
+
+    <!-- Schema: eduPerson attributes -->
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAffiliation" sourceAttributeID="cn">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" friendlyName="eduPersonAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonEntitlement" sourceAttributeID="eduPersonEntitlement">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonEntitlement" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.7" friendlyName="eduPersonEntitlement" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonNickname" sourceAttributeID="eduPersonNickname">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonNickname" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.2" friendlyName="eduPersonNickname" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonPrimaryAffiliation" sourceAttributeID="eduPersonPrimaryAffiliation">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.5" friendlyName="eduPersonPrimaryAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonUniqueId" scope="%{idp.scope}" sourceAttributeID="localUniqueId">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" friendlyName="eduPersonUniqueId" encodeType="false" />
+    </resolver:AttributeDefinition>
+-->
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonPrincipalName" scope="%{idp.scope}" sourceAttributeID="eduPersonPrincipalName">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonPrincipalName" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" friendlyName="eduPersonPrincipalName" encodeType="false" />
+    </resolver:AttributeDefinition>
+<!--
+    <resolver:AttributeDefinition xsi:type="ad:Prescoped" id="eduPersonPrincipalNamePrior" sourceAttributeID="eduPersonPrincipalNamePrior">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.12" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.12" friendlyName="eduPersonPrincipalNamePrior" encodeType="false" />
+    </resolver:AttributeDefinition>
+
+    <resolver:AttributeDefinition xsi:type="ad:Scoped" id="eduPersonScopedAffiliation" scope="%{idp.scope}" sourceAttributeID="eduPersonAffiliation">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1ScopedString" name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9" friendlyName="eduPersonScopedAffiliation" encodeType="false" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="ad:Simple" id="eduPersonAssurance" sourceAttributeID="eduPersonAssurance">
+        <resolver:Dependency ref="myLDAP" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML1String" name="urn:mace:dir:attribute-def:eduPersonAssurance" encodeType="false" />
+        <resolver:AttributeEncoder xsi:type="enc:SAML2String" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" friendlyName="eduPersonAssurance" encodeType="false" />
+    </resolver:AttributeDefinition>
+    -->
+
+    <!-- ========================================== -->
+    <!--      Data Connectors                       -->
+    <!-- ========================================== -->
+
+    <!-- Example Static Connector -->
+    <!--
+    <resolver:DataConnector id="staticAttributes" xsi:type="dc:Static">
+        <dc:Attribute id="eduPersonAffiliation">
+            <dc:Value>member</dc:Value>
+        </dc:Attribute>
+    </resolver:DataConnector>
+    -->
+
+    <!-- Example Relational Database Connector -->
+    <!--
+    <resolver:DataConnector id="mySIS" xsi:type="dc:RelationalDatabase">
+        <dc:ApplicationManagedConnection jdbcDriver="oracle.jdbc.driver.OracleDriver"
+                                         jdbcURL="jdbc:oracle:thin:@db.example.org:1521:SomeDB" 
+                                         jdbcUserName="myid" 
+                                         jdbcPassword="mypassword" />
+        <dc:QueryTemplate>
+            <![CDATA[
+                SELECT * FROM student WHERE gzbtpid = '$requestContext.principalName'
+            ]]>
+        </dc:QueryTemplate>
+
+        <dc:Column columnName="gzbtpid" attributeID="uid" />
+        <dc:Column columnName="fqlft" attributeID="gpa" />
+    </resolver:DataConnector>
+     -->
+
+    <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
+        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
+        baseDN="%{idp.attribute.resolver.LDAP.baseDN}" 
+        principal="%{idp.attribute.resolver.LDAP.bindDN}"
+        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
+        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}">
+        <dc:FilterTemplate>
+            <![CDATA[
+                %{idp.attribute.resolver.LDAP.searchFilter}
+            ]]>
+        </dc:FilterTemplate>
+        <!--
+        <dc:StartTLSTrustCredential id="LDAPtoIdPCredential" xsi:type="sec:X509ResourceBacked">
+            <sec:Certificate>%{idp.attribute.resolver.LDAP.trustCertificates}</sec:Certificate>
+        </dc:StartTLSTrustCredential>
+    -->
+    </resolver:DataConnector>
+
+</resolver:AttributeResolver>
\ No newline at end of file
diff --git a/demo/complex2s/idp/shibboleth-idp/conf/idp.properties b/demo/complex2s/idp/shibboleth-idp/conf/idp.properties
new file mode 100644
index 0000000..4396f49
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/conf/idp.properties
@@ -0,0 +1,195 @@
+# Load any additional property resources from a comma-delimited list
+idp.additionalProperties= /conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties
+
+# Set the entityID of the IdP
+idp.entityID= https://idptestbed/idp/shibboleth
+
+# Set the scope used in the attribute resolver for scoped attributes
+idp.scope= example.org
+
+# General cookie properties (maxAge only applies to persistent cookies)
+#idp.cookie.secure = false
+#idp.cookie.httpOnly = true
+#idp.cookie.domain =
+#idp.cookie.path =
+#idp.cookie.maxAge = 31536000
+
+# Set the location of user-supplied web flow definitions
+#idp.webflows = %{idp.home}/flows
+
+# Set the location of Velocity view templates
+#idp.views = %{idp.home}/views
+
+# Settings for internal AES encryption key
+#idp.sealer.storeType = JCEKS
+#idp.sealer.updateInterval = PT15M
+#idp.sealer.aliasBase = secret
+idp.sealer.storeResource= %{idp.home}/credentials/sealer.jks
+idp.sealer.versionResource= %{idp.home}/credentials/sealer.kver
+idp.sealer.storePassword= password
+idp.sealer.keyPassword= password
+
+# Settings for public/private signing and encryption key(s)
+# During decryption key rollover, point the ".2" properties at a second
+# keypair, uncomment in credentials.xml, then publish it in your metadata.
+idp.signing.key= %{idp.home}/credentials/idp-signing.key
+idp.signing.cert= %{idp.home}/credentials/idp-signing.crt
+idp.encryption.key= %{idp.home}/credentials/idp-encryption.key
+idp.encryption.cert= %{idp.home}/credentials/idp-encryption.crt
+#idp.encryption.key.2 = %{idp.home}/credentials/idp-encryption-old.key
+#idp.encryption.cert.2 = %{idp.home}/credentials/idp-encryption-old.crt
+
+# Sets the bean ID to use as a default security configuration set
+#idp.security.config = shibboleth.DefaultSecurityConfiguration
+
+# To default to SHA-1, set to shibboleth.SigningConfiguration.SHA1
+#idp.signing.config = shibboleth.SigningConfiguration.SHA256
+
+# Configures trust evaluation of keys used by services at runtime
+# Defaults to supporting both explicit key and PKIX using SAML metadata.
+#idp.trust.signatures = shibboleth.ChainingSignatureTrustEngine
+# To pick only one set to one of:
+#   shibboleth.ExplicitKeySignatureTrustEngine, shibboleth.PKIXSignatureTrustEngine
+#idp.trust.certificates = shibboleth.ChainingX509TrustEngine
+# To pick only one set to one of:
+#   shibboleth.ExplicitKeyX509TrustEngine, shibboleth.PKIXX509TrustEngine
+
+# If true, encryption will happen whenever a key to use can be located, but
+# failure to encrypt won't result in request failure.
+#idp.encryption.optional = false
+
+# Configuration of client- and server-side storage plugins
+#idp.storage.cleanupInterval = PT10M
+#idp.storage.htmlLocalStorage = false
+
+# Set to true to expose more detailed errors in responses to SPs
+#idp.errors.detailed = false
+# Set to false to skip signing of SAML response messages that signal errors
+#idp.errors.signed = true
+# Name of bean containing a list of Java exception classes to ignore
+#idp.errors.excludedExceptions = ExceptionClassListBean
+# Name of bean containing a property set mapping exception names to views
+#idp.errors.exceptionMappings = ExceptionToViewPropertyBean
+# Set if a different default view name for events and exceptions is needed
+#idp.errors.defaultView = error
+
+# Set to false to disable the IdP session layer
+#idp.session.enabled = true
+
+# Set to "shibboleth.StorageService" for server-side storage of user sessions
+#idp.session.StorageService = shibboleth.ClientSessionStorageService
+idp.session.StorageService = shibboleth.StorageService
+
+# Size of session IDs
+#idp.session.idSize = 32
+# Bind sessions to IP addresses
+#idp.session.consistentAddress = true
+# Inactivity timeout
+#idp.session.timeout = PT60M
+# Extra time to store sessions for logout
+#idp.session.slop = PT0S
+# Tolerate storage-related errors
+#idp.session.maskStorageFailure = false
+# Track information about SPs logged into
+#idp.session.trackSPSessions = false
+# Support lookup by SP for SAML logout
+#idp.session.secondaryServiceIndex = false
+# Length of time to track SP sessions
+#idp.session.defaultSPlifetime = PT2H
+
+# Regular expression matching login flows to enable, e.g. IPAddress|Password
+idp.authn.flows= Password
+
+# Regular expression of forced "initial" methods when no session exists,
+# usually in conjunction with the idp.authn.resolveAttribute property below.
+#idp.authn.flows.initial = Password
+
+# Set to an attribute ID to resolve prior to selecting authentication flows;
+# its values are used to filter the flows to allow.
+#idp.authn.resolveAttribute = eduPersonAssurance
+
+# Default lifetime and timeout of various authentication methods
+#idp.authn.defaultLifetime = PT60M
+#idp.authn.defaultTimeout = PT30M
+
+# Whether to prioritize "active" results when an SP requests more than
+# one possible matching login method (V2 behavior was to favor them)
+#idp.authn.favorSSO = true
+
+# Whether to fail requests when a user identity after authentication
+# doesn't match the identity in a pre-existing session.
+#idp.authn.identitySwitchIsError = false
+
+# Set to "shibboleth.StorageService" or custom bean for alternate storage of consent
+#idp.consent.StorageService = shibboleth.ClientPersistentStorageService
+
+# Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute
+# to key user consent storage records (and set the attribute name)
+#idp.consent.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey
+#idp.consent.userStorageKeyAttribute = uid
+
+# Flags controlling how built-in attribute consent feature operates
+#idp.consent.allowDoNotRemember = true
+#idp.consent.allowGlobal = true
+#idp.consent.allowPerAttribute = false
+
+# Whether attribute values and terms of use text are compared
+#idp.consent.compareValues = false
+# Maximum number of consent records for space-limited storage (e.g. cookies)
+#idp.consent.maxStoredRecords = 10
+# Maximum number of consent records for larger/server-side storage (0 = no limit)
+#idp.consent.expandedMaxStoredRecords = 0
+
+# Time in milliseconds to expire consent storage records.
+#idp.consent.storageRecordLifetime = P1Y
+
+# Whether to lookup metadata, etc. for every SP involved in a logout
+# for use by user interface logic; adds overhead so off by default.
+#idp.logout.elaboration = false
+
+# Whether to require logout requests be signed/authenticated.
+#idp.logout.authenticated = true
+
+# Message freshness and replay cache tuning
+#idp.policy.messageLifetime = PT3M
+#idp.policy.clockSkew = PT3M
+
+# Set to custom bean for alternate storage of replay cache
+#idp.replayCache.StorageService = shibboleth.StorageService
+
+# Toggles whether to allow outbound messages via SAML artifact
+#idp.artifact.enabled = true
+# Suppresses typical signing/encryption when artifact binding used
+#idp.artifact.secureChannel = true
+# May differ to direct SAML 2 artifact lookups to specific server nodes
+#idp.artifact.endpointIndex = 2
+# Set to custom bean for alternate storage of artifact map state
+#idp.artifact.StorageService = shibboleth.StorageService
+
+# Name of access control policy for various admin flows
+idp.status.accessPolicy= AccessByIPAddress
+idp.resolvertest.accessPolicy= AccessByIPAddress
+idp.reload.accessPolicy= AccessByIPAddress
+
+# Comma-delimited languages to use if not match can be found with the
+# browser-supported languages, defaults to an empty list.
+idp.ui.fallbackLanguages= en,fr,de
+
+# Storage service used by CAS protocol
+# Defaults to shibboleth.StorageService (in-memory)
+# MUST be server-side storage (e.g. in-memory, memcached, database)
+# NOTE that idp.session.StorageService requires server-side storage
+# when CAS protocol is enabled
+idp.cas.StorageService=shibboleth.StorageService
+
+# CAS service registry implementation class
+#idp.cas.serviceRegistryClass=net.shibboleth.idp.cas.service.PatternServiceRegistry
+
+# Profile flows in which the ProfileRequestContext should be exposed
+# in servlet request under the key "opensamlProfileRequestContext"
+#idp.profile.exposeProfileRequestContextInServletRequest = SAML2/POST/SSO,SAML2/Redirect/SSO
+
+# F-TICKS auditing - set salt to include hashed username
+#idp.fticks.federation=MyFederation
+#idp.fticks.algorithm=SHA-256
+#idp.fticks.salt=somethingsecret
diff --git a/demo/complex2s/idp/shibboleth-idp/conf/ldap.properties b/demo/complex2s/idp/shibboleth-idp/conf/ldap.properties
new file mode 100644
index 0000000..726f145
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/conf/ldap.properties
@@ -0,0 +1,58 @@
+# LDAP authentication configuration, see authn/ldap-authn-config.xml
+
+## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator
+#idp.authn.LDAP.authenticator                   = anonSearchAuthenticator
+
+## Connection properties ##
+idp.authn.LDAP.ldapURL                          = ldap://directory:389
+idp.authn.LDAP.useStartTLS                     = false
+idp.authn.LDAP.useSSL                          = false
+#idp.authn.LDAP.connectTimeout                  = 3000
+
+## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust
+#idp.authn.LDAP.sslConfig                       = certificateTrust
+## If using certificateTrust above, set to the trusted certificate's path
+idp.authn.LDAP.trustCertificates                = %{idp.home}/credentials/ldap-server.crt
+## If using keyStoreTrust above, set to the truststore path
+idp.authn.LDAP.trustStore                       = %{idp.home}/credentials/ldap-server.truststore
+
+## Return attributes during authentication
+## NOTE: this is not used during attribute resolution; configure that directly in the
+## attribute-resolver.xml configuration via a DataConnector's <dc:ReturnAttributes> element
+idp.authn.LDAP.returnAttributes                 = cn,businessCategory,mail
+
+## DN resolution properties ##
+
+# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator
+# for AD: CN=Users,DC=example,DC=org
+idp.authn.LDAP.baseDN                           = ou=people,dc=internet2,dc=edu
+#idp.authn.LDAP.subtreeSearch                   = false
+idp.authn.LDAP.userFilter                       = (uid={user})
+# bind search configuration
+# for AD: idp.authn.LDAP.bindDN=adminuser@domain.com
+idp.authn.LDAP.bindDN                           = cn=admin,dc=internet2,dc=edu
+idp.authn.LDAP.bindDNCredential                 = password
+
+# Format DN resolution, used by directAuthenticator, adAuthenticator
+# for AD use idp.authn.LDAP.dnFormat=%s@domain.com
+idp.authn.LDAP.dnFormat                         = uid=%s,ou=people,dc=internet2,dc=edu
+
+# LDAP attribute configuration, see attribute-resolver.xml
+idp.attribute.resolver.LDAP.ldapURL             = %{idp.authn.LDAP.ldapURL}
+idp.attribute.resolver.LDAP.baseDN              = %{idp.authn.LDAP.baseDN}
+idp.attribute.resolver.LDAP.bindDN              = %{idp.authn.LDAP.bindDN}
+idp.attribute.resolver.LDAP.bindDNCredential    = %{idp.authn.LDAP.bindDNCredential}
+idp.attribute.resolver.LDAP.useStartTLS         = %{idp.authn.LDAP.useStartTLS:true}
+idp.attribute.resolver.LDAP.trustCertificates   = %{idp.authn.LDAP.trustCertificates}
+idp.attribute.resolver.LDAP.searchFilter        = (uid=$requestContext.principalName)
+
+# LDAP pool configuration, used for both authn and DN resolution
+#idp.pool.LDAP.minSize                          = 3
+#idp.pool.LDAP.maxSize                          = 10
+#idp.pool.LDAP.validateOnCheckout               = false
+#idp.pool.LDAP.validatePeriodically             = true
+#idp.pool.LDAP.validatePeriod                   = 300
+#idp.pool.LDAP.prunePeriod                      = 300
+#idp.pool.LDAP.idleTime                         = 600
+#idp.pool.LDAP.blockWaitTime                    = 3000
+#idp.pool.LDAP.failFastInitialize               = false
diff --git a/demo/complex2s/idp/shibboleth-idp/conf/metadata-providers.xml b/demo/complex2s/idp/shibboleth-idp/conf/metadata-providers.xml
new file mode 100644
index 0000000..f70135e
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/conf/metadata-providers.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This file is an EXAMPLE metadata configuration file. -->
+<MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider"
+    xmlns="urn:mace:shibboleth:2.0:metadata"
+    xmlns:resource="urn:mace:shibboleth:2.0:resource"
+    xmlns:security="urn:mace:shibboleth:2.0:security"
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd
+                        urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd 
+                        urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd
+                        urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd">
+                        
+    <!-- ========================================================================================== -->
+    <!--                             Metadata Configuration                                         -->
+    <!--                                                                                            -->
+    <!--  Below you place the mechanisms which define how to load the metadata for the SP you will  -->
+    <!--  provide a service to.                                                                     -->
+    <!--                                                                                            -->
+    <!--  Two examples are provided.  The Shibboleth Documentation at                               -->
+    <!--  https://wiki.shibboleth.net/confluence/display/IDP30/MetadataConfiguration                -->
+    <!--  provides more details.                                                                    --> 
+    <!--                                                                                            -->
+    <!--  NOTE.  This file SHOULD NOT contain the metadata for this IdP.                            -->
+    <!--                                                                                            -->
+    <!-- ========================================================================================== -->
+
+    <MetadataProvider id="GrouperSP"  xsi:type="FilesystemMetadataProvider" metadataFile="%{idp.home}/metadata/grouper-sp.xml"/>
+    <MetadataProvider id="MidpointSP"  xsi:type="FilesystemMetadataProvider" metadataFile="%{idp.home}/metadata/midpoint-sp.xml"/>
+
+    <!-- Example HTTP metadata provider.  Use this if you want to download
+         the metadata from a remote service.
+         
+         You *MUST*  provider the SignatureValidationFilter in order to function securely.
+         Get the PubLic key, and validate it via some out of band mechanism, from the
+         party publishing the metadata
+         
+         The EntityRoleWhiteList saves memory by only loading metadata from entity types
+         that you will interoperate with. 
+    
+    <MetadataProvider id="HTTPMetadata"
+                      xsi:type="FileBackedHTTPMetadataProvider"
+                      backingFile="%{idp.home}/metadata/localCopyFromXYZHTTP.xml"
+                      metadataURL="http://WHATEVER"> 
+        
+        <MetadataFilter xsi:type="SignatureValidation"
+            requireSignedMetadata="false">
+            <PublicKey>
+                THIS IS AN EXAMPLE
+            
+                MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxg0TyQAP/tIvOH89EtaX
+                uRRn8SYzTj7W1TbNY4VvBmobjkRmSkki4hH9x4sQpi635wn6WtXTN/FNNmkTK3N/
+                LspmBWxfZS+n+cc7I82E5yvCAPX67QsZgqgglp2W5dvK/FsMMCS6X6SVqzBLMP88
+                NenXKxY+HMxMs0sT0UKYh1cAEqadrHRBO65aDBcm5a0sBVYt9K6pgaOHrp/zSIbh
+                nR5tFFLjBbtFktDpHL3AdGBH3OYidNGKBO3tJ3Ms7LeKXsM0+0Y4P+9fHZINL2X3
+                E2N6GVnKs5PZTg9sP0FtIpAbYm/+zCx7Yj1ET/Er8mDd6tNVGSQsn9s5xUBwGqn1
+                4wIDAQAB
+            </PublicKey>
+        </MetadataFilter>
+        <MetadataFilter xsi:type="EntityRoleWhiteList">
+            <RetainedRole>md:SPSSODescriptor</RetainedRole>
+        </MetadataFilter>
+        
+    </MetadataProvider>
+    
+    -->   
+
+    <!-- Example file metadata provider.  Use this if you want to load metadata
+         from a local file.  You might use this if you have some local SPs
+         which are not "federated" but you wish to offer a service to.
+         
+         If you do not provide a SignatureValidation filter then you *have*
+         to know that the file is valid.
+         
+
+    <MetadataProvider id="LocalMetadata"  xsi:type="FilesystemMetadataProvider" metadataFile="PATH_TO_YOUR_METADATA"/>
+
+     -->
+          
+    
+</MetadataProvider>
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-backchannel.crt b/demo/complex2s/idp/shibboleth-idp/credentials/idp-backchannel.crt
new file mode 100644
index 0000000..c1f8fab
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/credentials/idp-backchannel.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-backchannel.p12 b/demo/complex2s/idp/shibboleth-idp/credentials/idp-backchannel.p12
new file mode 100644
index 0000000..112540a
Binary files /dev/null and b/demo/complex2s/idp/shibboleth-idp/credentials/idp-backchannel.p12 differ
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-browser.p12 b/demo/complex2s/idp/shibboleth-idp/credentials/idp-browser.p12
new file mode 100644
index 0000000..032be0b
Binary files /dev/null and b/demo/complex2s/idp/shibboleth-idp/credentials/idp-browser.p12 differ
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-encryption.crt b/demo/complex2s/idp/shibboleth-idp/credentials/idp-encryption.crt
new file mode 100644
index 0000000..15d764f
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/credentials/idp-encryption.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-encryption.key b/demo/complex2s/idp/shibboleth-idp/credentials/idp-encryption.key
new file mode 100644
index 0000000..8bb5cc6
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/credentials/idp-encryption.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAgV79KN35k/Ipbsi4yeJQQFQlvmUVchFz2ELkYu73w3DuGund
+ZMYiS7GitFvPFTcYxUEa/D4A5Fq9vL8KB9a4JOKS7LMyw+PAwcw/eNqXiZf0uhZ7
+CCY5mh3AYeKWzYVOMqMLut4ipL7ba3GQBG6RK6OmfAs4lhMfLMsKGmBEBonz5K/T
+kVegp97cavvYDAXjxuNRq7Wa1BiLvsa53S9EoYeD6tHqv/TALFZSCFxGvPVnx/Cd
+pBXEzn6FrSHO9G+0y2ULMeGJzXJ6xi0lBHLLRcjy1/l7b+UjWRfPTjiMV1TYzb4B
+OQ2yW/YTDOFABaiPtW6PUKrccE4Y3P7DryMczQIDAQABAoIBAF/IflMllcUtw/Nb
+9USzpIscQh2nJaugtE5nqER/fT1cfU273Mjh0T6NtFMorjec5WAWBe6/0VVAwb3f
+C4QmO4xDnFhXjLxwAaT6nfvSi+O5d93XCxxLgNZUNL3ET7a2feELyoF+OdQT4sy3
+9dLyMdVHgtnQTQMAAVLeuQoyP+s+Zax4Gca6ln8QxIIvDoD7NITnpl8887Hghhzl
+CvKtRiPRtoI2JTXWgWuLI6xXfVsDvFT+Up+ki9TMLWLACcmMU1d+lUBOKIqhhQHG
++np9iKxVausJwYaLwwT3h8SItNon7ltbV6kcqyZxMAA+uN8CVgIb5UaUrlW7Nvze
+1iUNudkCgYEAxpnBg8YxdEHFSMTqjEOYapn18cs3n32EBPtvPaUcvw3mGC1+ZVx1
+9WqnVsgykBOWI0qSBVF7Kke8yOqgqWtYQUFqLiMgCC9e/QcXnrm/bzAmKDgLVcCR
+KzgqU2ECQDkNSS0qeODjLGX4SEabDbLhN59WykHKM0i/RcrbhuvT1BcCgYEApsMD
+TFQBaiaEmLVm252piZf8b5g3DrUHeqGktHkHXTW4Iyyn8zEknoiCosk/Tej73zga
+cTT3zQgEh63DMC9Ag8IbIJiDpYLMkt1QvZYtq95E/94GVEfRRok6/pyagGYB351R
+PXcykrDyy26FSofmtaXU37Wxaj3ow+WROaPgULsCgYEArFoFScG3a2gkuRlDX8TN
+wj2o5lTxCbWY2+YEzR+8icWbGQJqPbb3G6uaW8LTtpt44Vm2zWzAEZo+KLMOCNmC
+tub5Kd8Lzm6l5brA8dvLWcgUZTT2CU5b7YEJomB+3pNkh0vuHwczv3Ui+j5kE4hY
+0bezT0W3H7iTXhNFXprMs7MCgYEAlIZn75l6URLRUjluzPdVQoktei72CpFNgflp
++ps45dmskRd61mzUkqY+w8G+MiPqANu1IVLtyZz0e+tVRxsuuKsvAg8UYVtn3P5k
+pRaWwtaKWeFjfbkhOVOMSa0tJmK0FHfHHZmGX4ReGrXq3YDBCNQUDtOCmn9dSuyy
+NcYxSXUCgYB+yo6dg8nyHDSqKDdrQQiAKv7jNsbecQ/rYrt8l0n9FBiwn5R7v6kp
+afsimCVou5i06L2Cr5Xs+XSf11KVkDh+qM70ZFubWEsHCDrS1KrxUzfFbrQczKof
+qX7ZsBuOT72RwVEa8fpT6IZ6IpOOEPmUid/f2VM2aAcXgaF//vMjxA==
+-----END RSA PRIVATE KEY-----
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-signing.crt b/demo/complex2s/idp/shibboleth-idp/credentials/idp-signing.crt
new file mode 100644
index 0000000..6a032c1
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/credentials/idp-signing.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/idp-signing.key b/demo/complex2s/idp/shibboleth-idp/credentials/idp-signing.key
new file mode 100644
index 0000000..011c27c
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/credentials/idp-signing.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7gu6eo4dua
+eLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2Z6dzJsul
+JZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJCb/Q6dYz
+RWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+MNkv6aId
+cHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBsuYlY7lEr
+89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABAoIBAGpInLarQ0+X+ZXK
++aoC+tNO9DUiHq/z2OD4ALGhXSTvr4mgBWNWTkc0F+qJD8MlM8zNkJxaoNGTyLjY
+Z95NQJPXAx2k15HwCENdulvV1oiX0dkTjgmscRmj6FwNAZ0EnWtien45mxZHxEyW
+FkbB9+OHc6JzNvzG9ps1Vk1FtFtO8w4exXuJVATJeArQmMvAUHMJYPb7Qs+/NX9R
+RlDvFfXDzQv5eAzudT1SyFSa5W+Bsw6BtEoeiqdp+xQh4yc733nwN7KG2Z/TpGse
+jVe6akbULuCXOe9uPa7kv8hnQEUH38QVlIw8pK1SsgNq7S0U44WU5uF8gbDBYle/
+OoPBvSECgYEAvCwVEa8ryLzee5FaX4PBxk10lEl/Yp9jC88wPUQ+ZpfniIIQIfwl
+csRE9D3/dJOVAxw/Ac32F72SLVDzLabAhlBRINYLB0ZkVuJi1CIoDHIf9nfh/pOx
+b96VMUe/mpAL4hZnZkmBKjesX5URPEKtBD0aSeCw9aFqhORjRrxCJg0CgYEAuNaD
+LOuTPKsC6nxRtiL9r0CA5gCCdpALxwJA7wHAeh03i5xmy61i4iOMaunxKZhG+nzz
+PhcI8Uhwwk+l3tbYAf1rrtmMKNcyjy+UqWXGt4ZkWFlIyIungyLiH9L32IMhXNF0
+fBgOZNtFTmQBU18a78uIir9xASUbtaakzOtJ2+cCgYAgfawVpZ11x8bSp0Jng6SN
+zQn4IMiyCrtbaqb1rTbpGAmOdIa8l4EP0/vkAGB/jIwKQXJPqXR4nO8EjBmxJD3R
+80RO2yaEVw80QVq3Lj6kB4ClWgXXo0DcBB7Wp4DZ+01R+HRaIQ8AbySATIjxUsH1
+HWfQoc9sWja+Q4Ew0YjKcQKBgGLoPsdBw8b6B5RsM9lPvgoSbScmbKl/CR5TwWVj
+vZhanAd0CLnCrSAvP4tSZf8JAio1xH+cGefrCJOhxTOKKYpfDklBFjQge2iNYHKJ
+CJ3aJ0XzePP/bwLIHtJCtOdBvA+L8VYaFVG418xLzT3MrYBVnFoKeTDQp5Q7eQJC
+gYJPAoGBAKHcuXWzvXoHKnOg8Ljg2xZ6/SfjwNDIIrpXVTAQifmK3q4+Ua2Q+Cjq
+97tPMxF2bVRcbnCSNKpTMOTrsWs8Z3GpMyCh6XgYMSlclXusDVUkRkPpWj8hVTR4
+opm/rxS83hCrTsIX3Il3T8Fpb97kdF+unCiWEaxrPEurjW8lB506
+-----END RSA PRIVATE KEY-----
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/sealer.jks b/demo/complex2s/idp/shibboleth-idp/credentials/sealer.jks
new file mode 100644
index 0000000..89957e0
Binary files /dev/null and b/demo/complex2s/idp/shibboleth-idp/credentials/sealer.jks differ
diff --git a/demo/complex2s/idp/shibboleth-idp/credentials/sealer.kver b/demo/complex2s/idp/shibboleth-idp/credentials/sealer.kver
new file mode 100644
index 0000000..d64b0e4
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/credentials/sealer.kver
@@ -0,0 +1,2 @@
+#Fri Dec 11 02:20:32 UTC 2015
+CurrentVersion=1
diff --git a/demo/complex2s/idp/shibboleth-idp/metadata/grouper-sp.xml b/demo/complex2s/idp/shibboleth-idp/metadata/grouper-sp.xml
new file mode 100644
index 0000000..5b42a7b
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/metadata/grouper-sp.xml
@@ -0,0 +1,78 @@
+<!--
+This is example metadata only. Do *NOT* supply it as is without review,
+and do *NOT* provide it in real time to your partners.
+ -->
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_57114916ca68943103854cb57a3a3b1c7c38bb81" entityID="https://grouperdemo/shibboleth">
+
+  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+  </md:Extensions>
+
+  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://localhost:4443/Shibboleth.sso/Login"/>
+      <idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://localhost:4443/Shibboleth.sso/Login" index="1"/>
+    </md:Extensions>
+    <md:KeyDescriptor>
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:KeyName>sp.example.org</ds:KeyName>
+        <ds:X509Data>
+          <ds:X509SubjectName>CN=sp.example.org,O=Internet2/TIER,L=Ann Arbor,ST=MI,C=US</ds:X509SubjectName>
+          <ds:X509Certificate>MIIDPDCCAiQCCQDNZe8r0hVtuTANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxFzAVBgNVBAMMDnNwLmV4YW1wbGUub3JnMB4XDTE3MDkyMjE5
+NTAzNVoXDTI3MDkyMDE5NTAzNVowYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1J
+MRIwEAYDVQQHDAlBbm4gQXJib3IxFzAVBgNVBAoMDkludGVybmV0Mi9USUVSMRcw
+FQYDVQQDDA5zcC5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMTNJmsNpTpR4NrDJwOgK/o3UYlNdi1c6xBflt+liLAsQc160QReV4dS
+SGK8LZvN58a/BTIsH8dLhQlUQ8qQUY2AfolVrNxb7Waumeh/POzYUTRylnoGpU3W
+bGMEPxE/AdgP5U/adYvyu4XI5epv7wjZJOTqcVag15SalY+aso+ZC/5l+UzRxmWB
+ZxKTsSL1y7PFehY4/Zl3Y3oGVsVl/zspt5lteoZQeeVxUX29S3Af11yHY4xpEp+7
+rvAzY/nlsTiHAsUoCFK/NFQ2evvSRx52B9Fk1cWP1MDVDm2QjQqD9xBGYSnX6bhQ
+ejVx7JUJHlblu2Q5p5XdW0BihgFluoECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+n/qhYnIviPs4tglCdrw+M7gbqKNWadDC3F9HDYzlJMFeS/ae2turhEUgQPbYPDQQ
+eO3oOILtvCXNFUPM58jf8V5YFRrOqrTgx44kexQDaHO5YYNft5tF5TdvBYE2gOVr
+GdYrH2iSP8WX+Yy7JH5uqkfwWzEntWHJdey39rCWKAUCCB35+/2b4N53Qmlv2+ug
+CpNJYFtXInd4YMmM5HjXLyoWXtjnKiwDqYUCeYPSwAajnCqRqRXUX0gYTFDRiwRP
+HbmO9We0nqoc/71nikmGGoSRMO/zWVMFjwmAx1fGiWdU61sjGX8sHifzmVyJVEBI
+Z75p+JrWYZJYrx/vpWxL8g==
+</ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
+    </md:KeyDescriptor>
+    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:4443/Shibboleth.sso/Artifact/SOAP" index="1"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:4443/Shibboleth.sso/SLO/SOAP"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:4443/Shibboleth.sso/SLO/Redirect"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:4443/Shibboleth.sso/SLO/POST"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:4443/Shibboleth.sso/SLO/Artifact"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:4443/Shibboleth.sso/SAML2/POST" index="1"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost:4443/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:4443/Shibboleth.sso/SAML2/Artifact" index="3"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://localhost:4443/Shibboleth.sso/SAML2/ECP" index="4"/>
+  </md:SPSSODescriptor>
+
+</md:EntityDescriptor>
diff --git a/demo/complex2s/idp/shibboleth-idp/metadata/idp-metadata.xml b/demo/complex2s/idp/shibboleth-idp/metadata/idp-metadata.xml
new file mode 100644
index 0000000..84266d4
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/metadata/idp-metadata.xml
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     This is example metadata only. Do *NOT* supply it as is without review,
+     and do *NOT* provide it in real time to your partners.
+
+     This metadata is not dynamic - it will not change as your configuration changes.
+-->
+<EntityDescriptor  xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" entityID="https://idptestbed/idp/shibboleth">
+
+    <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">example.org</shibmd:Scope>
+<!--
+    Fill in the details for your IdP here 
+
+            <mdui:UIInfo>
+                <mdui:DisplayName xml:lang="en">A Name for the IdP at idptestbed</mdui:DisplayName>
+                <mdui:Description xml:lang="en">Enter a description of your IdP at idptestbed</mdui:Description>
+                <mdui:Logo height="80" width="80">https://localhost/Path/To/Logo.png</mdui:Logo>
+            </mdui:UIInfo>
+-->
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
+        <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+
+        <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://localhost/idp/profile/Shibboleth/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+        <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+
+    </IDPSSODescriptor>
+
+
+    <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+
+        <Extensions>
+            <shibmd:Scope regexp="false">localhost</shibmd:Scope>
+        </Extensions>
+
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUS9SuTXwsFVVG+LjOEAbLqqT/el0wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMjZaFw0zNTEy
+MTEwMjIwMjZaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCMAoDHx8xCIfv/6QKqt9mcHYmEJ8y2dKprUbpdcOjH
+YvNPIl/lHPsUyrb+Nc+q2CDeiWjVk1mWYq0UpIwpBMuw1H6+oOqr4VQRi65pin0M
+SfE0MWIaFo5FPvpvoptkHD4gvREbm4swyXGMczcMRfqgalFXhUD2wz8W3XAM5Cq2
+03XeJbj6TwjvKatG5XPdeUe2FBGuOO2q54L1hcIGnLMCQrg7D31lR13PJbjnJ0No
+5C3k8TPuny6vJsBC03GNLNKfmrKVTdzr3VKp1uay1G3DL9314fgmbl8HA5iRQmy+
+XInUU6/8NXZSF59p3ITAOvZQeZsbJjg5gGDip5OZo9YlAgMBAAGjWzBZMB0GA1Ud
+DgQWBBRPlM4VkKZ0U4ec9GrIhFQl0hNbLDA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAIZ0a1ov3my3ljJG588I/PHx+TxAWONWmpKbO9c/qI3Drxk4oRIffiac
+ANxdvtabgIzrlk5gMMisD7oyqHJiWgKv5Bgctd8w3IS3lLl7wHX65mTKQRXniG98
+NIjkvfrhe2eeJxecOqnDI8GOhIGCIqZUn8ShdM/yHjhQ2Mh0Hj3U0LlKvnmfGSQl
+j0viGwbFCaNaIP3zc5UmCrdE5h8sWL3Fu7ILKM9RyFa2ILHrJScV9t623IcHffHP
+IeaY/WtuapsrqRFxuQL9QFWN0FsRIdLmjTq+00+B/XnnKRKFBuWfjhHLF/uu8f+E
+t6Lf23Kb8yD6ZR7dihMZAGHnYQ/hlhM=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="signing">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDFDCCAfygAwIBAgIVAN3vv+b7KN5Se9m1RZsCllp/B/hdMA0GCSqGSIb3DQEB
+CwUAMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwHhcNMTUxMjExMDIyMDE0WhcNMzUx
+MjExMDIyMDE0WjAVMRMwEQYDVQQDDAppZHB0ZXN0YmVkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAh91caeY0Q85uhaUyqFwP2bMjwMFxMzRlAoqBHd7g
+u6eo4duaeLz1BaoR2XTBpNNvFR5oHH+TkKahVDGeH5+kcnIpxI8JPdsZml1srvf2
+Z6dzJsulJZUdpqnngycTkGtZgEoC1vmYVky2BSAIIifmdh6s0epbHnMGLsHzMKfJ
+Cb/Q6dYzRWTCPtzE2VMuQqqWgeyMr7u14x/Vqr9RPEFsgY8GIu5jzB6AyUIwrLg+
+MNkv6aIdcHwxYTGL7ijfy6rSWrgBflQoYRYNEnseK0ZHgJahz4ovCag6wZAoPpBs
+uYlY7lEr89Ucb6NHx3uqGMsXlDFdE4QwfDLLhCYHPvJ0uwIDAQABo1swWTAdBgNV
+HQ4EFgQUAkOgED3iYdmvQEOMm6u/JmD/UTQwOAYDVR0RBDEwL4IKaWRwdGVzdGJl
+ZIYhaHR0cHM6Ly9pZHB0ZXN0YmVkL2lkcC9zaGliYm9sZXRoMA0GCSqGSIb3DQEB
+CwUAA4IBAQBIdd4YWlnvJjql8+zKKgmWgIY7U8DA8e6QcbAf8f8cdE33RSnjI63X
+sv/y9GfmbAVAD6RIAXPFFeRYJ08GOxGI9axfNaKdlsklJ9bk4ducHqgCSWYVer3s
+RQBjxyOfSTvk9YCJvdJVQRJLcCvxwKakFCsOSnV3t9OvN86Ak+fKPVB5j2fM/0fZ
+Kqjn3iqgdNPTLXPsuJLJO5lITRiBa4onmVelAiCstI9PQiaEck+oAHnMTnC9JE/B
+DHv3e4rwq3LznlqPw0GSd7xqNTdMDwNOWjkuOr3sGpWS8ms/ZHHXV1Vd22uPe70i
+s00xrv14zLifcc8oj5DYzOhYRifRXgHX
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+        <KeyDescriptor use="encryption">
+            <ds:KeyInfo>
+                    <ds:X509Data>
+                        <ds:X509Certificate>
+MIIDEzCCAfugAwIBAgIUG6Nn1rlERS1vsi88tcdzSYX0oqAwDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UEAwwKaWRwdGVzdGJlZDAeFw0xNTEyMTEwMjIwMTRaFw0zNTEy
+MTEwMjIwMTRaMBUxEzARBgNVBAMMCmlkcHRlc3RiZWQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCBXv0o3fmT8iluyLjJ4lBAVCW+ZRVyEXPYQuRi7vfD
+cO4a6d1kxiJLsaK0W88VNxjFQRr8PgDkWr28vwoH1rgk4pLsszLD48DBzD942peJ
+l/S6FnsIJjmaHcBh4pbNhU4yowu63iKkvttrcZAEbpEro6Z8CziWEx8sywoaYEQG
+ifPkr9ORV6Cn3txq+9gMBePG41GrtZrUGIu+xrndL0Shh4Pq0eq/9MAsVlIIXEa8
+9WfH8J2kFcTOfoWtIc70b7TLZQsx4YnNcnrGLSUEcstFyPLX+Xtv5SNZF89OOIxX
+VNjNvgE5DbJb9hMM4UAFqI+1bo9QqtxwThjc/sOvIxzNAgMBAAGjWzBZMB0GA1Ud
+DgQWBBStTyogRPuAVG6q7yPyav1uvE+7pTA4BgNVHREEMTAvggppZHB0ZXN0YmVk
+hiFodHRwczovL2lkcHRlc3RiZWQvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQEL
+BQADggEBAFMfoOv+oISGjvamq7+Y4G7ep5vxlAPeK3RATYPYvAmyH946qZXh98ni
+QXyuqZW5P5eEt86toY45IwDU5r09SKwHughEe99iiEkxh0mb2qo84qX9/qcg+kyN
+jeLd/OSyolpUCEFNwOFcog7pj7Eer+6AHbwTn1Mjb5TBsKwtDMJsaxPvdj0u7M5r
+xL/wHkFhn1rCo2QiojzjSlV3yLTh49iTyhE3cG+RxaNKDCxhp0jSSLX1BW/ZoPA8
++PMJEA+Q0QbyRD8aJOHN5O8jGxCa/ZzcOnYVL6AsEXoDiY3vAUYh1FUonOWw0m9H
+p+tGUbGS2l873J5PrsbpeKEVR/IIoKo=
+                        </ds:X509Certificate>
+                    </ds:X509Data>
+            </ds:KeyInfo>
+
+        </KeyDescriptor>
+
+        <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://localhost/idp/profile/SAML1/SOAP/AttributeQuery"/>
+        <AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/AttributeQuery"/> 
+        <!-- If you uncomment the above you should add urn:oasis:names:tc:SAML:2.0:protocol to the protocolSupportEnumeration above -->
+
+    </AttributeAuthorityDescriptor>
+
+</EntityDescriptor>
diff --git a/demo/complex2s/idp/shibboleth-idp/metadata/midpoint-sp-new.xml b/demo/complex2s/idp/shibboleth-idp/metadata/midpoint-sp-new.xml
new file mode 100644
index 0000000..a819f4b
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/metadata/midpoint-sp-new.xml
@@ -0,0 +1,37 @@
+<EntityDescriptor entityID="https://midpointdemo/idp/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+  <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <Extensions>
+      <shibmd:Scope regexp="false">midpointdemo</shibmd:Scope>
+    </Extensions>
+    <KeyDescriptor use="signing">
+      <ds:KeyInfo>
+        <ds:X509Data>
+          <ds:X509Certificate>
+MIIDHDCCAgSgAwIBAgIJAPEnL5jgbeVoMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
+BAMMD2lkcC5leGFtcGxlLmVkdTAeFw0xODEwMTAyMDM1NDBaFw0yMzEwMDkyMDM1
+NDBaMBoxGDAWBgNVBAMMD2lkcC5leGFtcGxlLmVkdTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKwTrvQhmFX3SUNgJAhQ/YV0UX56Rt53mwbiKuH+Ez83
+7z6XRynBVsfzHfbWe0IpNKx5mIr84dfbGhQKQBEKzQuek7ihW3J6PIVZN1A3icZZ
+B9i7gow902bT0ZfRG8QW49gl7pk3ASutPcO9Dq5Xc/AqWr3OSO/Pei0yBtTdzG3b
+rm0u0gbj3P2tjt7BN77wIB+yjJsND3ITtP0MFXIJxLTlty8thwqQOAOAYcF+rhC5
+znnBLsRNo0E57PtzZs8i/BpEX2uPTxpEyvlU1vtyxcKUiHtK5ZjOsDEkS2rEualr
++FILYg/Oxw1gi0+mNO1a94Ft+UoLiREztq6MQt8OK98CAwEAAaNlMGMwQgYDVR0R
+BDswOYIPaWRwLmV4YW1wbGUuZWR1hiZodHRwczovL2lkcC5leGFtcGxlLmVkdS9p
+ZHAvc2hpYmJvbGV0aDAdBgNVHQ4EFgQU3ZJ8oHkmlgPtZuZAxnzONccPsb8wDQYJ
+KoZIhvcNAQELBQADggEBAIJ4oZKSMGpF8J3qdfjLZGkc3iVbu/eiE1MD77no0oCz
+nelY0CNUBuFJk1Xv+Bv0fW0cVugtMPz4xi7zv0zkpS2IVxpPZWBosuVabUD9k+V4
+iN5woJdO7e2KRGvhlWmbkmoZUvhygDe0u0vblNfLzDwFQvxHXiWG//P7SanoQrjP
+dE8U21tYz+EFm6s5TvHxVhr9id8c+UacAFCpAtzUB+J8K1abx05XlKsySflkOQV9
+JbM4zOy5gXSI5dY9dGUF77g0muyC+jAhIhLSt/7v3vJgvBurrxPoeBFXOU3D+siT
+VZlKtYzYjJhVqXx1vKrWEE1hkpqm+iYgZe4MvgcdswY=
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </KeyDescriptor>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost/idp/profile/SAML2/Redirect/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost/idp/profile/SAML2/POST/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost/idp/profile/SAML2/POST-SimpleSign/SSO"/>
+    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost/idp/profile/SAML2/SOAP/ECP"/>
+  </IDPSSODescriptor>
+</EntityDescriptor>
+
diff --git a/demo/complex2s/idp/shibboleth-idp/metadata/midpoint-sp.xml b/demo/complex2s/idp/shibboleth-idp/metadata/midpoint-sp.xml
new file mode 100644
index 0000000..54f0577
--- /dev/null
+++ b/demo/complex2s/idp/shibboleth-idp/metadata/midpoint-sp.xml
@@ -0,0 +1,80 @@
+<!--
+This is example metadata only. Do *NOT* supply it as is without review,
+and do *NOT* provide it in real time to your partners.
+ -->
+<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_57114916ca68943103854cb57a3a3b1c7c38bb81" entityID="https://midpointdemo/shibboleth">
+
+  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
+    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
+  </md:Extensions>
+
+  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://localhost:8443/Shibboleth.sso/Login"/>
+      <idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://localhost:8443/Shibboleth.sso/Login" index="1"/>
+    </md:Extensions>
+    <md:KeyDescriptor>
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:KeyName>midpoint.sp.example.org</ds:KeyName>
+        <ds:X509Data>
+          <ds:X509SubjectName>CN=midpoint.sp.example.org,O=Internet2/TIER,L=Ann Arbor,ST=MI,C=US</ds:X509SubjectName>
+          <ds:X509Certificate>MIIDqDCCApCgAwIBAgIJAKUZrfriIt9cMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXZXZvbHZldW0uc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU0NjU3WhcNMTkwOTE0MDU0NjU3WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF2V2b2x2ZXVtLnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw5v1zxlM94yaBssgNNbIUJwW
+XxbGxgSs2AWBeg2aEi/VQd2UE5ivZakNJlqWSJyHo2xE4kxeSyBBxinjSyhmpNao
+xIcqQsgW0gxo4SEHo3kUXWPo+of/pj6CslutsSJZWGTRV0dHITvaWX+NM8eXMfgu
+mJFwy3RMdLaWQhY1Dyi2jNoO+DZnfNgPyPeEZcmORaoeEID9QdZfHtcgTf2QfSHq
++xsTwHB6Ro5t7YD2ma8Krb/XcDTfsq3qJemd7LhPj5lGmhYSMgDbgwEkZgZ1kBOP
+lfsP2BvX5nipv7Vd1C5YXmv+NDR8V3yAWBC7ZAenxGmrnkaSVXnpUplUsGGm1QID
+AQABo1MwUTAdBgNVHQ4EFgQUuxSZwW6V1P/b0tsTM32OU/v/n+UwHwYDVR0jBBgw
+FoAUuxSZwW6V1P/b0tsTM32OU/v/n+UwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAJWLXEfZkPeUyiGvsIUjczzdF3ptqXoP9aETS2pOV9sTri19R
+TsQZW6XQRHGtuEOsqEGH8yiTdGR5hbGC+ynH/xTJnK+tBn/R3KrgxLKyMvoUzAPl
+mhVq1dh+ZEtbsRpQRRubP6nm9kXNma0cXrkJSzuWM0W+l/xSOOYiSRRk3XWJfVjn
+9jQlcJRh5SOkKN08oZHrCYKxToEuOfV8PtRj3T80DhsBTv2SHqhg4cBhzQPb0Kjm
+9m4IkYOz8c5ZtuHDGnqMHw60Nyt+jyik4mMFP2frcOVP0W0sgwcfHllYzHoA/Khq
+Yk3TBVs1BjPuNDJWHct8Eo68YP2/ZvzqfVM87Q==
+</ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
+      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
+    </md:KeyDescriptor>
+    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:8443/Shibboleth.sso/Artifact/SOAP" index="1"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://localhost:8443/Shibboleth.sso/SLO/SOAP"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:8443/Shibboleth.sso/SLO/Redirect"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:8443/Shibboleth.sso/SLO/POST"/>
+    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:8443/Shibboleth.sso/SLO/Artifact"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:8443/Shibboleth.sso/SAML2/POST" index="1"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://localhost:8443/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://localhost:8443/Shibboleth.sso/SAML2/Artifact" index="3"/>
+    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://localhost:8443/Shibboleth.sso/SAML2/ECP" index="4"/>
+  </md:SPSSODescriptor>
+
+</md:EntityDescriptor>
diff --git a/demo/complex2s/midpoint-objects-manual/tasks/task-async-update-grouper.xml b/demo/complex2s/midpoint-objects-manual/tasks/task-async-update-grouper.xml
new file mode 100644
index 0000000..750ddc5
--- /dev/null
+++ b/demo/complex2s/midpoint-objects-manual/tasks/task-async-update-grouper.xml
@@ -0,0 +1,43 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="47fc57bd-8c34-4555-9b9f-7087ff179860">
+	<name>Grouper async updates</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<!-- ... -->
+	</extension>
+	<taskIdentifier>1552664339630-0-2</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>AsynchronousUpdate</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/async-update/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex2s/midpoint-objects-manual/tasks/task-import-sis-persons.xml b/demo/complex2s/midpoint-objects-manual/tasks/task-import-sis-persons.xml
new file mode 100644
index 0000000..ebeb5df
--- /dev/null
+++ b/demo/complex2s/midpoint-objects-manual/tasks/task-import-sis-persons.xml
@@ -0,0 +1,31 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+      oid="22c2a3d0-0961-4255-9eec-c550a79aeaaa">
+   <name>Import from SIS persons</name>
+   <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:type="c:ExtensionType">
+      <mext:kind>account</mext:kind>
+      <mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+      <mext:tracing>
+          <interval>500</interval>
+      </mext:tracing>
+   </extension>
+   <taskIdentifier>1535407239440-0-1</taskIdentifier>
+   <ownerRef oid="00000000-0000-0000-0000-000000000002"
+             relation="org:default"
+             type="c:UserType"><!-- administrator --></ownerRef>
+   <executionStatus>runnable</executionStatus>
+   <category>ImportingAccounts</category>
+   <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/import/handler-3</handlerUri>
+   <objectRef oid="4d70a0da-02dd-41cf-b0a1-00e75d3eaa15"
+              relation="org:default"
+              type="c:ResourceType"><!-- SQL SIS persons (sources) --></objectRef>
+   <recurrence>single</recurrence>
+   <binding>loose</binding>
+</task>
diff --git a/demo/complex2s/midpoint-objects-manual/tasks/task-recomputation-users.xml b/demo/complex2s/midpoint-objects-manual/tasks/task-recomputation-users.xml
new file mode 100644
index 0000000..08bcc01
--- /dev/null
+++ b/demo/complex2s/midpoint-objects-manual/tasks/task-recomputation-users.xml
@@ -0,0 +1,25 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" oid="83a737ea-5eb7-4e78-b431-331cccf02354">
+    <name>User recomputing with bucket</name>
+    <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xsi:type="c:ExtensionType">
+        <mext:objectType>c:UserType</mext:objectType>
+        <mext:tracingInterval>200</mext:tracingInterval>
+    </extension>
+    <taskIdentifier>1571729899646-0-1</taskIdentifier>
+    <ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+        <!-- administrator -->
+    </ownerRef>
+    <channel>http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#recompute</channel>
+    <executionStatus>runnable</executionStatus>
+    <category>Recomputation</category>
+    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/recompute/handler-3</handlerUri>
+    <workManagement>
+        <taskKind>standalone</taskKind>
+        <buckets>
+            <oidSegmentation>
+                <depth>2</depth>
+            </oidSegmentation>
+        </buckets>
+    </workManagement>
+    <recurrence>single</recurrence>
+    <binding>tight</binding>
+</task>
diff --git a/demo/complex2s/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml b/demo/complex2s/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
new file mode 100644
index 0000000..b59f5d7
--- /dev/null
+++ b/demo/complex2s/midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
@@ -0,0 +1,43 @@
+<!--
+  ~ Copyright (c) 2010-2019 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+	  xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  oid="605a0127-a313-442a-9d5e-151eac8b0745">
+	<name>Grouper reconciliation (groups)</name>
+	<extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c:ExtensionType">
+		<mext:objectclass>ri:CustomPlainGroupObjectClass</mext:objectclass>
+	</extension>
+	<taskIdentifier>605a0127-a313-442a-9d5e-151eac8b0745</taskIdentifier>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
+		<!-- administrator -->
+	</ownerRef>
+	<executionStatus>runnable</executionStatus>
+	<category>Reconciliation</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/reconciliation/handler-3</handlerUri>
+	<objectRef oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233" relation="org:default" type="c:ResourceType">
+		<!-- Grouper Resource -->
+	</objectRef>
+	<recurrence>single</recurrence>
+	<binding>loose</binding>
+	<threadStopAction>restart</threadStopAction>
+</task>
diff --git a/demo/complex2s/midpoint-objects/archetypes/archetype-affiliation.xml b/demo/complex2s/midpoint-objects/archetypes/archetype-affiliation.xml
new file mode 100644
index 0000000..0064575
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/archetypes/archetype-affiliation.xml
@@ -0,0 +1,42 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="56f53812-047d-4b69-83e8-519a73d161e1">
+    <name>affiliation</name>
+    <extension>
+        <ext:grouperNamePrefix>ref:affiliation:</ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=Affiliations,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+        <ext:midPointNamePrefix>affiliation_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Affiliation: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="1d7c0e3a-4456-409c-9f50-95407b2eb785" relation="org:default" type="c:OrgType" />     <!-- affiliations -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <resourceRef oid="e417225d-8a08-46f3-9b5d-624990b52386" relation="org:default" type="c:ResourceType" />     <!-- Faculty CSV -->
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier == 'faculty'</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</archetype>
diff --git a/demo/complex2s/midpoint-objects/archetypes/archetype-course.xml b/demo/complex2s/midpoint-objects/archetypes/archetype-course.xml
new file mode 100644
index 0000000..5a906e1
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/archetypes/archetype-course.xml
@@ -0,0 +1,54 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="3dab9a72-118b-4e40-a138-bb691c335eca">
+    <name>course</name>
+    <extension>
+        <ext:grouperNamePrefix>ref:course:</ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=Courses,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+        <ext:midPointNamePrefix>course_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Course: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="225e9360-0639-40ba-8a31-7f31bef067be" relation="org:default" type="c:OrgType" />     <!-- courses -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <strength>weak</strength>
+            <resourceRef oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" relation="org:default" type="c:ResourceType" />     <!-- CS CSV -->
+            <attribute>
+                <c:ref>ri:courses</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+        <condition>
+            <expression>
+                <script>
+                    <code>assignmentPath[0].target.identifier?.startsWith('CS')</code>
+                </script>
+            </expression>
+        </condition>
+    </inducement>
+</archetype>
diff --git a/demo/complex2s/midpoint-objects/archetypes/archetype-department.xml b/demo/complex2s/midpoint-objects/archetypes/archetype-department.xml
new file mode 100644
index 0000000..c8cf8b4
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/archetypes/archetype-department.xml
@@ -0,0 +1,43 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="1cec5f78-8fba-459b-9547-ef7485009f40">
+    <name>department</name>
+    <extension>
+        <ext:grouperNamePrefix>ref:dept:</ext:grouperNamePrefix>
+        <ext:midPointNamePrefix>department_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Department: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <!--  No LDAP metarole here: we deal with LDAP ourselves -->
+    <inducement>
+        <targetRef oid="bee44c51-2469-411d-bac7-695728e9c241" relation="org:default" type="c:OrgType" />     <!-- departments -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- LDAP -->
+            <attribute>
+                <ref>ri:businessCategory</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</archetype>
diff --git a/demo/complex2s/midpoint-objects/archetypes/archetype-generic-grouper-group.xml b/demo/complex2s/midpoint-objects/archetypes/archetype-generic-grouper-group.xml
new file mode 100644
index 0000000..08b09d6
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/archetypes/archetype-generic-grouper-group.xml
@@ -0,0 +1,30 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="5f2b96d2-49b5-4a8a-9601-14457309a69b">
+    <name>generic-grouper-group</name>
+    <extension>
+        <ext:grouperNamePrefix></ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=generic,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+        <ext:midPointNamePrefix>generic_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix></ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d" relation="org:default" type="c:OrgType" />     <!-- generic-groups -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <!--  nothing here by now -->
+</archetype>
diff --git a/demo/complex2s/midpoint-objects/archetypes/archetype-mailing-list.xml b/demo/complex2s/midpoint-objects/archetypes/archetype-mailing-list.xml
new file mode 100644
index 0000000..c5ed3a8
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/archetypes/archetype-mailing-list.xml
@@ -0,0 +1,46 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="1645d1dc-1f7c-4508-b50b-97b501ccdee3">
+    <name>mailing-list</name>
+    <extension>
+        <ext:grouperNamePrefix>app:mailinglist:</ext:grouperNamePrefix>
+        <ext:ldapRootDn>ou=generic,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>       <!--  could be also something specific e.g. ou=lists,ou=Groups,dc=internet2,dc=edu -->
+        <ext:midPointNamePrefix>mailinglist_</ext:midPointNamePrefix>
+        <ext:midPointDisplayNamePrefix>Mailing list: </ext:midPointDisplayNamePrefix>
+    </extension>
+    <assignment>
+        <targetRef oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90" relation="org:default" type="c:RoleType" />     <!-- metarole-grouper-provided-group -->
+    </assignment>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="d81fb46c-20c7-44d3-8402-fef404ea1264" relation="org:default" type="c:OrgType" />     <!-- generic-groups -->
+    </inducement>
+    <!-- Group-type-specific data -->
+    <inducement>
+        <construction>
+            <resourceRef oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" relation="org:default" type="c:ResourceType" />     <!-- Mailing lists CSV -->
+            <attribute>
+                <c:ref>ri:lists</c:ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>assignmentPath[0].target.identifier</code>
+                        </script>
+                    </expression>
+                </outbound>
+            </attribute>
+        </construction>
+        <order>2</order>
+    </inducement>
+</archetype>
diff --git a/demo/complex2s/midpoint-objects/archetypes/archetype-midpoint-group.xml b/demo/complex2s/midpoint-objects/archetypes/archetype-midpoint-group.xml
new file mode 100644
index 0000000..eb94ab2
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/archetypes/archetype-midpoint-group.xml
@@ -0,0 +1,22 @@
+<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xmlns:ext="http://grouper-demo.tier.internet2.edu"
+      oid="2be36917-71ad-4c3e-8789-89cadea2d5d6">
+    <name>midpoint-group</name>
+    <extension>
+        <ext:ldapRootDn>ou=midpoint,ou=Groups,dc=internet2,dc=edu</ext:ldapRootDn>
+    </extension>
+    <assignment>
+        <targetRef oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a" relation="org:default" type="c:RoleType" />     <!-- metarole-ldap-group -->
+    </assignment>
+    <inducement>
+        <targetRef oid="4790ab69-7ef0-41a4-8992-78877f3beb23" relation="org:default" type="c:OrgType" />     <!-- midpoint-groups -->
+    </inducement>
+</archetype>
diff --git a/demo/complex2s/midpoint-objects/functionLibraries/function-library-grouper.xml b/demo/complex2s/midpoint-objects/functionLibraries/function-library-grouper.xml
new file mode 100644
index 0000000..6219eb0
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/functionLibraries/function-library-grouper.xml
@@ -0,0 +1,184 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<functionLibrary oid="2eef4181-25fa-420f-909d-846a36ca90f3"
+				 xmlns='http://midpoint.evolveum.com/xml/ns/public/common/common-3'
+				 xmlns:c='http://midpoint.evolveum.com/xml/ns/public/common/common-3'
+				 xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3'
+				 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+				 xmlns:xsd='http://www.w3.org/2001/XMLSchema'
+				 xmlns:piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'>
+	<name>grouper</name>
+	<description>Functions for Grouper AMQP connector</description>
+	<function>
+
+		<!-- Some examples:
+	{
+	  encrypted=false,
+	  esbEvent=[
+	  {
+		sourceId=ldap,
+		membershipType=flattened,
+		fieldName=members,
+		groupId=00000000000000000000000000000001,
+		changeOccurred=false,
+		createdOnMicros=1551884863420000,
+		subjectId=banderson,
+		id=94320942304930294023940329403294,
+		sequenceNumber=1000,
+		eventType=MEMBERSHIP_ADD,
+		groupName=etc:midpointGroups
+	  }
+	]}
+
+
+	 {
+	  "encrypted": false,
+	  "esbEvent": [
+		{
+		  "displayName": "ref:affiliation:alumni",
+		  "changeOccurred": false,
+		  "createdOnMicros": 1551884850499000,
+		  "parentStemId": "9a7ce40af6c546148b41eec81b8ca18d",
+		  "id": "00000000000000000000000000000002",
+		  "sequenceNumber": "110",
+		  "eventType": "GROUP_ADD",
+		  "name": "ref:affiliation:alumni"
+		}
+	  ]
+	}
+	 -->
+
+
+		<name>createUcfChange</name>
+		<parameter>
+			<name>message</name>
+			<type>c:AsyncUpdateMessageType</type>
+		</parameter>
+		<parameter>
+			<name>superGroup</name>
+			<type>xsd:string</type>
+		</parameter>
+		<parameter>
+			<name>groupIncludePattern</name>
+			<type>xsd:anyType</type>
+		</parameter>
+		<parameter>
+			<name>groupExcludePattern</name>
+			<type>xsd:anyType</type>
+		</parameter>
+		<parameter>
+			<name>relevantSourceId</name>
+			<type>xsd:string</type>
+		</parameter>
+		<script>
+			<code>
+				import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+				import com.evolveum.prism.xml.ns._public.types_3.*
+				import static com.evolveum.midpoint.schema.constants.SchemaConstants.*
+				import com.evolveum.midpoint.schema.util.*
+				import com.evolveum.midpoint.prism.path.*
+                import com.evolveum.midpoint.schema.constants.*
+                import com.evolveum.midpoint.prism.delta.*
+                
+                PLAIN_GROUP_OBJECT_CLASS = new ItemName(MidPointConstants.NS_RI, 'CustomPlainGroupObjectClass')
+                TRIGGER_FIRE_AFTER = 60000
+                TRIGGER_SAFETY_MARGIN = 10000
+
+				esbEvent = midpoint.getMessageBodyAsMap(message)['esbEvent'][0]
+				log.info('esbEvent = {}', esbEvent)
+				eventType = esbEvent['eventType']
+				if (eventType == 'MEMBERSHIP_ADD' || eventType == 'MEMBERSHIP_DELETE') {
+					groupName = esbEvent['groupName']
+					if (groupName == null) {
+						log.warn('No group name in membership change message, ignoring it: {}', esbEvent)
+						return null
+					}
+                    groupId = esbEvent['groupId']
+                    if (groupId == null) {
+                        log.warn('No group ID in membership change message, ignoring it: {}', esbEvent)
+                        return null
+                    }
+					isExported = matches(groupName, groupIncludePattern, groupExcludePattern)
+					if (!isExported) {
+						log.info('Irrelevant group membership change, ignoring it: {}', groupName)
+						return null
+					}
+					sourceId = esbEvent['sourceId']
+					if (sourceId != relevantSourceId) {
+						log.info('Irrelevant subject source ID in membership change message, ignoring it: {}', sourceId)
+						return null
+					}
+					subjectId = esbEvent['subjectId']
+                    if (subjectId == null) {
+                        log.info('Null subject ID in membership change message, ignoring it: {}', sourceId)
+                        return null
+                    }
+					log.info('### {} - {} - {}', subjectId, eventType, groupName)
+					identifiers = new HashMap()
+					identifiers.put(ICFS_NAME, groupName)
+					identifiers.put(ICFS_UID, groupId)
+					ObjectDeltaType delta
+					itemDelta = new ItemDeltaType()
+					itemDelta.modificationType = eventType == 'MEMBERSHIP_ADD' ? ModificationTypeType.ADD : ModificationTypeType.DELETE
+					itemDelta.path = new ItemPathType(ItemPath.create(ShadowType.F_ATTRIBUTES, 'member'))
+					itemDelta.value.add(RawType.fromPropertyRealValue(subjectId, null, prismContext))
+					delta = new ObjectDeltaType()
+					delta.changeType = ChangeTypeType.MODIFY
+					delta.itemDelta.add(itemDelta)
+                    
+                    added = midpoint
+                            .getOptimizingTriggerCreator(TRIGGER_FIRE_AFTER, TRIGGER_SAFETY_MARGIN)
+                            .createForNamedUser(subjectId)
+                    log.info('Recompute trigger for {}: {}', subjectId, added ? 'added' : 'not added (already present or user not found)')
+                    
+					return UcfChangeUtil.create(PLAIN_GROUP_OBJECT_CLASS, identifiers, delta, prismContext)
+				} else if (eventType == 'GROUP_ADD' || eventType == 'GROUP_DELETE') {
+					groupName = esbEvent['name']
+					groupId = esbEvent['id']
+					isExported = matches(groupName, groupIncludePattern, groupExcludePattern)
+					if (!isExported) {
+						log.info('Irrelevant group add/delete event, ignoring it: {}', groupName)
+						return null
+					}
+					identifiers = new HashMap()
+					identifiers.put(ICFS_NAME, groupName)
+					identifiers.put(ICFS_UID, groupId)
+					ObjectDeltaType delta
+					if (eventType == 'GROUP_DELETE') {
+						delta = new ObjectDeltaType()
+						delta.changeType = ChangeTypeType.DELETE
+					} else {
+						delta = null
+					}
+					return UcfChangeUtil.create(PLAIN_GROUP_OBJECT_CLASS, identifiers, delta, prismContext)
+				} else {
+					log.warn('Unsupported event type: {} -> {}', eventType, esbEvent)
+					return null
+				}
+
+				def matches(String name, Collection includes, Collection excludes) {
+					matches(name, includes) &amp;&amp; !matches(name, excludes)
+				}
+
+				def matches(String name, Collection patterns) {
+					if (name == null || patterns == null) {
+						false
+					} else {
+						for (pattern in patterns) {
+							if (name ==~ pattern) {
+								return true
+							}
+						}
+						false
+					}
+				}
+			</code>
+		</script>
+		<returnType>c:UcfChangeType</returnType>
+	</function>
+</functionLibrary>
diff --git a/demo/complex2s/midpoint-objects/objectTemplates/template-user.xml b/demo/complex2s/midpoint-objects/objectTemplates/template-user.xml
new file mode 100644
index 0000000..9442803
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/objectTemplates/template-user.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<objectTemplate xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" oid="8098b124-c20c-4965-8adf-e528abedf7a4">
+    <name>User Template</name>
+    <mapping>
+        <strength>strong</strength>
+        <source>
+            <path>name</path>
+        </source>
+        <expression>
+            <script>
+                <code>
+                    import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+                    import com.evolveum.midpoint.schema.constants.*
+                    import com.evolveum.midpoint.schema.* 
+                    import javax.xml.namespace.*
+                    import com.evolveum.midpoint.util.*
+                    import com.evolveum.midpoint.prism.path.*
+                    
+                    GROUPER_RESOURCE_OID = '1eff65de-5bb6-483d-9edf-8cc2c2ee0233'
+                    MEMBER_NAME = new QName(MidPointConstants.NS_RI, 'member')
+                    
+                    memberDef = prismContext.definitionFactory().createPropertyDefinition(MEMBER_NAME, DOMUtil.XSD_STRING)
+                    memberDef.setMaxOccurs(-1)
+
+                    shadowQuery = prismContext.queryFor(ShadowType.class)
+                        .item(ShadowType.F_RESOURCE_REF).ref(GROUPER_RESOURCE_OID)
+                        .and().item(ShadowType.F_SYNCHRONIZATION_SITUATION).eq(SynchronizationSituationType.LINKED)
+                        .and().item(ShadowType.F_KIND).eq(ShadowKindType.ENTITLEMENT)
+                        .and().item(ShadowType.F_INTENT).eq('group')
+                        .and().block().item(ShadowType.F_DEAD).isNull().or().item(ShadowType.F_DEAD).eq(false).endBlock()
+                        .and().item(ItemPath.create(ShadowType.F_ATTRIBUTES, MEMBER_NAME), memberDef).eq(basic.stringify(name))
+                        .build()
+                        
+                    //log.info('shadowQuery = {}\n{}', shadowQuery, shadowQuery.debugDump())
+                    options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch())
+                    shadows = midpoint.searchObjects(ShadowType.class, shadowQuery, options)
+                    //log.info('shadows found for {}: {}', name, shadows)
+                    
+                    orgNames = shadows.collect { basic.stringify(it.name) }            // todo - use attributes
+                    log.info('org names = {}', orgNames)
+                    
+                    if (!orgNames.isEmpty()) { 
+                        orgQueryBuilder = prismContext.queryFor(OrgType.class)
+                        
+                        first = true
+                        for (orgName in orgNames) {
+                            if (first) {
+                                first = false
+                            } else {
+                                orgQueryBuilder = orgQueryBuilder.or()
+                            }
+                            orgQueryBuilder = orgQueryBuilder.item(ItemPath.create(OrgType.F_EXTENSION, 'grouperName')).eq(orgName)
+                        }
+                            
+                        orgQuery = orgQueryBuilder.build()
+                        //log.info('org query:\n', orgQuery.debugDump())
+                        
+                        orgs = midpoint.searchObjects(OrgType.class, orgQuery, null)
+                        log.info('orgs found: {}', orgs)
+                        
+                        orgs.collect {
+                            new AssignmentType(prismContext)
+                                .subtype('grouper-group')
+                                .targetRef(it.oid, OrgType.COMPLEX_TYPE)
+                        }
+                    } else {
+                        null
+                    }
+                </code>
+            </script>
+        </expression>
+        <target>
+            <path>assignment</path>
+            <set>
+                <condition>
+                    <script>
+                        <code>
+                            assignment?.subtype.contains('grouper-group')
+                        </code>
+                    </script>
+                </condition>
+            </set>
+        </target>
+    </mapping>
+</objectTemplate>
diff --git a/demo/complex2s/midpoint-objects/orgs/org-affiliations.xml b/demo/complex2s/midpoint-objects/orgs/org-affiliations.xml
new file mode 100644
index 0000000..577c894
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-affiliations.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1d7c0e3a-4456-409c-9f50-95407b2eb785">
+    <name>affiliations</name>
+    <displayName>Affiliations</displayName>
+</org>
diff --git a/demo/complex2s/midpoint-objects/orgs/org-courses.xml b/demo/complex2s/midpoint-objects/orgs/org-courses.xml
new file mode 100644
index 0000000..47147d5
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-courses.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="225e9360-0639-40ba-8a31-7f31bef067be">
+    <name>courses</name>
+    <displayName>Courses</displayName>
+</org>
\ No newline at end of file
diff --git a/demo/complex2s/midpoint-objects/orgs/org-departments.xml b/demo/complex2s/midpoint-objects/orgs/org-departments.xml
new file mode 100644
index 0000000..b5638d4
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-departments.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="bee44c51-2469-411d-bac7-695728e9c241">
+    <name>departments</name>
+    <displayName>Departments</displayName>
+</org>
\ No newline at end of file
diff --git a/demo/complex2s/midpoint-objects/orgs/org-generic-groups.xml b/demo/complex2s/midpoint-objects/orgs/org-generic-groups.xml
new file mode 100644
index 0000000..baa2c79
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-generic-groups.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="1f339075-5b2f-4a18-9c98-451f3eb0d28d">
+    <name>generic-groups</name>
+    <displayName>Generic groups</displayName>
+</org>
diff --git a/demo/complex2s/midpoint-objects/orgs/org-grouper-sysadmin.xml b/demo/complex2s/midpoint-objects/orgs/org-grouper-sysadmin.xml
new file mode 100644
index 0000000..201777a
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-grouper-sysadmin.xml
@@ -0,0 +1,16 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      oid="d48ec05b-fffd-4262-acd3-d9ff63365b62">
+    <name>org-grouper-sysadmin</name>
+    <displayName>Grouper Administrators</displayName>
+    <assignment id="1">
+        <targetRef oid="2be36917-71ad-4c3e-8789-89cadea2d5d6" type="ArchetypeType"/>         <!--  archetype midpoint-group -->
+    </assignment>
+    <identifier>sysadmingroup</identifier>
+</org>
diff --git a/demo/complex2s/midpoint-objects/orgs/org-mailing-lists.xml b/demo/complex2s/midpoint-objects/orgs/org-mailing-lists.xml
new file mode 100644
index 0000000..6674745
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-mailing-lists.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="d81fb46c-20c7-44d3-8402-fef404ea1264">
+    <name>mailing-lists</name>
+    <displayName>Mailing lists</displayName>
+</org>
diff --git a/demo/complex2s/midpoint-objects/orgs/org-midpoint-groups.xml b/demo/complex2s/midpoint-objects/orgs/org-midpoint-groups.xml
new file mode 100644
index 0000000..9c0658d
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/orgs/org-midpoint-groups.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    oid="4790ab69-7ef0-41a4-8992-78877f3beb23">
+    <name>midpoint-groups</name>
+    <displayName>midPoint groups</displayName>
+</org>
diff --git a/demo/complex2s/midpoint-objects/resources/ldap-main.xml b/demo/complex2s/midpoint-objects/resources/ldap-main.xml
new file mode 100644
index 0000000..09934db
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/resources/ldap-main.xml
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<resource oid="0a37121f-d515-4a23-9b6d-554c5ef61272"
+        xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3' xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+	xmlns:my="http://whatever.com/my" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
+	xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+
+	<name>LDAP (directory)</name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.ldap.LdapConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration
+		xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+		xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
+		<icfc:configurationProperties
+			xmlns:icfcldap="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector">
+            <icfcldap:port>389</icfcldap:port>
+            <icfcldap:host>directory</icfcldap:host>
+            <!-- <icfcldap:host>192.168.56.101</icfcldap:host>  -->
+			<icfcldap:baseContext>dc=internet2,dc=edu</icfcldap:baseContext>
+			<icfcldap:bindDn>cn=Directory Manager</icfcldap:bindDn>
+			<icfcldap:bindPassword>
+				<t:clearValue>password</t:clearValue>
+			</icfcldap:bindPassword>
+			<icfcldap:uidAttribute>nsUniqueId</icfcldap:uidAttribute>
+			<icfcldap:pagingStrategy>spr</icfcldap:pagingStrategy> <!-- spr? -->
+			<!--  <icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute>  -->
+			<icfcldap:operationalAttributes>memberOf</icfcldap:operationalAttributes>
+			<icfcldap:operationalAttributes>createTimestamp</icfcldap:operationalAttributes>
+			<icfcldap:operationalAttributes>nsAccountLock</icfcldap:operationalAttributes>
+			<!-- >icfcldap:usePermissiveModify>always</icfcldap:usePermissiveModify>
+			<icfcldap:passwordHashAlgorithm>SSHA</icfcldap:passwordHashAlgorithm  -->
+			<!-- >icfcldap:vlvSortAttribute>uid</icfcldap:vlvSortAttribute> <icfcldap:vlvSortOrderingRule>2.5.13.3</icfcldap:vlvSortOrderingRule -->
+		</icfc:configurationProperties>
+		<icfc:resultsHandlerConfiguration>
+			<icfc:enableNormalizingResultsHandler>false</icfc:enableNormalizingResultsHandler>
+			<icfc:enableFilteredResultsHandler>false</icfc:enableFilteredResultsHandler>
+			<icfc:enableAttributesToGetSearchResultsHandler>false</icfc:enableAttributesToGetSearchResultsHandler>
+		</icfc:resultsHandlerConfiguration>
+	</connectorConfiguration>
+
+	<schema>
+		<generationConstraints>
+			<generateObjectClass>ri:inetOrgPerson</generateObjectClass>
+			<generateObjectClass>ri:eduPerson</generateObjectClass>
+			<generateObjectClass>ri:groupOfUniqueNames</generateObjectClass>
+			<generateObjectClass>ri:groupOfNames</generateObjectClass>
+			<generateObjectClass>ri:organizationalUnit</generateObjectClass>
+		</generationConstraints>
+	</schema>
+
+	<schemaHandling>
+		<objectType>
+			<kind>account</kind>
+			<displayName>Normal Account</displayName>
+			<default>true</default>
+			<objectClass>ri:inetOrgPerson</objectClass>
+			<auxiliaryObjectClass>ri:eduPerson</auxiliaryObjectClass>
+			<attribute>
+				<ref>ri:dn</ref>
+				<displayName>Distinguished Name</displayName>
+                <limitations>
+                    <minOccurs>0</minOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+				<matchingRule>mr:distinguishedName</matchingRule>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>name</path>
+                    </source>
+                    <expression>
+                        <script>
+                            <code>
+                                'uid=' + name + ',ou=People,dc=internet2,dc=edu'
+                            </code>
+                        </script>
+                    </expression>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:cn</ref>
+				<displayName>Common Name</displayName>
+				<limitations>
+					<minOccurs>0</minOccurs>
+				</limitations>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>fullName</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:sn</ref>
+				<displayName>Surname</displayName>
+                <limitations>
+                    <minOccurs>0</minOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>familyName</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:givenName</ref>
+				<displayName>Given Name</displayName>
+                <limitations>
+                    <minOccurs>0</minOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>givenName</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:uid</ref>
+				<displayName>Login Name</displayName>
+                <tolerant>false</tolerant>
+				<matchingRule>mr:stringIgnoreCase</matchingRule>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>name</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<displayName>Mail</displayName>
+				<matchingRule>mr:stringIgnoreCase</matchingRule>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>emailAddress</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:employeeNumber</ref>
+                <tolerant>false</tolerant>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>employeeNumber</path>
+                    </source>
+                </outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:businessCategory</ref>
+                <tolerant>false</tolerant>
+			</attribute>
+<!-- 				<attribute>
+				<ref>ri:eduPersonAffiliation</ref>
+				<outbound>
+					<strength>strong</strength>
+					<source>
+						<path>extension/rawAffiliation</path>
+					</source>
+				</outbound>
+                <tolerant>false</tolerant>
+			</attribute> -->
+            <association>
+                <tolerant>false</tolerant>
+                <ref>ri:group</ref>
+                <kind>entitlement</kind>
+                <intent>group</intent>
+                <direction>objectToSubject</direction>
+                <associationAttribute>ri:uniqueMember</associationAttribute>
+                <valueAttribute>ri:dn</valueAttribute>
+            </association>
+			<protected>
+				<filter>
+					<q:equal>
+						<q:matching>http://prism.evolveum.com/xml/ns/public/matching-rule-3#distinguishedName</q:matching>
+						<q:path>attributes/ri:dn</q:path>
+						<q:value>cn=root,dc=internet2,dc=edu</q:value>
+					</q:equal>
+				</filter>
+			</protected>
+            <credentials>
+                <password>
+                    <outbound/>
+                </password>
+            </credentials>
+		</objectType>
+        
+        <objectType>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <displayName>LDAP Group</displayName>
+            <objectClass>ri:groupOfUniqueNames</objectClass>
+            <attribute>
+                <ref>ri:uniqueMember</ref>
+                <matchingRule>mr:distinguishedName</matchingRule>
+                <fetchStrategy>minimal</fetchStrategy>
+            </attribute>
+            <attribute>
+                <ref>ri:dn</ref>
+                <matchingRule>mr:distinguishedName</matchingRule>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>extension/ldapDn</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:cn</ref>
+                <matchingRule>mr:stringIgnoreCase</matchingRule>
+                <outbound>
+                    <strength>weak</strength>
+                    <source>
+                        <path>identifier</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:uniqueMember</ref>
+                <matchingRule>mr:distinguishedName</matchingRule>
+				<fetchStrategy>minimal</fetchStrategy>
+            </attribute>
+        </objectType>
+	</schemaHandling>
+
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
+							$account/attributes/ri:uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+        <objectSynchronization>
+            <name>group sync</name>
+            <objectClass>ri:groupOfUniqueNames</objectClass>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <focusType>OrgType</focusType>
+            <enabled>true</enabled>
+            <condition>
+                <script>
+                    <code>
+                        import javax.naming.ldap.*
+                        dn = new LdapName(basic.getAttributeValue(account, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'dn'))
+                        dn.startsWith(new LdapName('ou=Affiliations,ou=Groups,dc=internet2,dc=edu')) ||
+                            dn.startsWith(new LdapName('ou=Courses,ou=Groups,dc=internet2,dc=edu')) ||
+                            dn.startsWith(new LdapName('ou=generic,ou=Groups,dc=internet2,dc=edu')) ||
+                            dn.startsWith(new LdapName('ou=midpoint,ou=Groups,dc=internet2,dc=edu'))
+                    </code>
+                </script>
+            </condition>
+            <correlation>
+                <q:equal>
+                    <q:path>extension/ldapDn</q:path>
+                    <expression>
+                        <path>$shadow/attributes/ri:dn</path>
+                    </expression>
+                </q:equal>
+            </correlation>
+            <reaction>
+                <situation>linked</situation>
+                <synchronize>true</synchronize>
+            </reaction>
+            <reaction>
+                <situation>deleted</situation>
+                <synchronize>true</synchronize>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+                </action>
+            </reaction>
+            <reaction>
+                <situation>unlinked</situation>
+                <synchronize>true</synchronize>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                </action>
+            </reaction>
+            <reaction>
+                <situation>unmatched</situation>
+            </reaction>
+        </objectSynchronization>
+	</synchronization>
+    <consistency>
+        <avoidDuplicateValues>true</avoidDuplicateValues>
+    </consistency>
+</resource>
diff --git a/demo/complex2s/midpoint-objects/resources/resource-grouper.xml b/demo/complex2s/midpoint-objects/resources/resource-grouper.xml
new file mode 100644
index 0000000..0e0f802
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/resources/resource-grouper.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<resource oid="1eff65de-5bb6-483d-9edf-8cc2c2ee0233"
+		  xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+          xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+          xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+          xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+          xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+		  xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+		  xmlns:rest="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-grouper-rest/com.evolveum.polygon.connector.grouper.rest.GrouperConnector"
+		  xmlns:conf="http://midpoint.evolveum.com/xml/ns/public/connector/builtin-1/bundle/com.evolveum.midpoint.provisioning.ucf.impl.builtin.async/AsyncUpdateConnector"
+          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+    <name>Grouper Resource</name>
+    <connectorRef type="c:ConnectorType">
+        <filter>
+            <q:equal>
+                <q:path>connectorType</q:path>
+                <q:value>com.evolveum.polygon.connector.grouper.rest.GrouperConnector</q:value>
+            </q:equal>
+        </filter>
+    </connectorRef>
+    <connectorConfiguration>
+        <icfc:configurationProperties>
+            <rest:baseUrl>https://grouper-ws:443</rest:baseUrl>
+            <rest:username>banderson</rest:username>
+            <rest:password>password</rest:password>
+            <rest:superGroup>etc:midpointGroups</rest:superGroup>
+            <rest:groupIncludePattern>midpoint:.*</rest:groupIncludePattern>
+            <rest:groupIncludePattern>app:.*</rest:groupIncludePattern>
+            <rest:groupIncludePattern>test:.*</rest:groupIncludePattern>
+            <rest:groupIncludePattern>ref:.*</rest:groupIncludePattern>
+            <rest:groupExcludePattern>.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)</rest:groupExcludePattern>
+            <rest:subjectSource>ldap</rest:subjectSource>
+            <rest:groupSource>g:gsa</rest:groupSource>
+            <rest:ignoreSslValidation>true</rest:ignoreSslValidation>
+            <rest:exportStem>:</rest:exportStem>
+        </icfc:configurationProperties>
+    </connectorConfiguration>
+        <additionalConnector>
+        <name>AMQP async update connector</name>
+        <connectorRef type="c:ConnectorType">
+            <filter>
+                <q:equal>
+                    <q:path>connectorType</q:path>
+                    <q:value>AsyncUpdateConnector</q:value>
+                </q:equal>
+            </filter>
+        </connectorRef>
+        <connectorConfiguration>
+            <conf:sources>
+                <amqp091>
+                    <uri>amqp://mq:5672</uri>
+                    <username>guest</username>
+                    <password>guest</password>
+                    <queue>sampleQueue</queue>
+                </amqp091>
+            </conf:sources>
+            <conf:transformExpression>
+                <script>
+                    <code>
+                        // ------------------ START OF CONFIGURATION ------------------
+
+                        parameters = [
+                            superGroup: 'etc:midpointGroups',
+                            groupIncludePattern: [ 'midpoint:.*', 'app:.*', 'test:.*', 'ref:.*' ],
+                            groupExcludePattern: [ '.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)' ],
+                            relevantSourceId: 'ldap'
+                        ]
+
+                        // ------------------ END OF CONFIGURATION ------------------
+
+                        parameters.put('message', message)
+                        grouper.execute('createUcfChange', parameters)
+                    </code>
+                </script>
+            </conf:transformExpression>
+        </connectorConfiguration>
+    </additionalConnector>
+    <schemaHandling>
+        <objectType>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <objectClass>ri:CustomPlainGroupObjectClass</objectClass>
+            <default>true</default>
+            <attribute>
+                <ref>icfs:name</ref>
+                <inbound>
+                    <strength>strong</strength>
+                    <target>
+                        <path>extension/grouperName</path>
+                    </target>
+                </inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <script>
+                            <code>
+                                import com.evolveum.midpoint.schema.util.*
+                                import com.evolveum.midpoint.schema.constants.*
+                                
+                                if (input == null) {
+                                    null
+                                } else {
+                                    archetypeOid = '5f2b96d2-49b5-4a8a-9601-14457309a69b'       // generic-grouper-group archetype
+                                    switch (input) {
+                                        case ~/ref:affiliation:.*/: archetypeOid = '56f53812-047d-4b69-83e8-519a73d161e1'; break;   // affiliation archetype
+                                        case ~/ref:dept:.*/: archetypeOid = '1cec5f78-8fba-459b-9547-ef7485009f40'; break;          // department archetype
+                                        case ~/ref:course:.*/: archetypeOid = '3dab9a72-118b-4e40-a138-bb691c335eca'; break;        // course archetype
+                                        case ~/app:mailinglist:.*/: archetypeOid = '1645d1dc-1f7c-4508-b50b-97b501ccdee3'; break;   // mailing-list archetype
+                                    }
+                                    ObjectTypeUtil.createAssignmentTo(archetypeOid, ObjectTypes.ARCHETYPE, prismContext)
+                                }
+                            </code>
+                        </script>
+                    </expression>
+                    <target>
+                        <path>assignment</path>
+                        <set>
+                            <predefined>all</predefined>    <!--  we tolerate no other assignments -->
+                        </set>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:member</ref>
+                <fetchStrategy>explicit</fetchStrategy>
+                <storageStrategy>indexOnly</storageStrategy>
+            </attribute>
+        </objectType>
+    </schemaHandling>
+    <synchronization>
+        <objectSynchronization>
+            <enabled>true</enabled>
+            <kind>entitlement</kind>
+            <intent>group</intent>
+            <objectClass>ri:CustomPlainGroupObjectClass</objectClass>
+            <focusType>OrgType</focusType>
+            <correlation>
+                <q:equal>
+                    <q:path>extension/grouperName</q:path>
+                    <expression>
+                        <path>
+                            $account/attributes/name
+                        </path>
+                    </expression>
+                </q:equal>
+            </correlation>
+            <reaction>
+                <situation>linked</situation>
+                <channel>http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#asyncUpdate</channel>
+                <synchronize>false</synchronize>
+            </reaction>
+            <reaction>
+                <situation>linked</situation>
+                <synchronize>true</synchronize>
+            </reaction>
+            <reaction>
+                <situation>deleted</situation>
+                <!-- a separate task will take care of deleted groups -->
+                <!-- we don't even need to unlink the shadow -->
+                <synchronize>true</synchronize>
+            </reaction>
+            <reaction>
+                <situation>unlinked</situation>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+                </action>
+            </reaction>
+            <reaction>
+                <situation>unmatched</situation>
+                <action>
+                    <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+                </action>
+            </reaction>
+        </objectSynchronization>
+    </synchronization>
+    <caching>
+        <cachingStategy>passive</cachingStategy>
+    </caching>
+</resource>
diff --git a/demo/complex2s/midpoint-objects/resources/scriptedsql-sis-persons.xml b/demo/complex2s/midpoint-objects/resources/scriptedsql-sis-persons.xml
new file mode 100644
index 0000000..e47a0a7
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/resources/scriptedsql-sis-persons.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="4d70a0da-02dd-41cf-b0a1-00e75d3eaa15"
+    xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+    xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+    xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3"
+    xmlns:mr="http://prism.evolveum.com/xml/ns/public/matching-rule-3"
+    xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+
+	<c:name>SQL SIS persons (sources)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>connectorType</q:path>
+				<q:value>net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<c:connectorConfiguration>
+
+		<icfc:configurationProperties 
+			xmlns:icscscriptedsql="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/net.tirasa.connid.bundles.db.scriptedsql/net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector">
+			<icscscriptedsql:host>sources</icscscriptedsql:host>
+			<icscscriptedsql:port>3306</icscscriptedsql:port>
+			<icscscriptedsql:quoting></icscscriptedsql:quoting>
+			<icscscriptedsql:user>root</icscscriptedsql:user>
+			<icscscriptedsql:password>
+				<clearValue>123321</clearValue>
+			</icscscriptedsql:password>
+			<icscscriptedsql:database>sis</icscscriptedsql:database>
+			<!-- >icscscriptedsql:clearTextPasswordToScript>true</icscscriptedsql:clearTextPasswordToScript -->
+			<icscscriptedsql:scriptingLanguage>GROOVY</icscscriptedsql:scriptingLanguage>
+
+			<icscscriptedsql:searchScriptFileName>/opt/midpoint/var/res/sis-persons/SearchScript.groovy</icscscriptedsql:searchScriptFileName>
+			<icscscriptedsql:testScriptFileName>/opt/midpoint/var/res/sis-persons/TestScript.groovy</icscscriptedsql:testScriptFileName>
+			<icscscriptedsql:schemaScriptFileName>/opt/midpoint/var/res/sis-persons/SchemaScript.groovy</icscscriptedsql:schemaScriptFileName>
+			
+			<icscscriptedsql:reloadScriptOnExecution>false</icscscriptedsql:reloadScriptOnExecution>
+			<!-- >icscscriptedsql:syncScriptFileName>/opt/midpoint/var/res/SyncScript.groovy</icscscriptedsql:syncScriptFileName -->
+
+			<icscscriptedsql:validConnectionQuery></icscscriptedsql:validConnectionQuery>
+			<icscscriptedsql:jndiProperties></icscscriptedsql:jndiProperties>
+
+			<icscscriptedsql:jdbcDriver>org.mariadb.jdbc.Driver</icscscriptedsql:jdbcDriver>
+			<icscscriptedsql:jdbcUrlTemplate>jdbc:mysql://%h:%p/%d?useUnicode=true&amp;characterEncoding=utf8&amp;connectionCollation=utf8_bin</icscscriptedsql:jdbcUrlTemplate>
+			<icscscriptedsql:enableEmptyString>true</icscscriptedsql:enableEmptyString>
+			<icscscriptedsql:rethrowAllSQLExceptions>true</icscscriptedsql:rethrowAllSQLExceptions>
+			<icscscriptedsql:nativeTimestamps>false</icscscriptedsql:nativeTimestamps>
+			<icscscriptedsql:allNative>false</icscscriptedsql:allNative>
+			<!--<icscscriptedsql:changeLogColumn>timestamp</icscscriptedsql:changeLogColumn> -->
+			<icscscriptedsql:datasource></icscscriptedsql:datasource>
+		</icfc:configurationProperties>
+
+		<!-- Generic ICF configuration -->
+
+	</c:connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<kind>account</kind>
+			<displayName>Normal Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<displayName>UID</displayName>
+                <inbound>
+                    <target>
+                        <path>name</path>
+                    </target>
+                </inbound>
+                <inbound>
+                    <strength>strong</strength>
+                    <expression>
+                        <assignmentTargetSearch>
+                            <targetType>RoleType</targetType>
+                            <oid>c89f31dd-8d4f-4e0a-82cb-58ff9d8c1b2f</oid>     <!--  role-ldap-basic -->
+                            <assignmentProperties>
+                                <subtype>grouper-basic</subtype>
+                            </assignmentProperties>
+                        </assignmentTargetSearch>
+                    </expression>                            
+                    <target>
+                        <path>assignment</path>
+                        <set>
+                            <condition>
+                                <script>
+                                    <code>
+                                        assignment.subtype.contains('grouper-basic')
+                                    </code>
+                                </script>
+                            </condition>
+                        </set>
+                    </target>
+                </inbound>
+			</attribute>
+            <attribute>
+                <ref>ri:fullName</ref>
+                <displayName>Full Name</displayName>
+                <inbound>
+                    <target>
+                        <path>fullName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:surname</ref>
+                <displayName>Surname</displayName>
+                <inbound>
+                    <target>
+                        <path>familyName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <displayName>Given Name</displayName>
+                <inbound>
+                    <target>
+                        <path>givenName</path>
+                    </target>
+                </inbound>
+            </attribute>
+            <attribute>
+                <ref>ri:mail</ref>
+                <displayName>Mail</displayName>
+                <matchingRule>mr:stringIgnoreCase</matchingRule>
+                <inbound>
+                    <target>
+                        <path>emailAddress</path>
+                    </target>
+                </inbound>
+            </attribute>
+		</objectType>
+	</schemaHandling>
+
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3";
+							$account/attributes/ri:uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+
+			<reaction>
+				<situation>linked</situation>
+				<synchronize>true</synchronize>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink</handlerUri>
+				</action>
+			</reaction>
+
+			<reaction>
+				<situation>unlinked</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#link</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+				<synchronize>true</synchronize>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus</handlerUri>
+				</action>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+
+</c:resource>
+
diff --git a/demo/complex2s/midpoint-objects/resources/target-cs-portal.xml b/demo/complex2s/midpoint-objects/resources/target-cs-portal.xml
new file mode 100644
index 0000000..2a4f239
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/resources/target-cs-portal.xml
@@ -0,0 +1,118 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="a343fc2e-3954-4034-ba1a-2b72c21e577a" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Computer science portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/cs-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>identifier</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:identifier</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:name</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:courses</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-course -->
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/identifier
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex2s/midpoint-objects/resources/target-faculty-portal.xml b/demo/complex2s/midpoint-objects/resources/target-faculty-portal.xml
new file mode 100644
index 0000000..94d54d0
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/resources/target-faculty-portal.xml
@@ -0,0 +1,127 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="e417225d-8a08-46f3-9b5d-624990b52386" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Faculty portal (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/faculty-portal.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:givenName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>givenName</path>
+                    </source>
+                </outbound>
+            </attribute>
+            <attribute>
+                <ref>ri:familyName</ref>
+                <outbound>
+                    <strength>strong</strength>
+                    <source>
+                        <path>familyName</path>
+                    </source>
+                </outbound>
+            </attribute>
+			<attribute>
+				<ref>ri:fullName</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>fullName</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex2s/midpoint-objects/resources/target-mailing-lists.xml b/demo/complex2s/midpoint-objects/resources/target-mailing-lists.xml
new file mode 100644
index 0000000..19f5460
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/resources/target-mailing-lists.xml
@@ -0,0 +1,108 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<c:resource oid="fe805d13-481b-43ec-97d8-9d2df72cd38e" xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:my="http://myself.me/schemas/whatever"
+	xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:icfc="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/connector-schema-3">
+
+	<c:name>Target: Mailing lists (CSV)</c:name>
+
+	<connectorRef type="ConnectorType">
+		<filter>
+			<q:equal>
+				<q:path>c:connectorType</q:path>
+				<q:value>com.evolveum.polygon.connector.csv.CsvConnector</q:value>
+			</q:equal>
+		</filter>
+	</connectorRef>
+
+	<connectorConfiguration xmlns:icfi="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-csv/com.evolveum.polygon.connector.csv.CsvConnector">
+					   
+		<icfc:configurationProperties>
+			<icfi:filePath>/opt/midpoint/var/mailing-lists.csv</icfi:filePath>
+			<icfi:encoding>utf-8</icfi:encoding>
+			<icfi:fieldDelimiter>,</icfi:fieldDelimiter>
+			<icfi:multivalueDelimiter>;</icfi:multivalueDelimiter>
+			<icfi:uniqueAttribute>uid</icfi:uniqueAttribute>
+		</icfc:configurationProperties>
+
+	</connectorConfiguration>
+	<schemaHandling>
+		<objectType>
+			<displayName>Default Account</displayName>
+			<default>true</default>
+			<objectClass>ri:AccountObjectClass</objectClass>
+			<attribute>
+				<ref>ri:uid</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>name</path>
+					</source>
+				</outbound>
+			</attribute>
+			<attribute>
+				<ref>ri:mail</ref>
+				<outbound>
+                    <strength>strong</strength>
+					<source>
+						<path>emailAddress</path>
+					</source>
+				</outbound>
+			</attribute>
+            <attribute>
+                <ref>ri:lists</ref>
+                <limitations>
+                    <maxOccurs>unbounded</maxOccurs>
+                </limitations>
+                <tolerant>false</tolerant>
+                <!-- outbound is in metarole-mailing-list -->
+            </attribute>
+		</objectType>
+	</schemaHandling>
+	<capabilities xmlns:cap="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
+		<configured>
+		</configured>
+	</capabilities>
+	<synchronization>
+		<objectSynchronization>
+			<enabled>true</enabled>
+			<correlation>
+				<q:equal>
+					<q:path>name</q:path>
+					<expression>
+						<path>
+							$account/attributes/uid
+						</path>
+					</expression>
+				</q:equal>
+			</correlation>
+			<reaction>
+				<situation>linked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>deleted</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unlinked</situation>
+				<action>
+					<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount</handlerUri>
+				</action>
+			</reaction>
+			<reaction>
+				<situation>unmatched</situation>
+			</reaction>
+		</objectSynchronization>
+	</synchronization>
+</c:resource>
\ No newline at end of file
diff --git a/demo/complex2s/midpoint-objects/roles/metarole-grouper-provided-group.xml b/demo/complex2s/midpoint-objects/roles/metarole-grouper-provided-group.xml
new file mode 100644
index 0000000..1274be7
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/roles/metarole-grouper-provided-group.xml
@@ -0,0 +1,192 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90">
+    <name>metarole-grouper-provided-group</name>
+    <description>A metarole for archetyped Grouper-provided groups</description>
+    <!-- 
+        This metarole arranges everything that is needed for a Grouper group to live in midPoint.
+        The schema is the following:
+        
+        Grouper group -> shadow -> org -> archetype -> this metarole
+        
+        e.g.
+        
+        ref:affiliation:member -> shadow -> affiliation_member -> affiliation (archetype) -> metarole-grouper-provided-group 
+            
+        1) Grouper group (e.g. ref:affiliation:member) has a shadow object.
+        
+        2) An org object (affiliation_member) is created and linked to this shadow.
+        
+        3) At the same time, appropriate archetype is assigned to the org, based on the Grouper name 
+        (e.g. ref:affiliation:* leads to archetype affiliation).
+        
+        4) This archetype defines basic parameters for the particular class of Grouper groups; e.g. where in midPoint
+        org tree they belong (e.g. under Affiliations org), where in LDAP tree they belong (e.g. under 
+        ou=Affiliations,ou=Groups,dc=internet2,dc=edu), what's the schema for their midPoint name
+        (e.g. affiliation_...) and displayName (e.g. Affiliation: ...).
+        
+        5) To avoid code duplication, these archetypes delegate specific processing
+        (i.e. filling-in appropriate properties of org objects) to metaroles:
+        to this one as well as to metarole-ldap-group.
+        
+        This metarole is devoted to process Grouper-specific information for Grouper groups.
+        As a source it needs only two pieces of information: extension/grouperName (e.g. ref:affiliation:member)
+        and particular archetype (e.g. affiliation) with its configuration data.
+        
+        It fills-in the following items: extension/grouperName -> identifier -> name and displayName
+        by inducing appropriate focus mappings to the org object.    
+         -->
+    <inducement>
+        <focusMappings>
+            <mapping>
+                <name>identifier</name>
+                <description>This mapping fills-in org identifier (e.g. 'member') from extension/grouperName (e.g. 'ref:affiliation:member').
+                It uses extension/grouperNamePrefix information from the archetype (e.g. 'ref:affiliation:' defined in affiliation archetype)</description>
+                <strength>strong</strength>
+                <source>
+                    <path>extension/grouperName</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (grouperName == null) {
+                                null
+                            } else {
+                                archetype = assignmentPath[-2].source       // e.g. archetype affiliation
+                                log.info('archetype = {}', archetype)
+                                if (archetype == null) {
+                                    throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
+                                }
+                                grouperNamePrefix = basic.getExtensionPropertyValue(archetype, 'grouperNamePrefix')      // e.g. 'ref:affiliation:'
+                                if (grouperNamePrefix == null) {
+                                    throw new IllegalStateException('No grouper name prefix in archetype ' + archetype)
+                                }
+                                // grouperName is e.g. 'ref:affiliation:member'
+                                if (grouperName.startsWith(grouperNamePrefix)) {
+                                    grouperName.substring(grouperNamePrefix.length())       // returning e.g. 'member'                                
+                                } else {
+                                    throw new IllegalStateException('Grouper name ' + grouperName + ' does not match the expected prefix: ' + grouperNamePrefix)
+                                }
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>identifier</path>
+                </target>
+            </mapping>
+
+            <mapping>
+                <name>name</name>
+                <description>This mapping fills-in org name (e.g. 'affiliation_member') from identifier (e.g. 'member').
+                It uses extension/midPointNamePrefix information from the archetype (e.g. 'affiliation_' defined in affiliation archetype)</description>
+                <strength>strong</strength>
+                <source>
+                    <path>identifier</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (identifier == null) {
+                                null
+                            } else {
+                                // e.g. identifier = 'member'
+                                archetype = assignmentPath[-2].source         // e.g. affiliation archetype
+                                if (archetype == null) {
+                                    throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
+                                }
+                                prefix = basic.getExtensionPropertyValue(archetype, 'midPointNamePrefix')        // e.g. 'affiliation_'
+                                prefix + identifier                                                             // e.g. 'affiliation_member'
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>name</path>
+                </target>
+            </mapping>
+            
+            <mapping>
+                <name>displayName</name>
+                <description>This mapping fills-in org displayName (e.g. 'Affiliation: member') from identifier (e.g. 'member').
+                It uses extension/midPointDisplayNamePrefix information from the archetype (e.g. 'Affiliation: ' defined in affiliation archetype)</description>
+                <strength>strong</strength>
+                <source>
+                    <path>identifier</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (identifier == null) {
+                                null
+                            } else {
+                                archetype = assignmentPath[-2].source                                                        // e.g. affiliation archetype
+                                if (archetype == null) {
+                                    throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
+                                }
+                                prefix = basic.getExtensionPropertyValue(archetype, 'midPointDisplayNamePrefix')         // e.g. 'Affiliation: '
+                                prefix + identifier                                                                     // e.g. 'Affiliation: member'
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>displayName</path>
+                </target>
+            </mapping>
+
+            <mapping>
+                <name>lifecycle state</name>
+                <description>This mapping sets org lifecycle state to be either "active" or "retired", depending on
+                    whether Grouper group for this org still exists. Orgs in the latter state are on the way to deletion:
+                    their members are unassigned and after no members are there, the org is automatically deleted.</description>
+                <strength>strong</strength>
+                <expression>
+                    <script>
+                        <code>
+                            import com.evolveum.midpoint.model.impl.expr.*
+                            import com.evolveum.midpoint.schema.*
+                            import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+
+                            GROUPER_RESOURCE_OID = '1eff65de-5bb6-483d-9edf-8cc2c2ee0233'
+
+                            modelContext = ModelExpressionThreadLocalHolder.lensContext
+                            rsd = new ResourceShadowDiscriminator(GROUPER_RESOURCE_OID, ShadowKindType.ENTITLEMENT, 'group', null, false)
+                            if (modelContext.findProjectionContext(rsd) != null) {
+                                log.info('Projection context for Grouper group found, marking as "active"')
+                                'active'
+                            } else {
+                                log.info('No projection context for Grouper group, marking as "retired"')
+                                'retired'
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>lifecycleState</path>
+                </target>
+            </mapping>
+        </focusMappings>
+        
+        <!-- 
+            Inducement order of 2 means these mappings are to be applied on org object, because the assignment structure is like this:
+            
+                org -> archetype -> this-metarole
+         -->
+        <order>2</order>
+    </inducement>
+</role>
\ No newline at end of file
diff --git a/demo/complex2s/midpoint-objects/roles/metarole-ldap-group.xml b/demo/complex2s/midpoint-objects/roles/metarole-ldap-group.xml
new file mode 100644
index 0000000..91bf370
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/roles/metarole-ldap-group.xml
@@ -0,0 +1,128 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="8da46694-bd71-4e1e-bfd7-73865ae2ea9a">
+    <name>metarole-ldap-group</name>
+    <description>A metarole for archetyped LDAP groups</description>
+    <!--
+        This metarole supports LDAP groups that correspond to appropriately archetyped
+        org objects.
+        
+        The schema is the following:
+        
+        org -> archetype -> this metarole
+        
+        e.g.
+        
+        affiliation_member -> archetype affiliation -> metarole-ldap-group
+        or org-grouper-sysadmin -> archetype midpoint-group -> metarole-ldap-group   
+            
+        1) An org has appropriate archetype e.g. affiliation_member has an archetype of affiliation;
+        org-grouper-sysadmin has an archetype of midpoint-group.
+        
+        2) This archetype defines LDAP root the particular class of orgs e.g.  
+        ou=Affiliations,ou=Groups,dc=internet2,dc=edu for affiliations or
+        ou=midpoint,ou=Groups,dc=internet2,dc=edu for midPoint-defined groups.
+        
+        3) To avoid code duplication, these archetypes delegate everything related
+        to LDAP to this metarole.
+        
+        This metarole does the three things:
+        
+        1) It ensures that extension/ldapDn is filled in for particular org object.
+        This property is then used by LDAP resource outbound mappings to provide
+        a value for ri:dn attribute.
+        
+        The value of extension/ldapDn is determined as 
+        
+        cn=identifier (in org) + ldapRootDn (in archetype)
+        
+        2) It ensures that appropriate group object is created in LDAP.
+        This is done by inducing a construction with kind=entitlement,
+        intent=group to the org object (i.e. inducement order=2).
+        
+        3) It ensures that appropriate group membership is created in LDAP
+        for any user that has an assignment to the org object. This is done
+        by inducing a construction with default kind and intent (i.e. regular
+        account) to the user that has assigned the org object (i.e. inducement order=3).
+     --> 
+
+    <!--  Fills-in extension/ldapDn in org object -->
+    <inducement>
+        <focusMappings>
+            <mapping>
+                <name>ldapDn</name>
+                <strength>strong</strength>
+                <source>
+                    <path>identifier</path>
+                </source>
+                <expression>
+                    <script>
+                        <code>
+                            if (identifier == null) {
+                                null
+                            } else {
+                                // identifier = e.g. 'member'
+                                metarole = assignmentPath[-2].source        // e.g. metarole-affiliation
+                                log.info('metarole = {}', metarole)
+                                if (metarole == null) {
+                                    throw new IllegalStateException('No metarole in assignment path: ' + assignmentPath)
+                                }
+                                'cn=' + identifier + ',' + basic.getExtensionPropertyValue(metarole, 'ldapRootDn')
+                            }
+                        </code>
+                    </script>
+                </expression>
+                <target>
+                    <path>extension/ldapDn</path>
+                </target>
+            </mapping>
+        </focusMappings>
+        <order>2</order>        <!--  order=2 means the org object: org->archetype->metarole -->
+    </inducement>
+     
+    <!--  Provides LDAP group for the org object -->
+    <inducement>
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />    
+            <kind>entitlement</kind>
+            <intent>group</intent>
+        </construction>
+        <order>2</order>        <!--  order=2 means the org object: org->archetype->metarole -->
+    </inducement>
+    
+    <!--  Provides LDAP group membership for the org object members (users) -->
+    <inducement>
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />    
+            <association>
+                <c:ref>ri:group</c:ref>
+                <outbound>
+                    <expression>
+                        <associationFromLink>
+                            <projectionDiscriminator>
+                                <kind>entitlement</kind>
+                                <intent>group</intent>
+                            </projectionDiscriminator>
+                            <assignmentPathIndex>1</assignmentPathIndex>        <!--  derive from the immediately assigned org -->
+                        </associationFromLink>
+                    </expression>
+                </outbound>
+            </association>
+        </construction>
+        <order>3</order>        <!--  order=3 means the user object; user has an assignment to the org: user->org->archetype->metarole -->
+    </inducement>
+</role>
diff --git a/demo/complex2s/midpoint-objects/roles/role-ldap-basic.xml b/demo/complex2s/midpoint-objects/roles/role-ldap-basic.xml
new file mode 100644
index 0000000..731f024
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/roles/role-ldap-basic.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" 
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" 
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" 
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+      oid="c89f31dd-8d4f-4e0a-82cb-58ff9d8c1b2f">
+    <name>role-ldap-basic</name>
+    <inducement id="1">
+        <construction>
+            <resourceRef oid="0a37121f-d515-4a23-9b6d-554c5ef61272" relation="org:default" type="c:ResourceType" />     <!-- LDAP -->
+        </construction>
+        <order>1</order>
+    </inducement>
+</role>
diff --git a/demo/complex2s/midpoint-objects/systemConfigurations/SystemConfiguration.xml b/demo/complex2s/midpoint-objects/systemConfigurations/SystemConfiguration.xml
new file mode 100644
index 0000000..de75d62
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/systemConfigurations/SystemConfiguration.xml
@@ -0,0 +1,257 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<systemConfiguration xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3" xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oid="00000000-0000-0000-0000-000000000001" version="2">
+    <name>SystemConfiguration</name>
+    <globalSecurityPolicyRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="00000000-0000-0000-0000-000000000120" relation="org:default" type="tns:SecurityPolicyType"/>
+    <logging>
+        <classLogger id="1">
+            <level>ERROR</level>
+            <package>ro.isdc.wro.extensions.processor.css.Less4jProcessor</package>
+        </classLogger>
+        <classLogger id="2">
+            <level>OFF</level>
+            <package>org.hibernate.engine.jdbc.spi.SqlExceptionHelper</package>
+        </classLogger>
+        <classLogger id="3">
+            <level>OFF</level>
+            <package>org.hibernate.engine.jdbc.batch.internal.BatchingBatch</package>
+        </classLogger>
+        <classLogger id="4">
+            <level>WARN</level>
+            <package>org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl</package>
+        </classLogger>
+        <classLogger id="5">
+            <level>OFF</level>
+            <package>org.hibernate.internal.ExceptionMapperStandardImpl</package>
+        </classLogger>
+        <classLogger id="6">
+            <level>OFF</level>
+            <package>net.sf.jasperreports.engine.fill.JRFillDataset</package>
+        </classLogger>
+        <classLogger id="7">
+            <level>WARN</level>
+            <package>org.apache.wicket.resource.PropertiesFactory</package>
+        </classLogger>
+        <classLogger id="8">
+            <level>ERROR</level>
+            <package>org.springframework.context.support.ResourceBundleMessageSource</package>
+        </classLogger>
+        <classLogger id="9">
+            <level>INFO</level>
+            <package>com.evolveum.midpoint.model.impl.lens.projector.Projector</package>
+        </classLogger>
+        <classLogger id="10">
+            <level>INFO</level>
+            <package>com.evolveum.midpoint.model.impl.lens.Clockwork</package>
+        </classLogger>
+        <appender id="11" xsi:type="c:FileAppenderConfigurationType">
+            <pattern>%date [%X{subsystem}] [%thread] %level \(%logger\): %msg%n</pattern>
+            <name>MIDPOINT_LOG</name>
+            <fileName>${midpoint.home}/log/midpoint.log</fileName>
+            <filePattern>${midpoint.home}/log/midpoint-%d{yyyy-MM-dd}.%i.log</filePattern>
+            <maxHistory>10</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <append>true</append>
+        </appender>
+        <appender id="12" xsi:type="c:FileAppenderConfigurationType">
+            <pattern>%date %level: %msg%n</pattern>
+            <name>MIDPOINT_PROFILE_LOG</name>
+            <fileName>${midpoint.home}/log/midpoint-profile.log</fileName>
+            <filePattern>${midpoint.home}/log/midpoint-profile-%d{yyyy-MM-dd}.%i.log</filePattern>
+            <maxHistory>10</maxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <append>true</append>
+        </appender>
+        <rootLoggerAppender>MIDPOINT_LOG</rootLoggerAppender>
+        <rootLoggerLevel>INFO</rootLoggerLevel>
+        <auditing>
+            <enabled>false</enabled>
+            <details>false</details>
+        </auditing>
+    </logging>
+    <defaultObjectPolicyConfiguration id="101">
+        <type>UserType</type>
+        <objectTemplateRef xmlns:tns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="8098b124-c20c-4965-8adf-e528abedf7a4" relation="org:default" type="tns:ObjectTemplateType"/>
+    </defaultObjectPolicyConfiguration>
+    <defaultObjectPolicyConfiguration>
+        <type>OrgType</type>
+        <lifecycleStateModel>
+            <state>
+                <name>retired</name>
+                <!-- object in this model is active but on its way to deletion -->
+            </state>
+        </lifecycleStateModel>
+    </defaultObjectPolicyConfiguration>
+    <cleanupPolicy>
+        <auditRecords>
+            <maxAge>P3M</maxAge>
+        </auditRecords>
+        <closedTasks>
+            <maxAge>P1M</maxAge>
+        </closedTasks>
+    </cleanupPolicy>
+    <internals>
+        <enableExperimentalCode>true</enableExperimentalCode>
+        <operationExecutionRecording>
+            <skipWhenSuccess>true</skipWhenSuccess>
+        </operationExecutionRecording>
+        <focusConstraintsChecking>
+            <skipWhenNoChange>true</skipWhenNoChange>
+            <skipWhenNoIteration>true</skipWhenNoIteration>
+        </focusConstraintsChecking>
+        <projectionConstraintsChecking>
+            <skipWhenNoChange>true</skipWhenNoChange>
+            <skipWhenNoIteration>true</skipWhenNoIteration>
+        </projectionConstraintsChecking>
+        <synchronizationSituationUpdating>
+            <skipWhenNoChange>true</skipWhenNoChange>
+        </synchronizationSituationUpdating>
+        <caching>
+            <profile>
+                <global>true</global>
+                <localRepoCache>
+                    <statistics>
+                        <classification>perCacheAndObjectType</classification>
+                    </statistics>
+                </localRepoCache>
+                <globalRepoCache>
+                    <timeToLive>60</timeToLive>
+                    <objectTypeSettings>
+                        <objectType>SystemConfigurationType</objectType>
+                        <objectType>ArchetypeType</objectType>
+                        <objectType>ObjectTemplateType</objectType>
+                        <objectType>SecurityPolicyType</objectType>
+                        <objectType>ValuePolicyType</objectType>
+                        <objectType>ResourceType</objectType>
+                        <objectType>RoleType</objectType>
+                        <objectType>OrgType</objectType>
+                        <objectType>ServiceType</objectType>
+                        <objectType>ShadowType</objectType>
+                    </objectTypeSettings>
+                    <statistics>
+                        <classification>perCacheAndObjectType</classification>
+                    </statistics>
+                </globalRepoCache>
+            </profile>
+        </caching>
+        <repository>
+            <statistics>
+                <classification>perOperationAndObjectType</classification>
+            </statistics>
+        </repository>
+        <tracing>
+            <profile>
+                <name>performance</name>
+                <displayName>Performance tracing</displayName>
+                <visible>true</visible>
+                <default>true</default>
+                <fileNamePattern>performance-trace %{timestamp} %{focusName} %{milliseconds}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+            </profile>
+            <profile>
+                <name>functional</name>
+                <displayName>Functional tracing</displayName>
+                <visible>true</visible>
+                <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+                <collectLogEntries>true</collectLogEntries>
+                <tracingTypeProfile>
+                    <level>normal</level>
+                </tracingTypeProfile>
+            </profile>
+            <profile>
+                <name>functional-model-logging</name>
+                <displayName>Functional tracing (with model logging)</displayName>
+                <visible>true</visible>
+                <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+                <collectLogEntries>true</collectLogEntries>
+                <loggingOverride>
+                    <levelOverride>
+                        <logger>com.evolveum.midpoint.model</logger>
+                        <level>TRACE</level>
+                    </levelOverride>
+                </loggingOverride>
+                <tracingTypeProfile>
+                    <level>normal</level>
+                </tracingTypeProfile>
+            </profile>
+            <profile>
+                <name>functional-sql-logging</name>
+                <displayName>Functional tracing (with SQL logging)</displayName>
+                <visible>true</visible>
+                <fileNamePattern>functional-trace %{timestamp} %{focusName}</fileNamePattern>
+                <createRepoObject>true</createRepoObject>
+                <compressOutput>true</compressOutput>
+                <collectLogEntries>true</collectLogEntries>
+                <loggingOverride>
+                    <levelOverride>
+                        <logger>org.hibernate.SQL</logger>
+                        <level>TRACE</level>
+                    </levelOverride>
+                </loggingOverride>
+                <tracingTypeProfile>
+                    <level>normal</level>
+                </tracingTypeProfile>
+            </profile>
+        </tracing>
+    </internals>
+    <deploymentInformation>
+        <name>demo/complex2s</name>
+    </deploymentInformation>
+    <adminGuiConfiguration>
+        <userDashboardLink id="13">
+            <targetUrl>/self/profile</targetUrl>
+            <label>Profile</label>
+            <description>View/edit your profile</description>
+            <icon>
+                <cssClass>fa fa-user</cssClass>
+            </icon>
+            <color>green</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfProfile</authorization>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll</authorization>
+        </userDashboardLink>
+        <userDashboardLink id="14">
+            <targetUrl>/self/credentials</targetUrl>
+            <label>Credentials</label>
+            <description>View/edit your credentials</description>
+            <icon>
+                <cssClass>fa fa-shield</cssClass>
+            </icon>
+            <color>blue</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfCredentials</authorization>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#selfAll</authorization>
+        </userDashboardLink>
+        <userDashboardLink id="15">
+            <targetUrl>/admin/users</targetUrl>
+            <label>List users</label>
+            <icon>
+                <cssClass>fa fa-users</cssClass>
+            </icon>
+            <color>red</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#users</authorization>
+        </userDashboardLink>
+        <userDashboardLink id="16">
+            <targetUrl>/admin/resources</targetUrl>
+            <label>List resources</label>
+            <icon>
+                <cssClass>fa fa-database</cssClass>
+            </icon>
+            <color>purple</color>
+            <authorization>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#resources</authorization>
+        </userDashboardLink>
+        <enableExperimentalFeatures>true</enableExperimentalFeatures>
+    </adminGuiConfiguration>
+    <workflowConfiguration>
+        <useLegacyApproversSpecification>never</useLegacyApproversSpecification>
+        <useDefaultApprovalPolicyRules>never</useDefaultApprovalPolicyRules>
+    </workflowConfiguration>
+</systemConfiguration>
diff --git a/demo/complex2s/midpoint-objects/tasks/task-group-scavenger.xml b/demo/complex2s/midpoint-objects/tasks/task-group-scavenger.xml
new file mode 100644
index 0000000..60f9852
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/tasks/task-group-scavenger.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<!--
+
+Looks for groups with the lifecycleState of 'retired' and completes their deletion:
+ - unassigns all the users (simply by recomputing them)
+
+-->
+
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+	  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+	  xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+	  xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	  xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+	  xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3"
+	  oid="1d7bef40-953e-443e-8e9a-ec6e313668c4">
+	<name>Group Scavenger</name>
+	<extension>
+		<scext:executeScript>
+			<s:action>
+				<s:type>execute-script</s:type>
+				<s:parameter>
+					<s:name>script</s:name>
+					<c:value xsi:type="c:ScriptExpressionEvaluatorType">
+						<c:code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
+
+						result = midpoint.currentResult
+						log.info('Processing dead group: {}', input)
+						query = prismContext.queryFor(UserType.class)
+								.item(UserType.F_ROLE_MEMBERSHIP_REF).ref(input.oid)
+								.build()
+						members = midpoint.repositoryService.searchObjects(UserType.class, query, null, result)
+						log.info('Found {} members: {}', members.size(), members)
+
+						for (member in members) {
+							log.info('Going to recompute {}', member)
+							try {
+								midpoint.recompute(UserType.class, member.oid)
+							} catch (Throwable t) {
+								log.error('Couldn\'t recompute {}: {}', member, t.message, t)
+							}
+						}
+						log.info('Members recomputed; checking if the org is still in "retired" state')
+						orgAfter = midpoint.repositoryService.getObject(OrgType.class, input.oid, null, result)
+						currentState = orgAfter.asObjectable().lifecycleState
+						log.info('Current state = {}', currentState)
+						if (currentState == 'retired') {
+							log.info('Deleting the org: {}', orgAfter)
+							midpoint.deleteObject(OrgType.class, orgAfter.oid, null)
+						} else {
+							log.info('State has changed, not deleting the org: {}', orgAfter)
+						}
+						log.info('Dead group processing done: {}', input)
+						</c:code>
+					</c:value>
+				</s:parameter>
+			</s:action>
+		</scext:executeScript>
+		<mext:objectType>OrgType</mext:objectType>
+		<mext:objectQuery>
+			<q:filter>
+				<q:equal>
+					<q:path>lifecycleState</q:path>
+					<q:value>retired</q:value>
+				</q:equal>
+			</q:filter>
+		</mext:objectQuery>
+	</extension>
+	<ownerRef oid="00000000-0000-0000-0000-000000000002"/>
+	<executionStatus>runnable</executionStatus>
+	<category>BulkActions</category>
+	<handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/iterative-scripting/handler-3</handlerUri>
+	<recurrence>recurring</recurrence>
+	<schedule>
+		<interval>60</interval>
+	</schedule>
+</task>
diff --git a/demo/complex2s/midpoint-objects/users/user-banderson.xml b/demo/complex2s/midpoint-objects/users/user-banderson.xml
new file mode 100644
index 0000000..10197ea
--- /dev/null
+++ b/demo/complex2s/midpoint-objects/users/user-banderson.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright (c) 2019 Evolveum and contributors
+  ~
+  ~ This work is dual-licensed under the Apache License 2.0
+  ~ and European Union Public License. See LICENSE file for details.
+  -->
+
+<user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      oid="e897468f-20bd-419c-8fc5-1fe60e2600de">
+    <name>banderson</name>
+    <assignment id="1">
+        <targetRef oid="d48ec05b-fffd-4262-acd3-d9ff63365b62" relation="org:default" type="c:OrgType">
+            <!-- org-grouper-sysadmin -->
+        </targetRef>
+    </assignment>
+    <fullName>Bob Anderson</fullName>
+    <givenName>Bob</givenName>
+    <familyName>Anderson</familyName>
+    <credentials>
+        <password>
+            <value>password</value>
+        </password>
+    </credentials>
+</user>
+	
diff --git a/demo/complex2s/midpoint_server/Dockerfile b/demo/complex2s/midpoint_server/Dockerfile
new file mode 100644
index 0000000..43dac56
--- /dev/null
+++ b/demo/complex2s/midpoint_server/Dockerfile
@@ -0,0 +1,9 @@
+FROM tier/midpoint:laboratory
+
+MAINTAINER info@evolveum.com
+
+ENV MP_DIR /opt/midpoint
+
+VOLUME ${MP_DIR}/var
+
+COPY container_files/mp-home/ ${MP_DIR}/var/
diff --git a/demo/complex2s/midpoint_server/container_files/httpd/host-cert.pem b/demo/complex2s/midpoint_server/container_files/httpd/host-cert.pem
new file mode 100644
index 0000000..9b1021b
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/httpd/host-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAMOSkn4oS2aAMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJNSTESMBAGA1UEBwwJQW5uIEFyYm9yMRcwFQYDVQQK
+DA5JbnRlcm5ldDIvVElFUjEgMB4GA1UEAwwXbWlkcG9pbnQuc3AuZXhhbXBsZS5v
+cmcwHhcNMTgwOTE0MDU1OTQ1WhcNMTkwOTE0MDU1OTQ1WjBpMQswCQYDVQQGEwJV
+UzELMAkGA1UECAwCTUkxEjAQBgNVBAcMCUFubiBBcmJvcjEXMBUGA1UECgwOSW50
+ZXJuZXQyL1RJRVIxIDAeBgNVBAMMF21pZHBvaW50LnNwLmV4YW1wbGUub3JnMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApj/b7MEUSfu3oXMfNgRwTse7
+a5UV7Jswf1M/ZN/ZZkAkIxNBevZgozjesvLPWrmsTgONi7XigJUJvCjdjmlW9eDM
+lri/rkD8HuOR1DQCVKL9nvoS2c3D7sq5Emda3V8Tlj82VqfEmePd3sajx7mcTfbH
+8jwAL9NhkC+WMib5IpjLGpG0FEAC0ha7Lxb+7jIiqHVJaqLXJGCyGN4mh6c1Q9S1
+f8RVTiW2a8x22G+9wnZYbkiA2Kxls177imHlhSz8EdvV4IpGw1amrEWhhuDEum7B
+vZ1xQDLatgRqh4qAKLIVYeRnJ8H1FelMa90qB4G08MIPifmTsQwqJyBYaEdgWQID
+AQABo1MwUTAdBgNVHQ4EFgQUqb9BteODF6wv5R57aEON/wGXMiowHwYDVR0jBBgw
+FoAUqb9BteODF6wv5R57aEON/wGXMiowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAAcKhxI+tSItrXmqC0PSmgWyAYpqbkz6W/cefTutXqhIgY09f
+h0LSv7ogTahoGpyiZk9vy6u3OE9bYwxapEfa4KBjO6HxBMIVBBb3RegVjoPzjElN
+BDwAx0VGFcZTXwMxDWycWdG8ql7rCZBvS50w04uTaIgnGmqXAdWWmBgfJ9cRbxW+
+JwO/mOl1QM1lR/5142NpvuUVWlmZSKEGydE5A1qPz2wpDbBR1ym1BQNS4NEqw6Kp
+GSB8jKyCS1Ve0v2wVze2038Wukz02dq9uKPTIO3T+B+ibZmxn6Op/kFCc1/kK5NS
+Q6JdO1B6KquGAYdGmKAcQ19mv+jqGktqWEEf0g==
+-----END CERTIFICATE-----
diff --git a/demo/complex2s/midpoint_server/container_files/httpd/host-key.pem b/demo/complex2s/midpoint_server/container_files/httpd/host-key.pem
new file mode 100644
index 0000000..5746e59
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/httpd/host-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmP9vswRRJ+7eh
+cx82BHBOx7trlRXsmzB/Uz9k39lmQCQjE0F69mCjON6y8s9auaxOA42LteKAlQm8
+KN2OaVb14MyWuL+uQPwe45HUNAJUov2e+hLZzcPuyrkSZ1rdXxOWPzZWp8SZ493e
+xqPHuZxN9sfyPAAv02GQL5YyJvkimMsakbQUQALSFrsvFv7uMiKodUlqotckYLIY
+3iaHpzVD1LV/xFVOJbZrzHbYb73CdlhuSIDYrGWzXvuKYeWFLPwR29XgikbDVqas
+RaGG4MS6bsG9nXFAMtq2BGqHioAoshVh5GcnwfUV6Uxr3SoHgbTwwg+J+ZOxDCon
+IFhoR2BZAgMBAAECggEAEIRBpjjceiku6jRUwnoYaks/nIWYQwR8AfpUTwJKR/VR
+Yca097Fokm7A+UhUP3A45RtHQb0VPq8P44iv0kk24YCu8r5yFK7SHYOAZnOwU5ZJ
+2jSAEPF3aM7tKh3okhuzB3dKP7u1NZDE5zAW723KUJiW7sL1RcsbY0bHBj6G+9/H
+NplmsjuGt684vRBB0qOBfKF7EiG7mT69tHuNj4gRza9SMY31UtKbZdt2fNY6mp5V
+HscMba7egZP+Ke0pVX4+go9j7K8GG8hYaQDLjrzlPqrxZ2c5X9cC+CRDI/CHuL/s
+V/2yGZJ6n6UabwZoH83RdFrbQ94rU8Hkli6EvxXvMQKBgQDRpheNW5jDG5TfeJKh
+yfKTDQqH2Tk3BsBYYBN7Hf3m7vbkzlxnAKJAoSLmtRMuoeXvI5MrhzaHGsNIUS76
+LDIZnvB7DLUxhFUZsCPkpAA1QHuTWY96oR3PHnPjpk8lSUvtbOPwDLdzVApeFJgZ
+VqMNArZ7AHsK3Kkyi+f4WVQjbQKBgQDLAWiGb5dx6fAM2W6B6HjNmzjBWOuVEXa2
+76to9jzupBZmETfZgxtWUaWUDuNS+f7dtVUTE+p6v/w8clrHEhEZYkqunIOLo/UA
+LFPiuoTfEsWb1rh+nsCjCgy4uimixj/bSkf7NC6NyKTvCygA1mGnVVJUEPegYlDy
+LXCkaKWxHQKBgQCmyHSKL2lrJkEcOwakEU2acNCE3Gno/cT9SYmV83kvQ8JEqmrW
+QqnRsp9aXIljGscapPmKsmnNt5vNp1AxFAHTYh88NRLczsMIyZj0ZwgHVUI6KhC7
+5Psa78YQQBlMt2/g9TSsnuE+rYgF6mpKFiNm0Vasqeg47uzn2mdzqlUGTQKBgE04
+JutkTUY+h1pL5vYxWKpVDfy19z7H2tFxT1FowPrBneeLSyRI88Ac5I/yLdRlVeY9
+0LOmEr5Igwj3MsKgg7KVKfVLgdo/LrW3Jt2Kt3onKNXDkoBPoNUjwH0QC0Boiue+
+VK0gR0kVdm+bXccbxR+im+NwZNE0NLg6Qqu3RredAoGBALuVoqbPPmTCZXYG328H
+bzOs2aiR7BzPSVByV+qG6jW7w03RAnFPJZp7HMU+ViI5VY0wabUscMSvz5163+gM
+4KwY3v9ZjZzZGukIfLuudkdqtaiVOx/KeAC0n+nG21YU+wpZww8gkfHh1/sa2CME
+CWYCgOnmiTHcj83UaTqEXtmv
+-----END PRIVATE KEY-----
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/config.xml b/demo/complex2s/midpoint_server/container_files/mp-home/config.xml
new file mode 100644
index 0000000..5a4e0ea
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/config.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2010-2017 Evolveum
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<configuration>
+    <midpoint>
+        <webApplication>
+            <importFolder>${midpoint.home}/import</importFolder>
+        </webApplication>
+        <repository>
+            <repositoryServiceFactoryClass>com.evolveum.midpoint.repo.sql.SqlRepositoryFactory</repositoryServiceFactoryClass>
+            <baseDir>${midpoint.home}</baseDir>
+            <asServer>true</asServer>
+            <enableIndexOnlyItems>true</enableIndexOnlyItems>
+            <enableNoFetchExtensionValuesInsertion>true</enableNoFetchExtensionValuesInsertion>
+            <enableNoFetchExtensionValuesDeletion>true</enableNoFetchExtensionValuesDeletion>
+        </repository>
+        <audit>
+            <auditService>
+                <auditServiceFactoryClass>com.evolveum.midpoint.audit.impl.LoggerAuditServiceFactory</auditServiceFactoryClass>
+            </auditService>
+            <auditService>
+                <auditServiceFactoryClass>com.evolveum.midpoint.repo.sql.SqlAuditServiceFactory</auditServiceFactoryClass>
+            </auditService>
+        </audit>
+        <icf>
+            <scanClasspath>true</scanClasspath>
+            <scanDirectory>${midpoint.home}/icf-connectors</scanDirectory>
+        </icf>
+        <keystore>
+            <keyStorePath>${midpoint.home}/keystore.jceks</keyStorePath>
+            <keyStorePassword>changeit</keyStorePassword>
+            <encryptionKeyAlias>default</encryptionKeyAlias>
+            <!--
+            You can use smaller cipher key size for encryption. For:
+            AES_128 "http://www.w3.org/2001/04/xmlenc#aes128-cbc";
+            AES_256 "http://www.w3.org/2001/04/xmlenc#aes256-cbc";
+            AES_192 "http://www.w3.org/2001/04/xmlenc#aes192-cbc";
+
+            in element <xmlCipher></xmlCipher>
+            By default AES_128 is used. If you change key size, than
+            you must also create secret key in key store with proper key size and change encryptionKeyAlias.
+
+            To generate keystore with keytool use command:
+            keytool -genseckey -alias default -keystore keystore.jceks -storetype jceks -keyalg AES -keysize 128
+
+            secret key password is by default 'midpoint'
+            -->
+        </keystore>
+        <!-- <profilingMode>dynamic</profilingMode> -->
+    </midpoint>
+</configuration>
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/cs-portal.csv b/demo/complex2s/midpoint_server/container_files/mp-home/cs-portal.csv
new file mode 100644
index 0000000..02a0c65
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/cs-portal.csv
@@ -0,0 +1 @@
+identifier,name,mail,courses
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/faculty-portal.csv b/demo/complex2s/midpoint_server/container_files/mp-home/faculty-portal.csv
new file mode 100644
index 0000000..ce346c5
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/faculty-portal.csv
@@ -0,0 +1 @@
+uid,givenName,familyName,fullName,mail
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.4.jar b/demo/complex2s/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.4.jar
new file mode 100644
index 0000000..b072d05
Binary files /dev/null and b/demo/complex2s/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.4.jar differ
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar b/demo/complex2s/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar
new file mode 100644
index 0000000..88fcb54
Binary files /dev/null and b/demo/complex2s/midpoint_server/container_files/mp-home/icf-connectors/net.tirasa.connid.bundles.db.scriptedsql-2.2.6-SNAPSHOT.jar differ
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/mailing-lists.csv b/demo/complex2s/midpoint_server/container_files/mp-home/mailing-lists.csv
new file mode 100644
index 0000000..780ab04
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/mailing-lists.csv
@@ -0,0 +1 @@
+uid,mail,lists
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy b/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy
new file mode 100644
index 0000000..0e0a52f
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/SchemaScript.groovy
@@ -0,0 +1,57 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import org.identityconnectors.framework.common.objects.AttributeInfo;
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags;
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder;
+import org.identityconnectors.framework.common.objects.ObjectClassInfo;
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder;
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+// This sample shows how to create 3 basic ObjectTypes: __ACCOUNT__, __GROUP__ and organization.
+// Each of them contains one required attribute and normal String attributes
+
+
+log.info("Entering "+action+" Script");
+
+uidAIB = new AttributeInfoBuilder("uid",String.class);
+uidAIB.setRequired(true);
+
+accAttrsInfo = new HashSet<AttributeInfo>();
+accAttrsInfo.add(uidAIB.build());
+accAttrsInfo.add(AttributeInfoBuilder.build("surname", String.class));
+accAttrsInfo.add(AttributeInfoBuilder.build("givenName", String.class));
+accAttrsInfo.add(AttributeInfoBuilder.build("fullName", String.class));
+accAttrsInfo.add(AttributeInfoBuilder.build("mail", String.class));
+ociAccount = new ObjectClassInfoBuilder().setType("__ACCOUNT__").addAllAttributeInfo(accAttrsInfo).build();
+builder.defineObjectClass(ociAccount);
+
+log.info("Schema script done");
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy b/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy
new file mode 100644
index 0000000..5a1f572
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/SearchScript.groovy
@@ -0,0 +1,153 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+
+import groovy.sql.Sql
+import groovy.sql.DataSet
+import org.identityconnectors.framework.common.objects.*
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used.
+//
+// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+log.info("Entering "+action+" Script");
+
+def sql = new Sql(connection);
+def result = []
+def where = "";
+def sqlParams = null
+
+switch ( objectClass ) {
+    case "__ACCOUNT__":
+
+    uidColumn = 'uid'
+    nameColumn = 'uid'
+
+    log.info("Building where clause, query {0}, uidcolumn {1}, nameColumn {2}", query, uidColumn, nameColumn)
+
+    String left = query?.get("left")
+    if (left != null) {
+      if (Uid.NAME.equals(left)) {
+          left = uidColumn
+      } else if (Name.NAME.equals(left)) {
+          left = nameColumn
+      }
+
+      String right = query.get("right")
+
+      String operation = query.get("operation")
+      switch (operation) {
+          case "CONTAINS":
+              right = '%' + right + '%'
+              break;
+          case "ENDSWITH":
+              right = '%' + right
+              break;
+          case "STARTSWITH":
+              right = right + '%'
+              break;
+      }
+
+      sqlParams = [:]
+      sqlParams.put(left, right)
+      right = ":" + left
+
+      def engine = new groovy.text.SimpleTemplateEngine()
+
+      def whereTemplates = [
+            CONTAINS          : ' $left ${not ? "not " : ""}like $right',
+            ENDSWITH          : ' $left ${not ? "not " : ""}like $right',
+            STARTSWITH        : ' $left ${not ? "not " : ""}like $right',
+            EQUALS            : ' $left ${not ? "<>" : "="} $right',
+            GREATERTHAN       : ' $left ${not ? "<=" : ">"} $right',
+            GREATERTHANOREQUAL: ' $left ${not ? "<" : ">="} $right',
+            LESSTHAN          : ' $left ${not ? ">=" : "<"} $right',
+            LESSTHANOREQUAL   : ' $left ${not ? ">" : "<="} $right'
+      ]
+
+      def wt = whereTemplates.get(operation)
+      if (wt != null) {
+        def binding = [left: left, right: right, not: query.get("not")]
+        def template = engine.createTemplate(wt).make(binding)
+        where = ' where ' + template.toString()
+        log.info("Where clause: {0}, with parameters {1}", where, sqlParams)
+      } else {
+        log.warn('Unsupported query: {0}, continuing without WHERE clause (worsening the performance)', query)
+        sqlParams = null
+        where = ''
+      }
+    }
+
+    q = 'select uid, surname, givenName, fullName, mail from SIS_PERSONS' + where
+
+    log.info('query = {0}', query)
+    log.info('sql = {0}', q)
+    log.info('sqlParams = {0}', sqlParams)
+   
+    def processRow = { row -> result.add([
+	__UID__:row.uid, 
+	__NAME__:row.uid, 
+	uid:row.uid,
+	surname:row.surname,
+	givenName:row.givenName,
+	fullName:row.fullName,
+	mail:row.mail])
+    }
+
+    if (sqlParams != null) {
+      sql.eachRow(sqlParams, q, processRow)
+    } else {
+      sql.eachRow(q, processRow)
+    }
+    break
+
+    default:
+    result;
+}
+
+return result;
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy b/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy
new file mode 100644
index 0000000..c887660
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/res/sis-persons/TestScript.groovy
@@ -0,0 +1,38 @@
+/* 
+ * ====================
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2013 ForgeRock. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License("CDDL") (the "License").  You may not use this file
+ * except in compliance with the License.
+ * 
+ * You can obtain a copy of the License at
+ * http://opensource.org/licenses/cddl1.php
+ * See the License for the specific language governing permissions and limitations
+ * under the License.
+ * 
+ * When distributing the Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://opensource.org/licenses/cddl1.php.
+ * If applicable, add the following below this CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ * ====================
+ * Portions Copyrighted 2013 ConnId.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering "+action+" Script");
+def sql = new Sql(connection);
+
+sql.eachRow("select * from SIS_PERSONS limit 10", { println it.uid } );
+
+
diff --git a/demo/complex2s/midpoint_server/container_files/mp-home/schema/internet2.xsd b/demo/complex2s/midpoint_server/container_files/mp-home/schema/internet2.xsd
new file mode 100644
index 0000000..c482436
--- /dev/null
+++ b/demo/complex2s/midpoint_server/container_files/mp-home/schema/internet2.xsd
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<xsd:schema elementFormDefault="qualified"
+  targetNamespace="http://grouper-demo.tier.internet2.edu"
+  xmlns:tns="http://grouper-demo.tier.internet2.edu"
+  xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3"
+  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+  <xsd:complexType name="UserExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:UserType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+	<!-- nothing here for now -->
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="OrgExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:OrgType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperName" type="xsd:string" minOccurs="0"/>
+        <xsd:element name="ldapDn" type="xsd:string" minOccurs="0"/>
+    </xsd:sequence>
+  </xsd:complexType>  
+
+  <xsd:complexType name="ArchetypeExtensionType">
+    <xsd:annotation>
+      <xsd:appinfo>
+        <a:extension ref="c:ArchetypeType"/>
+      </xsd:appinfo>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="grouperNamePrefix" type="xsd:string" minOccurs="0"/>		<!-- e.g. ref:affiliation: -->
+        <xsd:element name="ldapRootDn" type="xsd:string" minOccurs="0"/>		<!-- e.g. ou=Affiliations,ou=Groups,dc=internet2,dc=edu -->
+        <xsd:element name="midPointNamePrefix" type="xsd:string" minOccurs="0"/>		<!-- e.g. affiliation_ -->
+        <xsd:element name="midPointDisplayNamePrefix" type="xsd:string" minOccurs="0"/>		<!-- e.g. Affiliation: -->
+    </xsd:sequence>
+  </xsd:complexType>  
+</xsd:schema>
+
diff --git a/demo/complex2s/mq/Dockerfile b/demo/complex2s/mq/Dockerfile
new file mode 100644
index 0000000..1593b80
--- /dev/null
+++ b/demo/complex2s/mq/Dockerfile
@@ -0,0 +1,13 @@
+FROM tier/rabbitmq:latest
+
+COPY container_files/etc-rabbitmq/* /etc/rabbitmq/
+COPY container_files/usr-local-bin/* /usr/local/bin/
+
+ENV RABBITMQ_PID_FILE=/var/run/rabbitmq/pid
+
+# Must be on /var/lib/rabbitmq (this is the same place where queues are defined)
+ENV RABBITMQ_INIT_DONE_FILE=/var/lib/rabbitmq/initialization.done
+
+ENTRYPOINT ["/usr/local/bin/demo-entrypoint.sh"]
+
+CMD ["rabbitmq-server"]
diff --git a/demo/complex2s/mq/container_files/etc-rabbitmq/rabbitmq.conf b/demo/complex2s/mq/container_files/etc-rabbitmq/rabbitmq.conf
new file mode 100644
index 0000000..4c789ba
--- /dev/null
+++ b/demo/complex2s/mq/container_files/etc-rabbitmq/rabbitmq.conf
@@ -0,0 +1,2 @@
+# Allow guest access from anywhere (change this in production!)
+loopback_users = none
diff --git a/demo/complex2s/mq/container_files/usr-local-bin/demo-entrypoint.sh b/demo/complex2s/mq/container_files/usr-local-bin/demo-entrypoint.sh
new file mode 100755
index 0000000..7355248
--- /dev/null
+++ b/demo/complex2s/mq/container_files/usr-local-bin/demo-entrypoint.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [ ! -e $RABBITMQ_INIT_DONE_FILE ]; then
+    /usr/local/bin/initialize-rabbitmq.sh &
+else
+    echo "RabbitMQ was already initialized"
+fi
+/usr/local/bin/entrypoint.sh "$@"
diff --git a/demo/complex2s/mq/container_files/usr-local-bin/initialize-rabbitmq.sh b/demo/complex2s/mq/container_files/usr-local-bin/initialize-rabbitmq.sh
new file mode 100755
index 0000000..3660e80
--- /dev/null
+++ b/demo/complex2s/mq/container_files/usr-local-bin/initialize-rabbitmq.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -e
+
+echo "Executing RabbitMQ initialization"
+echo "Waiting for the server to start up..."
+rabbitmqctl -t 30 wait $RABBITMQ_PID_FILE
+echo "OK, creating sampleQueue..."
+rabbitmqadmin declare queue name=sampleQueue
+echo "Done"
+touch $RABBITMQ_INIT_DONE_FILE
diff --git a/demo/complex2s/recompute.sh b/demo/complex2s/recompute.sh
new file mode 100755
index 0000000..0d9633e
--- /dev/null
+++ b/demo/complex2s/recompute.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+recompute orgs d48ec05b-fffd-4262-acd3-d9ff63365b62
+recompute users e897468f-20bd-419c-8fc5-1fe60e2600de
diff --git a/demo/complex2s/show-queue-size.sh b/demo/complex2s/show-queue-size.sh
new file mode 100755
index 0000000..2687686
--- /dev/null
+++ b/demo/complex2s/show-queue-size.sh
@@ -0,0 +1 @@
+docker exec complex2s_mq_1 rabbitmqctl list_queues
diff --git a/demo/complex2s/sources/Dockerfile b/demo/complex2s/sources/Dockerfile
new file mode 100644
index 0000000..c76ff73
--- /dev/null
+++ b/demo/complex2s/sources/Dockerfile
@@ -0,0 +1,10 @@
+FROM tier/mariadb:mariadb10
+
+COPY container_files/seed-data/ /seed-data/
+
+ENV MYSQL_DATABASE sis
+ENV MYSQL_USER sis_user
+ENV MYSQL_PASSWORD 49321420423
+ENV MYSQL_DATADIR /var/lib/mysql
+ENV AFTER_FIRST_TIME_SQL /seed-data/persons-and-courses.sql
+
diff --git a/demo/complex2s/sources/container_files/seed-data/persons-and-courses.sql b/demo/complex2s/sources/container_files/seed-data/persons-and-courses.sql
new file mode 100644
index 0000000..65f8376
--- /dev/null
+++ b/demo/complex2s/sources/container_files/seed-data/persons-and-courses.sql
@@ -0,0 +1,531 @@
+USE sis;
+
+CREATE TABLE SIS_PERSONS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE SIS_AFFILIATIONS (
+    uid VARCHAR(255) NOT NULL,
+    affiliation VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , affiliation)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex2s/targets/Dockerfile b/demo/complex2s/targets/Dockerfile
new file mode 100644
index 0000000..6099cce
--- /dev/null
+++ b/demo/complex2s/targets/Dockerfile
@@ -0,0 +1,7 @@
+FROM tier/mariadb:mariadb10
+
+#TODO better name for the target database
+ENV MYSQL_DATABASE target
+ENV MYSQL_USER target_user
+ENV MYSQL_PASSWORD fdjskjrkwqjrw
+ENV MYSQL_DATADIR /var/lib/mysql
diff --git a/demo/complex2s/targets/container_files/seed-data/target.tmp b/demo/complex2s/targets/container_files/seed-data/target.tmp
new file mode 100644
index 0000000..01fa4ef
--- /dev/null
+++ b/demo/complex2s/targets/container_files/seed-data/target.tmp
@@ -0,0 +1,531 @@
+USE target;
+
+CREATE TABLE FACULTY_PORTAL_MEMBERS (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    fullName VARCHAR(255) DEFAULT NULL,
+    department VARCHAR(255) DEFAULT NULL,
+    mail VARCHAR(255) DEFAULT NULL,
+    PRIMARY KEY (uid)
+);
+
+CREATE TABLE MAILING_LIST_MEMBERS (
+    list VARCHAR(255) NOT NULL,
+    member VARCHAR(255) NOT NULL,
+    PRIMARY KEY (list, member)
+);
+
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jsmith','Smith','Joe','John Smith',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('banderson','Anderson','Bob','Bob Anderson',NULL,NULL);
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kwhite','White','Karl','Karl White','Law','kwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kwhite','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('whenderson','Henderson','William','William Henderson','Advising','whenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('whenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis','Davis','David','David Davis','Computer Science','ddavis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('cmorrison','Morrison','Colin','Colin Morrison','Financial Aid','cmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('cmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson','Anderson','Donna','Donna Anderson','Account Payable','danderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison','Morrison','Ann','Ann Morrison','Law','amorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wprice','Price','William','William Price','Account Payable','wprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wprice','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mroberts','Roberts','Marie','Marie Roberts','Law','mroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kjohnson','Johnson','Kiersten','Kiersten Johnson','Physical Education','kjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kjohnson','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown','Brown','James','James Brown','Information Technology','jbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('agasper','Gasper','Ann','Ann Gasper','Computer Science','agasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('agasper','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott','Scott','Jennifer','Jennifer Scott','Business','jscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bbutler','Butler','Betty','Betty Butler','Purchasing','bbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bbutler','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tmorrison','Morrison','Thomas','Thomas Morrison','Purchasing','tmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown14','Brown','Jennifer','Jennifer Brown','Accounting','jbrown14@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown14','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gjohnson','Johnson','Greg','Greg Johnson','Physical Education','gjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('rmartinez','Martinez','Robert','Robert Martinez','Financial Aid','rmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('rmartinez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlewis','Lewis','Jo','Jo Lewis','Accounting','jlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper','Gasper','Mary','Mary Gasper','Physical Education','mgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales','Vales','Karoline','Karoline Vales','Information Technology','kvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('tgrady','Grady','Thomas','Thomas Grady','Law','tgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('tgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmorrison','Morrison','Kiersten','Kiersten Morrison','Information Technology','kmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady','Grady','David','David Grady','Advising','dgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mthompson','Thompson','Mary','Mary Thompson','Financial Aid','mthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mthompson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper','Gasper','Bill','Bill Gasper','Business','bgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlopez','Lopez','David','David Lopez','Account Payable','dlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hwhite','White','Heather','Heather White','Physical Education','hwhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hwhite','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddavis27','Davis','Donna','Donna Davis','Accounting','ddavis27@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddavis27','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgasper28','Gasper','Bill','Bill Gasper','Engineering','bgasper28@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgasper28','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jjohnson','Johnson','Jennifer','Jennifer Johnson','Financial Aid','jjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jjohnson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('amorrison30','Morrison','Ann','Ann Morrison','Financial Aid','amorrison30@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('amorrison30','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kmartinez','Martinez','Karl','Karl Martinez','Accounting','kmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kmartinez','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ahenderson','Henderson','Ann','Ann Henderson','Accounting','ahenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ahenderson','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('avales','Vales','Ann','Ann Vales','Purchasing','avales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('avales','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ggonazles','Gonazles','Greg','Greg Gonazles','Language Arts','ggonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ggonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bdoe','Doe','Blake','Blake Doe','Business','bdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('plangenberg','Langenberg','Paul','Paul Langenberg','Information Technology','plangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('plangenberg','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gvales','Vales','Greg','Greg Vales','Language Arts','gvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nhenderson','Henderson','Nancy','Nancy Henderson','Physical Education','nhenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nhenderson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wthompson','Thompson','William','William Thompson','Law','wthompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wthompson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kvales40','Vales','Karl','Karl Vales','Business','kvales40@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kvales40','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('blee','Lee','Bill','Bill Lee','Engineering','blee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('blee','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlee','Lee','Marie','Marie Lee','Information Technology','mlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlee','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kclark','Clark','Kiersten','Kiersten Clark','Financial Aid','kclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kclark','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott','Scott','William','William Scott','Language Arts','wscott@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dbutler','Butler','Donna','Donna Butler','Financial Aid','dbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dbutler','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('awhite','White','Ann','Ann White','Purchasing','awhite@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('awhite','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hdoe','Doe','Heather','Heather Doe','Financial Aid','hdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hdoe','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg','Langenberg','David','David Langenberg','Language Arts','dlangenberg@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ethompson','Thompson','Eric','Eric Thompson','Law','ethompson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ethompson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jbrown50','Brown','Jennifer','Jennifer Brown','Account Payable','jbrown50@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jbrown50','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgonazles','Gonazles','Michael','Michael Gonazles','Computer Science','mgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgonazles','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gbutler','Butler','Greg','Greg Butler','Information Technology','gbutler@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gbutler','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mvales','Vales','Mark','Mark Vales','Engineering','mvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mvales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mlewis','Lewis','Michael','Michael Lewis','Information Technology','mlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mlewis','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hvales','Vales','Heather','Heather Vales','Information Technology','hvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hvales','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jscott56','Scott','Jo','Jo Scott','Purchasing','jscott56@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jscott56','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sdoe','Doe','Sarah','Sarah Doe','Business','sdoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sdoe','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('svales','Vales','Sarah','Sarah Vales','Advising','svales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('svales','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hmorrison','Morrison','Heather','Heather Morrison','Engineering','hmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hmorrison','student');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jlopez','Lopez','Jennifer','Jennifer Lopez','Language Arts','jlopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jlopez','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlangenberg61','Langenberg','Donna','Donna Langenberg','Law','dlangenberg61@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlangenberg61','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bgrady','Grady','Betty','Betty Grady','Accounting','bgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bgrady','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmorrison','Morrison','Jennifer','Jennifer Morrison','Law','jmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmorrison','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wvales','Vales','William','William Vales','Law','wvales@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wvales','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mmartinez','Martinez','Mark','Mark Martinez','Physical Education','mmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mmartinez','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez','Martinez','Jennifer','Jennifer Martinez','Information Technology','jmartinez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('mgasper67','Gasper','Mary','Mary Gasper','Computer Science','mgasper67@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('mgasper67','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dpeterson','Peterson','David','David Peterson','Advising','dpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dpeterson','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice','Price','Erik','Erik Price','Business','eprice@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgasper','Gasper','James','James Gasper','Accounting','jgasper@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgasper','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jclark','Clark','Jennifer','Jennifer Clark','Business','jclark@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jclark','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('bpeterson','Peterson','Betty','Betty Peterson','Account Payable','bpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('bpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wsmith','Smith','William','William Smith','Information Technology','wsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wsmith','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('lwilliams','Williams','Lisa','Lisa Williams','Purchasing','lwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('lwilliams','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady76','Grady','David','David Grady','Physical Education','dgrady76@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady76','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jmartinez77','Martinez','Jo','Jo Martinez','Law','jmartinez77@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jmartinez77','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dlewis','Lewis','Donna','Donna Lewis','Financial Aid','dlewis@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','community');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dlewis','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wscott79','Scott','William','William Scott','Account Payable','wscott79@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wscott79','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('ddoe','Doe','Donna','Donna Doe','Physical Education','ddoe@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','student');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('ddoe','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('gmorrison','Morrison','Greg','Greg Morrison','Language Arts','gmorrison@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('gmorrison','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('khenderson','Henderson','Kim','Kim Henderson','Account Payable','khenderson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','member');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('khenderson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kpeterson','Peterson','Karoline','Karoline Peterson','Accounting','kpeterson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kpeterson','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('eprice84','Price','Erik','Erik Price','Computer Science','eprice84@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('eprice84','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hsmith','Smith','Heather','Heather Smith','Business','hsmith@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hsmith','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwilliams','Williams','Donna','Donna Williams','Financial Aid','dwilliams@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','alum');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwilliams','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('klopez','Lopez','Karl','Karl Lopez','Advising','klopez@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','staff');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('klopez','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wjohnson','Johnson','William','William Johnson','Accounting','wjohnson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wjohnson','staff');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('wbrown','Brown','William','William Brown','Physical Education','wbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('wbrown','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('hbrown','Brown','Heather','Heather Brown','Law','hbrown@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('hbrown','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('kroberts','Roberts','Kim','Kim Roberts','Account Payable','kroberts@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('kroberts','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dwalters','Walters','Donna','Donna Walters','Advising','dwalters@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dwalters','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('nlee','Lee','Nancy','Nancy Lee','Computer Science','nlee@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','faculty');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('nlee','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('sgonazles','Gonazles','Sarah','Sarah Gonazles','Computer Science','sgonazles@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('sgonazles','faculty');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('handerson','Anderson','Heather','Heather Anderson','Purchasing','handerson@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('handerson','member');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('danderson96','Anderson','David','David Anderson','Advising','danderson96@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('danderson96','alum');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('dgrady97','Grady','David','David Grady','Advising','dgrady97@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('dgrady97','community');
+INSERT INTO SIS_PERSONS (uid, surname, givenName, fullName, department, mail) VALUES ('jgrady','Grady','James','James Grady','Purchasing','jgrady@example.edu');
+INSERT INTO SIS_AFFILIATIONS (uid, affiliation) VALUES ('jgrady','student');
+
+CREATE TABLE SIS_COURSES (
+    uid VARCHAR(255) NOT NULL,
+    surname VARCHAR(255) DEFAULT NULL,
+    givenName VARCHAR(255) DEFAULT NULL,
+    courseId VARCHAR(255) NOT NULL,
+    PRIMARY KEY (uid , courseId)
+);
+
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100');
+INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123');
+
diff --git a/demo/complex2s/test-resource-grouper.sh b/demo/complex2s/test-resource-grouper.sh
new file mode 100755
index 0000000..c0d5a65
--- /dev/null
+++ b/demo/complex2s/test-resource-grouper.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+test_resource 1eff65de-5bb6-483d-9edf-8cc2c2ee0233
diff --git a/demo/complex2s/test-resources-1.sh b/demo/complex2s/test-resources-1.sh
new file mode 100755
index 0000000..989ad9f
--- /dev/null
+++ b/demo/complex2s/test-resources-1.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+source $(dirname "$0")/../../library.bash
+
+test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
+test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+test_resource a343fc2e-3954-4034-ba1a-2b72c21e577a
+test_resource e417225d-8a08-46f3-9b5d-624990b52386
+test_resource fe805d13-481b-43ec-97d8-9d2df72cd38e
diff --git a/demo/complex2s/tests/main.bats b/demo/complex2s/tests/main.bats
new file mode 100644
index 0000000..4a781f7
--- /dev/null
+++ b/demo/complex2s/tests/main.bats
@@ -0,0 +1,355 @@
+#!/usr/bin/env bats
+
+load ../../../common
+load ../../../library
+
+@test "000 Cleanup before running the tests" {
+    (cd ../simple ; docker-compose down -v)
+    (cd ../shibboleth ; docker-compose down -v)
+    (cd ../postgresql ; docker-compose down -v)
+    docker-compose down -v
+}
+
+@test "010 Initialize and start the composition" {
+    # We want to fail cleanly if there's any interference
+    docker ps
+    ! (docker ps | grep -E "shibboleth_(idp|directory)_1|(complex|simple|shibboleth|postgresql)_(midpoint_server|midpoint_data)_1")
+    docker-compose build --pull grouper_daemon grouper_ui grouper_data directory sources targets midpoint_data idp mq
+    # Sometimes the tier/midpoint:xyz is not yet in the repository, causing issues with --pull
+    docker-compose build midpoint_server
+    docker-compose up -d
+}
+
+@test "020 Wait until components are started" {
+    touch $BATS_TMPDIR/not-started
+    wait_for_midpoint_start complex_midpoint_server_1 complex_midpoint_data_1
+    wait_for_shibboleth_idp_start complex_idp_1
+    wait_for_grouper_ui_start complex_grouper_ui_1
+    rm $BATS_TMPDIR/not-started
+}
+
+@test "040 Check midPoint health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+}
+
+@test "050 Check Shibboleth IDP health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health_shibboleth_idp
+}
+
+@test "060 Check Grouper health" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    skip TODO
+}
+
+@test "100 Get 'administrator'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    get_and_check_object users 00000000-0000-0000-0000-000000000002 administrator
+}
+
+@test "110 And and get 'test110'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    echo "<user><name>test110</name></user>" >/tmp/test110.xml
+    add_object users /tmp/test110.xml
+    rm /tmp/test110.xml
+    search_and_check_object users test110
+    delete_object_by_name users test110
+}
+
+@test "200 Upload objects" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    # reduce data in SIS database so imports will take reasonable time
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_COURSES where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_AFFILIATIONS where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+    docker exec complex_sources_1 mysql sis -u root -p123321 -e "delete from SIS_PERSONS where uid not in ('amorrison', 'banderson', 'cmorrison', 'danderson', 'ddavis', 'jsmith', 'kwhite', 'mroberts', 'whenderson', 'wprice')"
+
+    check_health
+    ./upload-objects.sh
+
+    search_and_check_object objectTemplates template-org-course
+    search_and_check_object objectTemplates template-org-department
+    search_and_check_object objectTemplates template-role-affiliation
+    search_and_check_object objectTemplates template-role-generic-group
+    
+    search_and_check_object orgs courses
+    search_and_check_object orgs departments
+
+    search_and_check_object resources "LDAP (directory)"
+    search_and_check_object resources "Grouper Resource"
+    search_and_check_object resources "SQL SIS courses (sources)"
+    search_and_check_object resources "SQL SIS persons (sources)"
+
+    search_and_check_object roles metarole-affiliation
+    search_and_check_object roles metarole-course
+    search_and_check_object roles metarole-department 
+    search_and_check_object roles metarole-generic-group
+    search_and_check_object roles role-grouper-sysadmin
+    search_and_check_object roles role-ldap-basic
+}
+
+@test "210 Test LDAP and SQL resources" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    test_resource 0a37121f-d515-4a23-9b6d-554c5ef61272
+    test_resource 13660d60-071b-4596-9aa1-5efcd1256c04
+    test_resource 4d70a0da-02dd-41cf-b0a1-00e75d3eaa15
+}
+
+@test "220 Import SIS_PERSONS" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-import-sis-persons.xml
+    search_and_check_object tasks "Import from SIS persons"
+    wait_for_task_completion 22c2a3d0-0961-4255-9eec-c550a79aeaaa 6 10
+    assert_task_success 22c2a3d0-0961-4255-9eec-c550a79aeaaa
+
+    search_and_check_object users jsmith
+    search_and_check_object users banderson
+    search_and_check_object users kwhite
+    search_and_check_object users whenderson
+    search_and_check_object users ddavis
+    search_and_check_object users cmorrison
+    search_and_check_object users danderson
+    search_and_check_object users amorrison
+    search_and_check_object users wprice
+    search_and_check_object users mroberts
+
+    check_ldap_account_by_user_name jsmith complex_directory_1
+    check_ldap_account_by_user_name banderson complex_directory_1
+    check_ldap_account_by_user_name kwhite complex_directory_1
+    check_ldap_account_by_user_name whenderson complex_directory_1
+    check_ldap_account_by_user_name ddavis complex_directory_1
+    check_ldap_account_by_user_name cmorrison complex_directory_1
+    check_ldap_account_by_user_name danderson complex_directory_1
+    check_ldap_account_by_user_name amorrison complex_directory_1
+    check_ldap_account_by_user_name wprice complex_directory_1
+    check_ldap_account_by_user_name mroberts complex_directory_1
+}
+
+@test "230 Import SIS_COURSES" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-import-sis-courses.xml
+    search_and_check_object tasks "Import from SIS courses"
+    wait_for_task_completion b73a2e66-8233-4c20-928f-acb30027b33e 8 10
+    assert_task_success b73a2e66-8233-4c20-928f-acb30027b33e
+
+    search_and_check_object orgs course_ACCT101
+    search_and_check_object orgs course_ACCT201
+    search_and_check_object orgs course_CS251
+    search_and_check_object orgs course_CS252
+    search_and_check_object orgs course_MATH100
+    search_and_check_object orgs course_MATH101
+    search_and_check_object orgs course_SCI123
+    search_and_check_object orgs course_SCI404
+
+    check_ldap_courses_by_name course_ACCT101 complex_directory_1
+    check_ldap_courses_by_name course_ACCT201 complex_directory_1
+    check_ldap_courses_by_name course_CS251 complex_directory_1
+    check_ldap_courses_by_name course_CS252 complex_directory_1
+    check_ldap_courses_by_name course_MATH100 complex_directory_1
+    check_ldap_courses_by_name course_MATH101 complex_directory_1
+    check_ldap_courses_by_name course_SCI123 complex_directory_1
+    check_ldap_courses_by_name course_SCI404 complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+    check_of_ldap_membership whenderson "ou=courses,ou=groups,dc=internet2,dc=edu" "ACCT101" complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership ddavis "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "CS251" complex_directory_1
+
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "CS252" complex_directory_1
+
+    check_of_ldap_membership danderson "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership ddavis "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+    check_of_ldap_membership wprice "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH100" complex_directory_1
+
+    check_of_ldap_membership amorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+    check_of_ldap_membership cmorrison "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "MATH101" complex_directory_1
+
+    check_of_ldap_membership danderson "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI123" complex_directory_1
+    check_of_ldap_membership mroberts "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI123" complex_directory_1
+
+    check_of_ldap_membership kwhite "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI404" complex_directory_1
+    check_of_ldap_membership wprice "ou=courses,ou=groups,dc=internet2,dc=edu" "SCI404" complex_directory_1
+}
+
+@test "240 Check 'TestUser240' in Midpoint and LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    echo "<user><name>TestUser240</name><fullName>Test User240</fullName><givenName>Test</givenName><familyName>User240</familyName><credentials><password><value><clearValue>password</clearValue></value></password></credentials></user>" >/tmp/testuser240.xml
+    add_object users /tmp/testuser240.xml
+    rm /tmp/testuser240.xml
+    search_and_check_object users TestUser240
+
+    execute_bulk_action tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml complex_midpoint_server_1
+    execute_bulk_action tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml complex_midpoint_server_1
+
+    check_ldap_account_by_user_name TestUser240 complex_directory_1
+    check_of_ldap_membership TestUser240 "ou=groups,dc=internet2,dc=edu" "sysadmingroup" complex_directory_1
+    
+    delete_object_by_name users TestUser240
+}
+
+@test "250 Make 'banderson' Grouper administrator" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    check_health
+    recompute roles d48ec05b-fffd-4262-acd3-d9ff63365b62
+    execute_bulk_action tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml complex_midpoint_server_1
+    recompute users e897468f-20bd-419c-8fc5-1fe60e2600de # for some reason this looks necessary (TODO)
+    check_of_ldap_membership banderson "ou=groups,dc=internet2,dc=edu" "sysadmingroup" complex_directory_1
+}
+
+#@test "255 Wait 120 seconds for changes to be propagated to Grouper" {
+#    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+#
+#    sleep 120
+#}
+
+@test "260 Export ref groups" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    ./add-ref-groups.sh
+}
+
+@test "265 Wait 120 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 120
+}
+
+@test "300 Test Grouper resource" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+    test_resource 1eff65de-5bb6-483d-9edf-8cc2c2ee0233
+}
+
+@test "310 Import Grouper-to-midPoint async update task" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    check_health
+    add_object tasks midpoint-objects-manual/tasks/task-async-update-grouper.xml
+    search_and_check_object tasks "Grouper async updates"
+}
+
+@test "320 Wait for the queue to become empty" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    ATTEMPT=0
+    MAX_ATTEMPTS=20
+    DELAY=10
+
+    get_messages sampleQueue
+    echo "Messages: $MESSAGES"
+
+    until [[ $ATTEMPT = $MAX_ATTEMPTS ]]; do
+        ATTEMPT=$((ATTEMPT+1))
+        get_messages sampleQueue
+        echo "Messages: $MESSAGES"
+        if [ "$MESSAGES" = "0" ]; then return 0; fi
+        echo "Waiting $DELAY seconds for the queue to become empty (attempt $ATTEMPT) ..."
+        sleep $DELAY
+    done
+    return 1
+}
+
+@test "330 Add wprice to 'midpoint:test' and 'ref:affiliation:alum_includes' groups" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t330.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t330.gsh"
+}
+
+@test "335 Wait 80 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 80
+}
+
+@test "340 Assert wprice membership in LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    assert_ldap_user_has_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_value wprice Entitlement "ref:affiliation:alum" complex_directory_1
+}
+
+@test "350 Add kwhite to 'midpoint:test', remove wprice from 'ref:affiliation:alum_includes'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t350.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t350.gsh"
+}
+
+@test "355 Wait 80 seconds for changes to be propagated to MQ" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    sleep 80
+}
+
+@test "360 Assert wprice and kwhite membership in LDAP" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    assert_ldap_user_has_value kwhite Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_no_value wprice Entitlement "ref:affiliation:alum" complex_directory_1
+}
+
+@test "400 Suspend async update task" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    suspend_task 47fc57bd-8c34-4555-9b9f-7087ff179860 complex_midpoint_server_1
+    wait_for_task_completion 47fc57bd-8c34-4555-9b9f-7087ff179860 5 10
+}
+
+@test "410 Remove kwhite and wprice from 'midpoint:test'" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    docker cp tests/resources/grouper/t410.gsh complex_grouper_daemon_1:/tmp/
+    docker exec complex_grouper_daemon_1 bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/t410.gsh"
+}
+
+@test "420 Reconcile Grouper" {
+    if [ -e $BATS_TMPDIR/not-started ]; then skip 'not started'; fi
+
+    add_object tasks midpoint-objects-manual/tasks/task-reconciliation-grouper-users.xml
+    search_and_check_object tasks "Grouper reconciliation (users)"
+    wait_for_task_completion 42aa9f43-64c5-41a6-814c-b58b9ea4e204 6 10
+    assert_task_success 42aa9f43-64c5-41a6-814c-b58b9ea4e204
+
+    search_and_check_object users jsmith
+    search_and_check_object users banderson
+    search_and_check_object users kwhite
+    search_and_check_object users whenderson
+    search_and_check_object users ddavis
+    search_and_check_object users cmorrison
+    search_and_check_object users danderson
+    search_and_check_object users amorrison
+    search_and_check_object users wprice
+    search_and_check_object users mroberts
+
+    check_ldap_account_by_user_name jsmith complex_directory_1
+    check_ldap_account_by_user_name banderson complex_directory_1
+    check_ldap_account_by_user_name kwhite complex_directory_1
+    check_ldap_account_by_user_name whenderson complex_directory_1
+    check_ldap_account_by_user_name ddavis complex_directory_1
+    check_ldap_account_by_user_name cmorrison complex_directory_1
+    check_ldap_account_by_user_name danderson complex_directory_1
+    check_ldap_account_by_user_name amorrison complex_directory_1
+    check_ldap_account_by_user_name wprice complex_directory_1
+    check_ldap_account_by_user_name mroberts complex_directory_1
+
+    assert_ldap_user_has_no_value wprice Entitlement "midpoint:test" complex_directory_1
+    assert_ldap_user_has_no_value kwhite Entitlement "midpoint:test" complex_directory_1
+}
+
+@test "999 Clean up" {
+    docker-compose down -v
+}
diff --git a/demo/complex2s/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml b/demo/complex2s/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml
new file mode 100644
index 0000000..9ec69a2
--- /dev/null
+++ b/demo/complex2s/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-banderson.xml
@@ -0,0 +1,22 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+   			  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+			  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+			  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+                    <s:type>c:UserType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>c:name</q:path>
+                            <q:value>banderson</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>assign</s:type>
+                        <s:parameter>
+                            <s:name>role</s:name>
+							<c:value xsi:type="xsd:string">d48ec05b-fffd-4262-acd3-d9ff63365b62</c:value>
+                        </s:parameter>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex2s/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml b/demo/complex2s/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml
new file mode 100644
index 0000000..0cb1a6b
--- /dev/null
+++ b/demo/complex2s/tests/resources/bulk-action/assign-role-grouper-sysadmin-to-test-user.xml
@@ -0,0 +1,22 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
+   			  xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+			  xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+			  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+                    <s:type>c:UserType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>c:name</q:path>
+                            <q:value>TestUser240</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>assign</s:type>
+                        <s:parameter>
+                            <s:name>role</s:name>
+							<c:value xsi:type="xsd:string">d48ec05b-fffd-4262-acd3-d9ff63365b62</c:value>
+                        </s:parameter>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex2s/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml b/demo/complex2s/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml
new file mode 100644
index 0000000..1356484
--- /dev/null
+++ b/demo/complex2s/tests/resources/bulk-action/recompute-role-grouper-sysadmin.xml
@@ -0,0 +1,16 @@
+<scext:executeScript xmlns:scext="http://midpoint.evolveum.com/xml/ns/public/model/scripting/extension-3"
+		     xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+		     xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
+                <s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
+                    <s:type>c:RoleType</s:type>
+                    <s:searchFilter>
+                        <q:equal>
+                            <q:path>name</q:path>
+                            <q:value>role-grouper-sysadmin</q:value>
+                        </q:equal>
+                    </s:searchFilter>
+                    <s:action>
+                        <s:type>recompute</s:type>
+                    </s:action>
+                </s:search>
+            </scext:executeScript>
diff --git a/demo/complex2s/tests/resources/grouper/t300.gsh b/demo/complex2s/tests/resources/grouper/t300.gsh
new file mode 100644
index 0000000..d2b63e3
--- /dev/null
+++ b/demo/complex2s/tests/resources/grouper/t300.gsh
@@ -0,0 +1,15 @@
+System.out.println("************** t300.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+exportedGroups = GroupFinder.findByName(gs, 'etc:exportedGroups')
+alumSubject = SubjectFinder.findByIdentifier('ref:affiliation:alum', 'group', 'g:gsa')
+exportedGroups.addMember(alumSubject, false)
+
+alumIncludes = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+testGroup = GroupFinder.findByName(gs, 'etc:testGroup')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+alumIncludes.addMember(wprice, false)
+testGroup.addMember(wprice, false)
+
+System.out.println("************** t300.gsh done **************");
diff --git a/demo/complex2s/tests/resources/grouper/t330.gsh b/demo/complex2s/tests/resources/grouper/t330.gsh
new file mode 100644
index 0000000..cb8f158
--- /dev/null
+++ b/demo/complex2s/tests/resources/grouper/t330.gsh
@@ -0,0 +1,11 @@
+System.out.println("************** t330.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+alumIncludesGroup = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.addMember(wprice, false)
+alumIncludesGroup.addMember(wprice, false)
+
+System.out.println("************** t330.gsh done **************");
diff --git a/demo/complex2s/tests/resources/grouper/t350.gsh b/demo/complex2s/tests/resources/grouper/t350.gsh
new file mode 100644
index 0000000..d0d2d3e
--- /dev/null
+++ b/demo/complex2s/tests/resources/grouper/t350.gsh
@@ -0,0 +1,12 @@
+System.out.println("************** t350.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+alumIncludes = GroupFinder.findByName(gs, 'ref:affiliation:alum_includes')
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+kwhite = SubjectFinder.findById('kwhite', 'person', 'ldap')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.addMember(kwhite, false)
+alumIncludes.deleteMember(wprice, false)
+
+System.out.println("************** t350.gsh done **************");
diff --git a/demo/complex2s/tests/resources/grouper/t410.gsh b/demo/complex2s/tests/resources/grouper/t410.gsh
new file mode 100644
index 0000000..69e4b18
--- /dev/null
+++ b/demo/complex2s/tests/resources/grouper/t410.gsh
@@ -0,0 +1,11 @@
+System.out.println("************** t410.gsh starting **************");
+
+gs = GrouperSession.startRootSession()
+
+testGroup = GroupFinder.findByName(gs, 'midpoint:test')
+kwhite = SubjectFinder.findById('kwhite', 'person', 'ldap')
+wprice = SubjectFinder.findById('wprice', 'person', 'ldap')
+testGroup.deleteMember(kwhite, false)
+testGroup.deleteMember(wprice, false)
+
+System.out.println("************** t410.gsh done **************");
diff --git a/demo/complex2s/tests/resources/rabbitmq/check-samplequeue.sh b/demo/complex2s/tests/resources/rabbitmq/check-samplequeue.sh
new file mode 100755
index 0000000..e336a63
--- /dev/null
+++ b/demo/complex2s/tests/resources/rabbitmq/check-samplequeue.sh
@@ -0,0 +1,8 @@
+count=$(rabbitmqctl list_queues | grep sampleQueue | awk '{print $2}')
+if [[ -z $count || $count -eq 0 ]]; then
+    echo "ERROR: sampleQueue does not exist or is empty"
+    exit 1
+else
+    echo "OK: sampleQueue has $count message(s)"
+    exit 0
+fi
diff --git a/demo/complex2s/tests/resources/tasks/task-livesync-grouper-single.xml b/demo/complex2s/tests/resources/tasks/task-livesync-grouper-single.xml
new file mode 100644
index 0000000..365d007
--- /dev/null
+++ b/demo/complex2s/tests/resources/tasks/task-livesync-grouper-single.xml
@@ -0,0 +1,29 @@
+<task xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
+      xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
+      xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
+      oid="87ffce52-717a-4205-ba01-0a698f0deaee">
+   <name>LiveSync from Grouper</name>
+   <extension xmlns:mext="http://midpoint.evolveum.com/xml/ns/public/model/extension-3"
+              xmlns:gen437="http://midpoint.evolveum.com/xml/ns/public/provisioning/liveSync-3"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:type="c:ExtensionType">
+      <mext:kind>account</mext:kind>
+      <mext:objectclass>ri:AccountObjectClass</mext:objectclass>
+   </extension>
+   <taskIdentifier>1535465478027-0-1</taskIdentifier>
+   <ownerRef oid="00000000-0000-0000-0000-000000000002"
+             relation="org:default"
+             type="c:UserType"><!-- administrator --></ownerRef>
+   <executionStatus>runnable</executionStatus>
+   <category>LiveSynchronization</category>
+   <handlerUri>http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/live-sync/handler-3</handlerUri>
+   <objectRef oid="6dcb84f5-bf82-4931-9072-fbdf87f96442"
+              relation="org:default"
+              type="c:ResourceType"><!-- Grouper SQL NEW --></objectRef>
+   <recurrence>single</recurrence>
+   <binding>loose</binding>
+</task>
diff --git a/demo/complex2s/tests/resources/users/user-grouper-admin.xml b/demo/complex2s/tests/resources/users/user-grouper-admin.xml
new file mode 100644
index 0000000..d785e47
--- /dev/null
+++ b/demo/complex2s/tests/resources/users/user-grouper-admin.xml
@@ -0,0 +1,20 @@
+<user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" 
+      xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
+      xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3" 
+      oid="a0c7c01e-c203-4777-9b21-27a4735da3ae">
+    <name>grouper-admin</name>
+    <assignment id="1">
+        <targetRef oid="d48ec05b-fffd-4262-acd3-d9ff63365b62" relation="org:default" type="c:RoleType">
+            <!-- role-grouper-sysadmin -->
+        </targetRef>
+    </assignment>
+    <fullName>Grouper admin</fullName>
+    <givenName>Grouper</givenName>
+    <familyName>Admin</familyName>
+    <credentials>
+        <password>
+            <value>password</value>
+        </password>
+    </credentials>
+</user>
+	
diff --git a/demo/complex2s/update-bgasper-in-grouper.gsh b/demo/complex2s/update-bgasper-in-grouper.gsh
new file mode 100644
index 0000000..b0ed0b2
--- /dev/null
+++ b/demo/complex2s/update-bgasper-in-grouper.gsh
@@ -0,0 +1,13 @@
+
+def add(gs,groupName,subject) {
+	GroupFinder.findByName(gs, groupName, true).addMember(subject, false)
+}
+
+gs = GrouperSession.startRootSession()
+
+def bgasper = SubjectFinder.findById('bgasper', 'user', 'ldap')
+add(gs, 'ref:affiliation:alum_excludes', bgasper)
+add(gs, 'ref:affiliation:faculty_includes', bgasper)
+add(gs, 'app:mailinglist:chess', bgasper)
+add(gs, 'app:mailinglist:idm-fans', bgasper)
+add(gs, 'test:volunteers', bgasper)
diff --git a/demo/complex2s/update-bgasper-in-grouper.sh b/demo/complex2s/update-bgasper-in-grouper.sh
new file mode 100755
index 0000000..78d9912
--- /dev/null
+++ b/demo/complex2s/update-bgasper-in-grouper.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+execute_gsh complex2s_grouper_daemon_1 update-bgasper-in-grouper.gsh
diff --git a/demo/complex2s/upload-async-update-task.sh b/demo/complex2s/upload-async-update-task.sh
new file mode 100755
index 0000000..bdf8ba2
--- /dev/null
+++ b/demo/complex2s/upload-async-update-task.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-async-update-grouper.xml
diff --git a/demo/complex2s/upload-import-sis-persons.sh b/demo/complex2s/upload-import-sis-persons.sh
new file mode 100755
index 0000000..058c9af
--- /dev/null
+++ b/demo/complex2s/upload-import-sis-persons.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-import-sis-persons.xml
diff --git a/demo/complex2s/upload-objects.sh b/demo/complex2s/upload-objects.sh
new file mode 100755
index 0000000..3f1c9b8
--- /dev/null
+++ b/demo/complex2s/upload-objects.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+function upload () {
+  local filename=$1
+  local regex="midpoint-objects/(.*)/(.*)"
+  if [[ $filename =~ $regex ]]
+  then
+    type="${BASH_REMATCH[1]}"
+    oid=`cat $filename | sed -n 's:.*oid=\"\([A-Za-z0-9\-]*\)\".*:\1:p' | sed -n '1 p'`
+    echo "Uploading $filename ($type, $oid)"
+    curl -k --user administrator:5ecr3t -H "Content-Type: application/xml" -X PUT "https://localhost:8443/midpoint/ws/rest/$type/$oid?options=overwrite&options=raw" --data-binary @$filename
+  else
+    echo "Skipping $filename"
+  fi
+}
+
+find midpoint-objects -name "*.xml" | while read filename; do upload $filename; done
diff --git a/demo/complex2s/upload-recompute-users.sh b/demo/complex2s/upload-recompute-users.sh
new file mode 100644
index 0000000..42b5551
--- /dev/null
+++ b/demo/complex2s/upload-recompute-users.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-recomputation-users.xml
diff --git a/demo/complex2s/upload-reconcile-grouper-groups.sh b/demo/complex2s/upload-reconcile-grouper-groups.sh
new file mode 100755
index 0000000..94deb18
--- /dev/null
+++ b/demo/complex2s/upload-reconcile-grouper-groups.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+source ../../library.bash
+
+upload_from_file midpoint-objects-manual/tasks/task-reconciliation-grouper-groups.xml
diff --git a/demo/perf-testing/sis_100k_users.zip b/demo/perf-testing/sis_100k_users.zip
new file mode 100644
index 0000000..05cf419
Binary files /dev/null and b/demo/perf-testing/sis_100k_users.zip differ
diff --git a/demo/perf-testing/sis_10k_users.zip b/demo/perf-testing/sis_10k_users.zip
new file mode 100644
index 0000000..ce040af
Binary files /dev/null and b/demo/perf-testing/sis_10k_users.zip differ
diff --git a/demo/perf-testing/sis_1k_users.zip b/demo/perf-testing/sis_1k_users.zip
new file mode 100644
index 0000000..9155bf8
Binary files /dev/null and b/demo/perf-testing/sis_1k_users.zip differ
diff --git a/library.bash b/library.bash
index 533384b..d70e694 100644
--- a/library.bash
+++ b/library.bash
@@ -304,7 +304,7 @@ function search_objects_by_name () {
 EOF
     local HTTP_CODE=$(sed '$!d' <<<"$(cat $TMPFILE)")
     sed -i '$ d' $TMPFILE
-    cat $TMPFILE
+    # cat $TMPFILE
 
     if [ "$HTTP_CODE" -eq 200 ]; then
         SEARCH_RESULT_FILE=$TMPFILE
@@ -418,6 +418,14 @@ function wait_for_task_completion () {
     return 1
 }
 
+function get_task_execution_status () {
+    local NAME=$1
+
+    search_objects_by_name tasks "$NAME"
+    TASK_EXECUTION_STATUS=$(xmllint --xpath "/*/*/*[local-name()='executionStatus']/text()" $SEARCH_RESULT_FILE) || (echo "Couldn't extract task status from task $NAME" ; cat $SEARCH_RESULT_FILE ; rm $SEARCH_RESULT_FILE ; return 1)
+    echo "Task execution status: $TASK_EXECUTION_STATUS"
+    return 0
+}
 
 function search_ldap_object_by_filter () {
     local BASE_CONTEXT_FOR_SEARCH=$1
@@ -556,3 +564,25 @@ function get_messages () {
     fi
     return 0
 }
+
+function upload_from_file () {
+  local FILENAME=$1
+  local OPTIONS_TO_ADD=$2
+  local REGEX="midpoint-objects.*/(.*)/(.*)"
+  if [[ $FILENAME =~ $REGEX ]]
+  then
+    TYPE="${BASH_REMATCH[1]}"
+    OID=`cat $FILENAME | sed -n 's:.*oid=\"\([A-Za-z0-9\-]*\)\".*:\1:p' | sed -n '1 p'`
+    echo "Uploading $FILENAME ($TYPE, $OID)"
+    curl -k --user administrator:5ecr3t -H "Content-Type: application/xml" -X PUT "https://localhost:8443/midpoint/ws/rest/$TYPE/$OID?options=overwrite$OPTIONS_TO_ADD" --data-binary @$FILENAME
+  else
+    echo "Skipping $FILENAME"
+  fi
+}
+
+function execute_gsh () {
+  local CONTAINER=$1
+  local FILE=$2
+  docker cp $FILE $CONTAINER:/tmp/
+  docker exec $CONTAINER bash -c "/opt/grouper/grouper.apiBinary/bin/gsh /tmp/$FILE"
+}