[java-identity-provider] 20/27: Parser changes to retrofit resolver to produce transcoding rules.

Scott Cantor cantor.2 at osu.edu
Fri May 3 14:32:10 EDT 2019


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch feature/IDP-1434
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=f43e512ca404fe55beb9d93d0868790b90b2842b

commit f43e512ca404fe55beb9d93d0868790b90b2842b
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed May 1 15:07:41 2019 -0400

    Parser changes to retrofit resolver to produce transcoding rules.
---
 .../spring/ad/BaseAttributeDefinitionParser.java   |  11 ---
 .../spring/enc/BaseAttributeEncoderParser.java     | 110 +++++++++++----------
 .../enc/BaseSAML1AttributeEncoderParser.java       |  59 +++++++++++
 .../enc/BaseSAML2AttributeEncoderParser.java       |  64 ++++++++++++
 .../enc/BaseScopedAttributeEncoderParser.java      |  59 -----------
 .../impl/SAML1Base64AttributeEncoderParser.java    |  37 ++-----
 .../SAML1ScopedStringAttributeEncoderParser.java   |  55 ++++++-----
 .../impl/SAML1StringAttributeEncoderParser.java    |  43 ++------
 .../impl/SAML1XMLObjectAttributeEncoderParser.java |  37 ++-----
 .../impl/SAML2Base64AttributeEncoderParser.java    |  42 ++------
 .../SAML2ScopedStringAttributeEncoderParser.java   |  58 +++++------
 .../impl/SAML2StringAttributeEncoderParser.java    |  43 ++------
 .../impl/SAML2XMLObjectAttributeEncoderParser.java |  43 ++------
 .../spring/impl/AttributeResolverParser.java       |  18 ++--
 .../spring/BaseAttributeDefinitionParserTest.java  |  10 +-
 .../spring/ad/SimpleAttributeParserTest.java       |  37 +------
 .../attribute/resolver/spring/enc/Regressions.java |  20 ++--
 .../enc/SAML1Base64AttributeEncoderParserTest.java |  41 +++++---
 ...AML1ScopedStringAttributeEncoderParserTest.java |  60 ++++++-----
 .../enc/SAML1StringAttributeEncoderParserTest.java |  44 ++++++---
 .../SAML1XMLObjectAttributeEncoderParserTest.java  |  43 +++++---
 .../enc/SAML2Base64AttributeEncoderParserTest.java |  46 ++++++---
 ...AML2ScopedStringAttributeEncoderParserTest.java |  60 ++++++-----
 .../enc/SAML2StringAttributeEncoderParserTest.java |  81 ++++++---------
 .../SAML2XMLObjectAttributeEncoderParserTest.java  |  49 +++++----
 .../idp/attribute/resolver/spring/customBean.xml   |   8 +-
 .../resolver/spring/enc/resolver/idp-571.xml       |   3 -
 .../resolver/spring/enc/resolver/saml1Base64.xml   |  10 +-
 .../spring/enc/resolver/saml1Base64Default.xml     |   4 +-
 .../resolver/spring/enc/resolver/saml1Scoped.xml   |   8 +-
 .../spring/enc/resolver/saml1ScopedDefault.xml     |   3 +-
 .../resolver/spring/enc/resolver/saml1String.xml   |  10 +-
 .../spring/enc/resolver/saml1StringDefault.xml     |   3 +-
 .../spring/enc/resolver/saml1XmlObject.xml         |  10 +-
 .../spring/enc/resolver/saml1XmlObjectDefault.xml  |   1 +
 .../resolver/spring/enc/resolver/saml2Base64.xml   |   9 +-
 .../spring/enc/resolver/saml2Base64Default.xml     |   1 +
 .../resolver/spring/enc/resolver/saml2Scoped.xml   |   9 +-
 .../spring/enc/resolver/saml2ScopedDefault.xml     |   1 +
 .../resolver/spring/enc/resolver/saml2String.xml   |   3 +-
 .../spring/enc/resolver/saml2StringConditional.xml |   2 +-
 .../spring/enc/resolver/saml2StringDefault.xml     |   1 +
 .../spring/enc/resolver/saml2XmlObject.xml         |   8 +-
 .../spring/enc/resolver/saml2XmlObjectDefault.xml  |   1 +
 .../src/main/resources/conf/attribute-registry.xml |   2 +
 .../main/resources/system/conf/services-system.xml |   1 +
 .../impl/AddAttributeStatementToAssertion.java     |  42 +-------
 .../impl/AddAttributeStatementToAssertion.java     |  42 +-------
 48 files changed, 649 insertions(+), 703 deletions(-)

diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/BaseAttributeDefinitionParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/BaseAttributeDefinitionParser.java
index 5b83ed8..0e85bc5 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/BaseAttributeDefinitionParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/ad/BaseAttributeDefinitionParser.java
@@ -31,7 +31,6 @@ import org.springframework.beans.factory.support.ManagedMap;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.w3c.dom.Element;
 
-import net.shibboleth.ext.spring.util.SpringSupport;
 import net.shibboleth.idp.attribute.resolver.spring.BaseResolverPluginParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -87,16 +86,6 @@ public abstract class BaseAttributeDefinitionParser extends BaseResolverPluginPa
             log.debug("{} Setting dependencyOnly {}", getLogPrefix(), dependencyOnly);
             builder.addPropertyValue("dependencyOnly", dependencyOnly);
         }
-
-        final List<Element> attributeEncoders =
-                ElementSupport.getChildElements(config, new QName(AttributeResolverNamespaceHandler.NAMESPACE,
-                        "AttributeEncoder"));
-
-        if (attributeEncoders != null && !attributeEncoders.isEmpty()) {
-            log.debug("{} Adding {} encoders", getLogPrefix(), attributeEncoders.size());
-            builder.addPropertyValue("attributeEncoders",
-                    SpringSupport.parseCustomElements(attributeEncoders, parserContext));
-        }
     }
     // CheckStyle: CyclomaticComplexity ON
 
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseAttributeEncoderParser.java
index 0250547..39095e8 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseAttributeEncoderParser.java
@@ -17,11 +17,13 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
+import java.util.Collections;
+import java.util.Map;
+
 import javax.annotation.Nonnull;
 
-import net.shibboleth.ext.spring.util.SpringSupport;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.profile.logic.RelyingPartyIdPredicate;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
 import net.shibboleth.idp.profile.logic.ScriptedPredicate;
 import net.shibboleth.idp.profile.spring.relyingparty.metadata.ScriptTypeBeanParser;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -30,8 +32,10 @@ import net.shibboleth.utilities.java.support.xml.ElementSupport;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedMap;
 import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.w3c.dom.Element;
@@ -47,77 +51,83 @@ public abstract class BaseAttributeEncoderParser extends AbstractSingleBeanDefin
     /** Log4j logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(BaseAttributeEncoderParser.class);
 
-    /** Whether the name property is required or not. */
-    private boolean nameRequired;
-
-    /** Constructor. */
-    public BaseAttributeEncoderParser() {
-        nameRequired = false;
+    /** {@inheritDoc} */
+    @Override
+    protected Class<?> getBeanClass(final Element element) {
+        return Collections.class;
     }
-
-    /**
-     * Set whether the name property is required or not.
-     * 
-     * @param flag flag to set
-     */
-    public void setNameRequired(final boolean flag) {
-        nameRequired = flag;
+    
+    /** {@inheritDoc} */
+    @Override
+    protected boolean shouldGenerateId() {
+        return true;
     }
 
     /** {@inheritDoc} */
-    @Override protected void doParse(final Element config, final ParserContext parserContext,
-            final BeanDefinitionBuilder builder) {
+    @Override
+    protected boolean shouldParseNameAsAliases() {
+        return false;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected void doParse(final Element config, final ParserContext context, final BeanDefinitionBuilder builder) {
 
-        super.doParse(config, parserContext, builder);
+        final ManagedMap rule = new ManagedMap();
+
+        builder.setFactoryMethod("singletonList");
+        builder.addConstructorArgValue(rule);
         
-        final String attributeName = StringSupport.trimOrNull(config.getAttributeNS(null, NAME_ATTRIBUTE_NAME));
-        if (nameRequired && attributeName == null) {
-            throw new BeanCreationException("Attribute encoder must contain a name property");
+        if (config.getParentNode() instanceof Element && ((Element)config.getParentNode()).hasAttributeNS(null, "id")) {
+            rule.put(AttributeTranscoderRegistry.PROP_ID,
+                    StringSupport.trimOrNull(((Element) config.getParentNode()).getAttributeNS(null, "id")));
+        } else {
+            log.warn("Parsing AttributeEncoder with no parent element, resulting rule will be ignored");
         }
 
         if (config.hasAttributeNS(null, "activationConditionRef")) {
             if (config.hasAttributeNS(null, "relyingParties")) {
                 log.warn("relyingParties ignored, using activationConditionRef");
             }
-            builder.addPropertyReference("activationCondition",
-                    StringSupport.trimOrNull(config.getAttributeNS(null, "activationConditionRef")));
+            rule.put(AttributeTranscoderRegistry.PROP_CONDITION, new RuntimeBeanReference(
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "activationConditionRef"))));
         } else if (config.hasAttributeNS(null, "relyingParties")) {
-            final BeanDefinitionBuilder rpBuilder =
-                    BeanDefinitionBuilder.genericBeanDefinition(RelyingPartyIdPredicate.class);
-            rpBuilder.setFactoryMethod("fromCandidates");
-            rpBuilder .addConstructorArgValue(
-                    SpringSupport.getAttributeValueAsList(config.getAttributeNodeNS(null, "relyingParties")));
-            builder.addPropertyValue("activationCondition", rpBuilder.getBeanDefinition());
+            rule.put(AttributeTranscoderRegistry.PROP_RELYINGPARTIES, config.getAttributeNS(null, "relyingParties"));
         } else {
             final Element child = ElementSupport.getFirstChildElement(config);
             if (child != null && ElementSupport.isElementNamed(child,
                     AttributeResolverNamespaceHandler.NAMESPACE, "ActivationConditionScript")) {
-                builder.addPropertyValue("activationCondition",
+                rule.put(AttributeTranscoderRegistry.PROP_CONDITION,
                         ScriptTypeBeanParser.parseScriptType(ScriptedPredicate.class, child).getBeanDefinition());
             }
         }
 
-        if (config.hasAttributeNS(null, "encodeType")) {
-            builder.addPropertyValue("encodeType", StringSupport.trimOrNull(config.getAttributeNS(null, "encodeType")));
-        }
-
-        builder.setInitMethodName("initialize");
-        builder.setDestroyMethodName("destroy");
-        builder.addPropertyValue("name", attributeName);
-
+        final BeanDefinition transcoder = buildTranscoder();
+        
+        transcoder.setInitMethodName("initialize");
+        transcoder.setDestroyMethodName("destroy");
+        
+        rule.put(AttributeTranscoderRegistry.PROP_TRANSCODER, transcoder);
+        
+        doParse(config, context, rule);
     }
+    
+    /**
+     * Inject any necessary elements into the mapping rule based on the specific encoder type.
+     * 
+     * @param config the encoder element being parsed
+     * @param parserContext the parser context
+     * @param rule the mapping rule
+     */
+    protected abstract void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
+            @Nonnull final Map<String,Object> rule);
 
-    /** {@inheritDoc} */
-    @Override public boolean shouldGenerateId() {
-        return true;
-    }
 
     /**
-     * {@inheritDoc}. <br/>
-     * We parse the attribute "name" and we do not want Spring to. see #IDP-571.
+     * Return a bean definition for the transcoder to include in the mapping.
+     * 
+     * @return bean definition for an AttributeTranscoder
      */
-    @Override protected boolean shouldParseNameAsAliases() {
-        return false;
-    }
-
+    @Nonnull protected abstract BeanDefinition buildTranscoder();
+    
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseSAML1AttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseSAML1AttributeEncoderParser.java
new file mode 100644
index 0000000..8d01a90
--- /dev/null
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseSAML1AttributeEncoderParser.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.
+ */
+
+package net.shibboleth.idp.attribute.resolver.spring.enc;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML1AttributeTranscoder;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Base class for Spring bean definition parser for SAML 1 attribute encoders.
+ */
+public abstract class BaseSAML1AttributeEncoderParser extends BaseAttributeEncoderParser {
+    
+    /** {@inheritDoc} */
+    @Override
+    protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
+            @Nonnull final Map<String,Object> rule) {
+        
+        if (config.hasAttributeNS(null, "name")) {
+            rule.put(AbstractSAML1AttributeTranscoder.PROP_NAME,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "name")));
+        } else {
+            throw new BeanDefinitionStoreException("Missing 'name' attribute, cannot create transcoder rule");
+        }
+
+        if (config.hasAttributeNS(null, "namespace")) {
+            rule.put(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "namespace")));
+        }
+
+        if (config.hasAttributeNS(null, "encodeType")) {
+            rule.put(AbstractSAML1AttributeTranscoder.PROP_ENCODE_TYPE,
+                    Boolean.valueOf(StringSupport.trimOrNull(config.getAttributeNS(null, "encodeType"))));
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseSAML2AttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseSAML2AttributeEncoderParser.java
new file mode 100644
index 0000000..eb86f35
--- /dev/null
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseSAML2AttributeEncoderParser.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.
+ */
+
+package net.shibboleth.idp.attribute.resolver.spring.enc;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML2AttributeTranscoder;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Base class for Spring bean definition parser for SAML 1 attribute encoders.
+ */
+public abstract class BaseSAML2AttributeEncoderParser extends BaseAttributeEncoderParser {
+    
+    /** {@inheritDoc} */
+    @Override
+    protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
+            @Nonnull final Map<String,Object> rule) {
+
+        if (config.hasAttributeNS(null, "name")) {
+            rule.put(AbstractSAML2AttributeTranscoder.PROP_NAME,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "name")));
+        } else {
+            throw new BeanDefinitionStoreException("Missing 'name' attribute, cannot create transcoder rule");
+        }
+
+        if (config.hasAttributeNS(null, "nameFormat")) {
+            rule.put(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "nameFormat")));
+        }
+        
+        if (config.hasAttributeNS(null, "friendlyName")) {
+            rule.put(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "friendlyName")));
+        }
+                
+        if (config.hasAttributeNS(null, "encodeType")) {
+            rule.put(AbstractSAML2AttributeTranscoder.PROP_ENCODE_TYPE,
+                    Boolean.valueOf(StringSupport.trimOrNull(config.getAttributeNS(null, "encodeType"))));
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseScopedAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseScopedAttributeEncoderParser.java
deleted file mode 100644
index 18aea46..0000000
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/BaseScopedAttributeEncoderParser.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements.  See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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.
- */
-
-package net.shibboleth.idp.attribute.resolver.spring.enc;
-
-import javax.annotation.Nonnull;
-
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
-
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
-
-/**
- * Base class for Spring bean definition parser for Shibboleth scoped attribute encoders.
- */
-public abstract class BaseScopedAttributeEncoderParser extends BaseAttributeEncoderParser {
-
-    /** Local name of scope type attribute. */
-    @Nonnull @NotEmpty public static final String SCOPE_TYPE_ATTRIBUTE_NAME = "scopeType";
-
-    /** Local name of scope delimiter attribute. */
-    @Nonnull @NotEmpty public static final String SCOPE_DELIMITER_ATTRIBUTE_NAME = "scopeDelimiter";
-
-    /** Local name of scope attribute attribute. */
-    @Nonnull @NotEmpty public static final String SCOPE_ATTRIBUTE_ATTRIBUTE_NAME = "scopeAttribute";
-
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, SCOPE_DELIMITER_ATTRIBUTE_NAME)) {
-            builder.addPropertyValue("scopeDelimiter",
-                    StringSupport.trimOrNull(config.getAttributeNS(null, SCOPE_DELIMITER_ATTRIBUTE_NAME)));
-        }
-
-        if (config.hasAttributeNS(null, SCOPE_ATTRIBUTE_ATTRIBUTE_NAME)) {
-            builder.addPropertyValue("scopeAttributeName",
-                    StringSupport.trimOrNull(config.getAttributeNS(null, SCOPE_ATTRIBUTE_ATTRIBUTE_NAME)));
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1Base64AttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1Base64AttributeEncoderParser.java
index fd06ee2..d1a3a30 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1Base64AttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1Base64AttributeEncoderParser.java
@@ -18,49 +18,28 @@
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML1AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1ByteAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1ByteAttributeTranscoder;
 
 /**
- * Spring Bean Definition Parser for {@link SAML1ByteAttributeEncoder}.
+ * Spring Bean Definition Parser for {@link SAML1ByteAttributeTranscoder}.
  */
-public class SAML1Base64AttributeEncoderParser extends BaseAttributeEncoderParser {
+public class SAML1Base64AttributeEncoderParser extends BaseSAML1AttributeEncoderParser {
 
     /** Schema type name. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE, 
             "SAML1Base64");
 
-    /** Local name of namespace attribute. */
-    @Nonnull @NotEmpty public static final String NAMESPACE_ATTRIBUTE_NAME = "namespace";
-
-    /** Constructor. */
-    public SAML1Base64AttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
     /** {@inheritDoc} */
-    @Override protected Class<SAML1ByteAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML1ByteAttributeEncoder.class;
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(SAML1ByteAttributeTranscoder.class).getBeanDefinition();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME)) {
-            final String namespace = StringSupport.trimOrNull(config.getAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME));
-            builder.addPropertyValue("namespace", namespace);
-        }
-    }
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1ScopedStringAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1ScopedStringAttributeEncoderParser.java
index 3b39b37..1c9c662 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1ScopedStringAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1ScopedStringAttributeEncoderParser.java
@@ -17,55 +17,56 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
+import java.util.Map;
+
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseScopedAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML1AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1ScopedStringAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1ScopedStringAttributeTranscoder;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 /**
- * Spring Bean Definition Parser for {@link SAML1ScopedStringAttributeEncoder}.
+ * Spring Bean Definition Parser for {@link SAML1ScopedStringAttributeTranscoder}.
  */
-public class SAML1ScopedStringAttributeEncoderParser extends BaseScopedAttributeEncoderParser {
+public class SAML1ScopedStringAttributeEncoderParser extends BaseSAML1AttributeEncoderParser {
 
     /** Schema type name. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE,
             "SAML1ScopedString");
 
-    /** Local name of namespace attribute. */
-    @Nonnull @NotEmpty public static final String NAMESPACE_ATTRIBUTE_NAME = "namespace";
-
-    /** Constructor. */
-    public SAML1ScopedStringAttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Class<SAML1ScopedStringAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML1ScopedStringAttributeEncoder.class;
-    }
-
     /** {@inheritDoc} */
     @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
+            @Nonnull final Map<String,Object> rule) {
+        super.doParse(config, parserContext, rule);
 
-        if (config.hasAttributeNS(null, SCOPE_TYPE_ATTRIBUTE_NAME)) {
-            builder.addPropertyValue("scopeType",
-                    StringSupport.trimOrNull(config.getAttributeNS(null, SCOPE_TYPE_ATTRIBUTE_NAME)));
+        if (config.hasAttributeNS(null, "scopeType")) {
+            rule.put(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_TYPE,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "scopeType")));
+        }
+        
+        if (config.hasAttributeNS(null, "scopeDelimiter")) {
+            rule.put(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_DELIMITER,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "scopeDelimiter")));
         }
 
-        if (config.hasAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME)) {
-            final String namespace = StringSupport.trimOrNull(config.getAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME));
-            builder.addPropertyValue("namespace", namespace);
+        if (config.hasAttributeNS(null, "scopeAttribute")) {
+            rule.put(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_ATTR_NAME,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "scopeAttribute")));
         }
     }
+
+    /** {@inheritDoc} */
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(
+                SAML1ScopedStringAttributeTranscoder.class).getBeanDefinition();
+    }
+
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1StringAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1StringAttributeEncoderParser.java
index a7a4768..153e479 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1StringAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1StringAttributeEncoderParser.java
@@ -18,55 +18,28 @@
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
-import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML1AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1StringAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1StringAttributeTranscoder;
 
 /**
- * Spring Bean Definition Parser for {@link SAML1StringAttributeEncoder}.
+ * Spring Bean Definition Parser for {@link SAML1StringAttributeTranscoder}.
  */
-public class SAML1StringAttributeEncoderParser extends BaseAttributeEncoderParser {
+public class SAML1StringAttributeEncoderParser extends BaseSAML1AttributeEncoderParser {
 
     /** Schema type name.. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE, 
             "SAML1String");
 
-    /** Local name of namespace attribute. */
-    @Nonnull @NotEmpty public static final String NAMESPACE_ATTRIBUTE_NAME = "namespace";
-
-    /** Constructor. */
-    public SAML1StringAttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
     /** {@inheritDoc} */
-    @Override protected Class<SAML1StringAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML1StringAttributeEncoder.class;
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(SAML1StringAttributeTranscoder.class).getBeanDefinition();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME)) {
-            final String namespace = StringSupport.trimOrNull(config.getAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME));
-            builder.addPropertyValue("namespace", namespace);
-        }
-
-        final String attributeName = StringSupport.trimOrNull(config.getAttributeNS(null, "name"));
-        if (attributeName == null) {
-            throw new BeanCreationException("SAML 1 attribute encoders must contain a name");
-        }
-    }
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1XMLObjectAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1XMLObjectAttributeEncoderParser.java
index 21ebb73..c76d5b7 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1XMLObjectAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML1XMLObjectAttributeEncoderParser.java
@@ -18,47 +18,26 @@
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML1AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1XMLObjectAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1XMLObjectAttributeTranscoder;
 
-/** Spring Bean Definition Parser for {@link SAML1XMLObjectAttributeEncoder}. */
-public class SAML1XMLObjectAttributeEncoderParser extends BaseAttributeEncoderParser {
+/** Spring Bean Definition Parser for {@link SAML1XMLObjectAttributeTranscoder}. */
+public class SAML1XMLObjectAttributeEncoderParser extends BaseSAML1AttributeEncoderParser {
 
     /** Schema type name.. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER =
             new QName(AttributeResolverNamespaceHandler.NAMESPACE, "SAML1XMLObject");
 
-    /** Local name of namespace attribute. */
-    @Nonnull @NotEmpty public static final String NAMESPACE_ATTRIBUTE_NAME = "namespace";
-
-    /** Constructor. */
-    public SAML1XMLObjectAttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
     /** {@inheritDoc} */
-    @Override protected Class<SAML1XMLObjectAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML1XMLObjectAttributeEncoder.class;
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(SAML1XMLObjectAttributeTranscoder.class).getBeanDefinition();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME)) {
-            final String namespace = StringSupport.trimOrNull(config.getAttributeNS(null, NAMESPACE_ATTRIBUTE_NAME));
-            builder.addPropertyValue("namespace", namespace);
-        }
-    }
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2Base64AttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2Base64AttributeEncoderParser.java
index b8ac4fc..c2c5180 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2Base64AttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2Base64AttributeEncoderParser.java
@@ -18,54 +18,28 @@
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML2AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2ByteAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2ByteAttributeTranscoder;
 
 /**
- * Spring Bean Definition Parser for {@link SAML2ByteAttributeEncoder}.
+ * Spring Bean Definition Parser for {@link SAML2ByteAttributeTranscoder}.
  */
-public class SAML2Base64AttributeEncoderParser extends BaseAttributeEncoderParser {
+public class SAML2Base64AttributeEncoderParser extends BaseSAML2AttributeEncoderParser {
 
     /** Schema type name.. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE, 
             "SAML2Base64");
 
-    /** Local name of name format attribute. */
-    @Nonnull @NotEmpty public static final String NAME_FORMAT_ATTRIBUTE_NAME = "nameFormat";
-
-    /** Local name of friendly name attribute. */
-    @Nonnull @NotEmpty public static final String FRIENDLY_NAME_ATTRIBUTE_NAME = "friendlyName";
-
-    /** Constructor. */
-    public SAML2Base64AttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
     /** {@inheritDoc} */
-    @Override protected Class<SAML2ByteAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML2ByteAttributeEncoder.class;
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(SAML2ByteAttributeTranscoder.class).getBeanDefinition();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME)) {
-            final String nameFormat = StringSupport.trimOrNull(config.getAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME));
-            builder.addPropertyValue("nameFormat", nameFormat);
-        }
-
-        builder.addPropertyValue("friendlyName", config.getAttributeNS(null, FRIENDLY_NAME_ATTRIBUTE_NAME));
-    }
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2ScopedStringAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2ScopedStringAttributeEncoderParser.java
index 8cbb0f6..8f68342 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2ScopedStringAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2ScopedStringAttributeEncoderParser.java
@@ -17,62 +17,56 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
+import java.util.Map;
+
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseScopedAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML2AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2ScopedStringAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2ScopedStringAttributeTranscoder;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 /**
- * Spring Bean Definition Parser for {@link SAML2ScopedStringAttributeEncoder}.
+ * Spring Bean Definition Parser for {@link SAML2ScopedStringAttributeTranscoder}.
  */
-public class SAML2ScopedStringAttributeEncoderParser extends BaseScopedAttributeEncoderParser {
+public class SAML2ScopedStringAttributeEncoderParser extends BaseSAML2AttributeEncoderParser {
 
     /** Schema type name.. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE,
             "SAML2ScopedString");
 
-    /** Local name of name format attribute. */
-    @Nonnull @NotEmpty public static final String NAME_FORMAT_ATTRIBUTE_NAME = "nameFormat";
-
-    /** Local name of friendly name attribute. */
-    @Nonnull @NotEmpty public static final String FRIENDLY_NAME_ATTRIBUTE_NAME = "friendlyName";
-
-    /** Constructor. */
-    public SAML2ScopedStringAttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Class<SAML2ScopedStringAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML2ScopedStringAttributeEncoder.class;
-    }
-
     /** {@inheritDoc} */
     @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
+            @Nonnull final Map<String,Object> rule) {
+        super.doParse(config, parserContext, rule);
 
-        if (config.hasAttributeNS(null, SCOPE_TYPE_ATTRIBUTE_NAME)) {
-            builder.addPropertyValue("scopeType",
-                    StringSupport.trimOrNull(config.getAttributeNS(null, SCOPE_TYPE_ATTRIBUTE_NAME)));
+        if (config.hasAttributeNS(null, "scopeType")) {
+            rule.put(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_TYPE,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "scopeType")));
+        }
+        
+        if (config.hasAttributeNS(null, "scopeDelimiter")) {
+            rule.put(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_DELIMITER,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "scopeDelimiter")));
         }
 
-        if (config.hasAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME)) {
-            final String nameFormat = StringSupport.trimOrNull(config.getAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME));
-            builder.addPropertyValue("nameFormat", nameFormat);
+        if (config.hasAttributeNS(null, "scopeAttribute")) {
+            rule.put(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_ATTR_NAME,
+                    StringSupport.trimOrNull(config.getAttributeNS(null, "scopeAttribute")));
         }
+    }
 
-        builder.addPropertyValue("friendlyName",
-                StringSupport.trimOrNull(config.getAttributeNS(null, FRIENDLY_NAME_ATTRIBUTE_NAME)));
+    /** {@inheritDoc} */
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(
+                SAML2ScopedStringAttributeTranscoder.class).getBeanDefinition();
     }
 
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2StringAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2StringAttributeEncoderParser.java
index 89c64e7..be7a02f 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2StringAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2StringAttributeEncoderParser.java
@@ -18,55 +18,28 @@
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML2AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2StringAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2StringAttributeTranscoder;
 
 /**
- * Spring Bean Definition Parser for {@link SAML2StringAttributeEncoder}.
+ * Spring Bean Definition Parser for {@link SAML2StringAttributeTranscoder}.
  */
-public class SAML2StringAttributeEncoderParser extends BaseAttributeEncoderParser {
+public class SAML2StringAttributeEncoderParser extends BaseSAML2AttributeEncoderParser {
 
     /** Schema type name.. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE, 
             "SAML2String");
 
-
-    /** Local name of name format attribute. */
-    @Nonnull @NotEmpty public static final String NAME_FORMAT_ATTRIBUTE_NAME = "nameFormat";
-
-    /** Local name of friendly name attribute. */
-    @Nonnull @NotEmpty public static final String FRIENDLY_NAME_ATTRIBUTE_NAME = "friendlyName";
-
-    /** Constructor. */
-    public SAML2StringAttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
     /** {@inheritDoc} */
-    @Override protected Class<SAML2StringAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML2StringAttributeEncoder.class;
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(SAML2StringAttributeTranscoder.class).getBeanDefinition();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME)) {
-            final String nameFormat = StringSupport.trimOrNull(config.getAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME));
-            builder.addPropertyValue("nameFormat", nameFormat);
-        }
-
-        builder.addPropertyValue("friendlyName", config.getAttribute(FRIENDLY_NAME_ATTRIBUTE_NAME));
-    }
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2XMLObjectAttributeEncoderParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2XMLObjectAttributeEncoderParser.java
index fe21954..6fcbcba 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2XMLObjectAttributeEncoderParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/enc/impl/SAML2XMLObjectAttributeEncoderParser.java
@@ -18,53 +18,26 @@
 package net.shibboleth.idp.attribute.resolver.spring.enc.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.w3c.dom.Element;
 
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
+import net.shibboleth.idp.attribute.resolver.spring.enc.BaseSAML2AttributeEncoderParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2XMLObjectAttributeEncoder;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2XMLObjectAttributeTranscoder;
 
-/** Spring Bean Definition Parser for SAML2 XMLObject attribute encoder. */
-public class SAML2XMLObjectAttributeEncoderParser extends BaseAttributeEncoderParser {
+/** Spring Bean Definition Parser for {@link SAML2XMLObjectAttributeTranscoder}. */
+public class SAML2XMLObjectAttributeEncoderParser extends BaseSAML2AttributeEncoderParser {
 
     /** Schema type name.. */
     @Nonnull public static final QName TYPE_NAME_RESOLVER = new QName(AttributeResolverNamespaceHandler.NAMESPACE,
             "SAML2XMLObject");
 
-    /** Local name of name format attribute. */
-    @Nonnull @NotEmpty public static final String NAME_FORMAT_ATTRIBUTE_NAME = "nameFormat";
-
-    /** Local name of friendly name attribute. */
-    @Nonnull @NotEmpty public static final String FRIENDLY_NAME_ATTRIBUTE_NAME = "friendlyName";
-
-    /** Constructor. */
-    public SAML2XMLObjectAttributeEncoderParser() {
-        setNameRequired(true);
-    }
-
     /** {@inheritDoc} */
-    @Override protected Class<SAML2XMLObjectAttributeEncoder> getBeanClass(@Nullable final Element element) {
-        return SAML2XMLObjectAttributeEncoder.class;
+    @Override
+    protected BeanDefinition buildTranscoder() {
+        return BeanDefinitionBuilder.genericBeanDefinition(SAML2XMLObjectAttributeTranscoder.class).getBeanDefinition();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
-            @Nonnull final BeanDefinitionBuilder builder) {
-        super.doParse(config, parserContext, builder);
-
-        if (config.hasAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME)) {
-            final String nameFormat = StringSupport.trimOrNull(config.getAttributeNS(null, NAME_FORMAT_ATTRIBUTE_NAME));
-            builder.addPropertyValue("nameFormat", nameFormat);
-        }
-
-        builder.addPropertyValue("friendlyName",
-                StringSupport.trimOrNull(config.getAttributeNS(null, FRIENDLY_NAME_ATTRIBUTE_NAME)));
-    }
 }
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverParser.java
index 757dfc7..6e2536d 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverParser.java
@@ -23,26 +23,23 @@ import java.util.Map;
 import javax.annotation.Nonnull;
 import javax.xml.namespace.QName;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.xml.BeanDefinitionParser;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
 
 import net.shibboleth.ext.spring.util.SpringSupport;
 import net.shibboleth.idp.attribute.resolver.spring.ad.BaseAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.dc.AbstractDataConnectorParser;
-import net.shibboleth.idp.attribute.resolver.spring.enc.BaseAttributeEncoderParser;
 import net.shibboleth.utilities.java.support.xml.ElementSupport;
 
 /**
  * Bean definition parser for an {@link net.shibboleth.idp.attribute.resolver.AttributeResolver}. <br/>
  * 
  * There is no bean being summoned up here. Rather we just parse all the children. Then over in the service all the
- * {@link net.shibboleth.idp.attribute.resolver.AttributeDefinition},
- * {@link net.shibboleth.idp.attribute.resolver.DataConnector} and
- * {@link net.shibboleth.idp.saml.attribute.principalconnector.impl.PrincipalConnector} beans are sucked out of Spring
+ * {@link net.shibboleth.idp.attribute.resolver.AttributeDefinition} and
+ * {@link net.shibboleth.idp.attribute.resolver.DataConnector} beans are sucked out of Spring
  * by type and injected into a new {@link net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl} via a
  * {@link net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverServiceStrategy}.
  */
@@ -55,9 +52,6 @@ public class AttributeResolverParser implements BeanDefinitionParser {
     /** Schema type. */
     @Nonnull public static final QName SCHEMA_TYPE = new QName(AttributeResolverNamespaceHandler.NAMESPACE,
             "AttributeResolverType");
-    
-    /** Log4j logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(BaseAttributeEncoderParser.class);
 
     /**
      * {@inheritDoc}
@@ -73,6 +67,12 @@ public class AttributeResolverParser implements BeanDefinitionParser {
         children = configChildren.get(AbstractDataConnectorParser.ELEMENT_NAME);
         SpringSupport.parseLazyInitCustomElements(children, context);
 
+        final NodeList attributeEncoders =
+                config.getElementsByTagNameNS(AttributeResolverNamespaceHandler.NAMESPACE, "AttributeEncoder");
+        for (int i = 0; i < attributeEncoders.getLength(); ++i) {
+            SpringSupport.parseLazyInitCustomElement((Element) attributeEncoders.item(i), context);
+        }
+        
         return null;
     }
 
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/BaseAttributeDefinitionParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/BaseAttributeDefinitionParserTest.java
index 082fc1f..33fada4 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/BaseAttributeDefinitionParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/BaseAttributeDefinitionParserTest.java
@@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 
 import org.opensaml.core.OpenSAMLInitBaseTestCase;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
@@ -36,7 +37,6 @@ import net.shibboleth.ext.spring.config.StringToIPRangeConverter;
 import net.shibboleth.ext.spring.config.StringToResourceConverter;
 import net.shibboleth.ext.spring.context.FilesystemGenericApplicationContext;
 import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
-import net.shibboleth.idp.attribute.AttributeEncoder;
 import net.shibboleth.idp.attribute.resolver.AttributeDefinition;
 import net.shibboleth.idp.attribute.resolver.DataConnector;
 import net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl;
@@ -63,7 +63,7 @@ public abstract class BaseAttributeDefinitionParserTest extends OpenSAMLInitBase
 
     public static final String PRINCIPALCONNECTOR_FILE_PATH = BEAN_FILE_PATH + "pc/";
     
-    private GenericApplicationContext pendingTeardownContext = null;
+    protected GenericApplicationContext pendingTeardownContext = null;
     
     @AfterMethod public void tearDownTestContext() {
         if (null == pendingTeardownContext ) {
@@ -191,17 +191,17 @@ public abstract class BaseAttributeDefinitionParserTest extends OpenSAMLInitBase
         return getBean(DATACONNECTOR_FILE_PATH + fileName, claz, context, supressValid);
     }
 
-    protected <Type extends AttributeEncoder> Type getAttributeEncoder(final String fileName, final Class<Type> claz) {
+    protected Collection<Map<String,Object>> getAttributeTranscoderRule(final String fileName, final Class<Collection> claz) {
 
         final GenericApplicationContext context = new GenericApplicationContext();
         setTestContext(context);
         context.setDisplayName("ApplicationContext: " + claz);
 
-        return getAttributeEncoder(fileName, claz, context);
+        return getAttributeTranscoderRule(fileName, claz, context);
 
     }
 
-    protected <Type extends AttributeEncoder> Type getAttributeEncoder(final String fileName, final Class<Type> claz,
+    protected Collection<Map<String,Object>> getAttributeTranscoderRule(final String fileName, final Class<Collection> claz,
             final GenericApplicationContext context) {
 
         return getBean(ENCODER_FILE_PATH + fileName, claz, context);
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java
index 2857dd6..4d3c397 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java
@@ -17,12 +17,9 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.ad;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.*;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collection;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -44,8 +41,6 @@ import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParse
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.SimpleAttributeDefinitionParser;
 import net.shibboleth.idp.profile.context.RelyingPartyContext;
 import net.shibboleth.idp.profile.logic.RelyingPartyIdPredicate;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1StringAttributeEncoder;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2StringAttributeEncoder;
 import net.shibboleth.idp.saml.impl.TestSources;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 
@@ -63,7 +58,8 @@ public class SimpleAttributeParserTest extends BaseAttributeDefinitionParserTest
         assertTrue(attrDef.getDisplayDescriptions().isEmpty(), "getDisplayDescriptions().isEmpty()");
         assertTrue(attrDef.getDisplayNames().isEmpty(), "getDisplayNames().isEmpty()");
         assertEquals(attrDef.getAttributeDependencies().size(), 1);
-        assertTrue(attrDef.getAttributeEncoders().isEmpty(), "getgetAttributeEncoders().isEmpty()");
+        
+        assertTrue(pendingTeardownContext.getBeansOfType(Collection.class).isEmpty());
     }
 
     @Test public void simplePopulated() throws ComponentInitializationException {
@@ -96,13 +92,6 @@ public class SimpleAttributeParserTest extends BaseAttributeDefinitionParserTest
         final ResolverDataConnectorDependency dcDep = dcDeps.iterator().next();
         assertEquals(dcDep.getDependencyPluginId(), "con1");
         assertTrue(dcDep.getAttributeNames().contains("dep1"));
-
-        assertEquals(attrDef.getAttributeEncoders().size(), 1);
-        final SAML2StringAttributeEncoder e1 =
-                (SAML2StringAttributeEncoder) attrDef.getAttributeEncoders().iterator().next();
-        assertEquals(e1.getName(), "urn:oid:0.9.2342.19200300.100.1.3");
-        assertEquals(e1.getFriendlyName(), "mail");
-
     }
 
     @Test public void populated2() throws ComponentInitializationException {
@@ -126,24 +115,6 @@ public class SimpleAttributeParserTest extends BaseAttributeDefinitionParserTest
 
         final Set<ResolverDataConnectorDependency> dcDeps = attrDef.getDataConnectorDependencies();
         assertEquals(dcDeps.size(), 0, "getDataConnectorDependencies");
-
-        
-        assertEquals(attrDef.getAttributeEncoders().size(), 2);
-        final List a = new ArrayList(attrDef.getAttributeEncoders());
-
-        final SAML2StringAttributeEncoder saml2;
-        final SAML1StringAttributeEncoder saml1;
-        if (a.get(0) instanceof SAML2StringAttributeEncoder) {
-            saml2 = (SAML2StringAttributeEncoder) a.get(0);
-            saml1 = (SAML1StringAttributeEncoder) a.get(1);
-        } else {
-            saml2 = (SAML2StringAttributeEncoder) a.get(1);
-            saml1 = (SAML1StringAttributeEncoder) a.get(0);
-        }
-        assertEquals(saml2.getName(), "urn:oid:0.9.2342.19200300.100.1.3");
-        assertEquals(saml2.getFriendlyName(), "mail");
-
-        assertEquals(saml1.getName(), "urn:mace:dir:attribute-def:mail");
     }
 
     @Test public void bad() throws ComponentInitializationException {
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/Regressions.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/Regressions.java
index a0201e3..b5e6083 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/Regressions.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/Regressions.java
@@ -17,19 +17,21 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.*;
 
 import java.util.Collection;
+import java.util.Map;
 
 import org.springframework.context.support.GenericApplicationContext;
 import org.testng.annotations.Test;
 
-import net.shibboleth.idp.attribute.AttributeEncoder;
 import net.shibboleth.idp.attribute.resolver.AttributeDefinition;
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2StringAttributeTranscoder;
 
 /**
- *
+ * Test for regressions identified and patched.
  */
 public class Regressions extends BaseAttributeDefinitionParserTest {
 
@@ -39,10 +41,16 @@ public class Regressions extends BaseAttributeDefinitionParserTest {
         loadFile(ENCODER_FILE_PATH + "resolver/idp-571.xml", context);
         context.refresh();
      
-        Collection<AttributeEncoder> encoders = context.getBeansOfType(AttributeEncoder.class).values();
         Collection<AttributeDefinition> definitions = context.getBeansOfType(AttributeDefinition.class).values();
+        Collection<Collection> transcoderRules = context.getBeansOfType(Collection.class).values();
         
-        assertEquals(encoders.size(), 1);
         assertEquals(definitions.size(), 1);
+        assertEquals(transcoderRules.size(), 1);
+        assertEquals(transcoderRules.iterator().next().size(), 1);
+        
+        final Map<String,Object> rule = (Map<String, Object>) transcoderRules.iterator().next().iterator().next();
+        assertEquals(rule.get(AttributeTranscoderRegistry.PROP_ID), "skillsoftdept");
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2StringAttributeTranscoder);
     }
-}
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1Base64AttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1Base64AttributeEncoderParserTest.java
index 4d0e03a..f1ac9ed 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1Base64AttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1Base64AttributeEncoderParserTest.java
@@ -17,39 +17,54 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML1Base64AttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1ByteAttributeEncoder;
-import net.shibboleth.idp.saml.xml.SAMLConstants;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML1AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1ByteAttributeTranscoder;
 
 /**
  * Test for {@link SAML1Base64AttributeEncoderParser}.
  */
 public class SAML1Base64AttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
   
-    @Test public void resolver() {
-        final SAML1ByteAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1Base64.xml", SAML1ByteAttributeEncoder.class);
+    @Test public void newNameSpace() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1Base64.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "SAML1_BASE64_ATTRIBUTE_NAME");
-        assertEquals(encoder.getNamespace(),"SAML1_BASE64_ATTRIBUTE_NAME_SPACE");
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1ByteAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "SAML1_BASE64_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE), "SAML1_BASE64_ATTRIBUTE_NAME_SPACE");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
 
     
     @Test public void defaultCase() {
-        final SAML1ByteAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1Base64Default.xml", SAML1ByteAttributeEncoder.class);
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1Base64Default.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "Base64_ATTRIBUTE");
-        assertEquals(encoder.getNamespace(), SAMLConstants.SAML1_ATTR_NAMESPACE_URI);
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1ByteAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "Base64_ATTRIBUTE");
+        assertNull(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml1Base64NoName.xml", SAML1ByteAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml1Base64NoName.xml", Collection.class);
     }
 }
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1ScopedStringAttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1ScopedStringAttributeEncoderParserTest.java
index b31b7ed..2cc265d 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1ScopedStringAttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1ScopedStringAttributeEncoderParserTest.java
@@ -17,45 +17,61 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML1ScopedStringAttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1ScopedStringAttributeEncoder;
-import net.shibboleth.idp.saml.xml.SAMLConstants;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML1AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1ScopedStringAttributeTranscoder;
 
 /**
  * Test for {@link SAML1ScopedStringAttributeEncoderParser}.
  */
 public class SAML1ScopedStringAttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
 
-    @Test public void resolver() {
-        final SAML1ScopedStringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1Scoped.xml", SAML1ScopedStringAttributeEncoder.class);
+    @Test public void newNamespace() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1Scoped.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "SAML1_SCOPED_ATTRIBUTE_NAME");
-        assertEquals(encoder.getNamespace(),"SAML1_SCOPED_ATTRIBUTE_NAME_FORMAT");
-        assertEquals(encoder.getScopeType(),"attribute");
-        assertEquals(encoder.getScopeAttributeName(),"saml1ScopeAttrib");
-        assertEquals(encoder.getScopeDelimiter(),"#@#");
-    }
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1ScopedStringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "SAML1_SCOPED_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE), "SAML1_SCOPED_ATTRIBUTE_NAME_FORMAT");
+        assertEquals(rule.get(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_TYPE), "attribute");
+        assertEquals(rule.get(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_ATTR_NAME), "saml1ScopeAttrib");
+        assertEquals(rule.get(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_DELIMITER), "#@#");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
+}
 
     
     @Test public void defaultCase() {
-        final SAML1ScopedStringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1ScopedDefault.xml", SAML1ScopedStringAttributeEncoder.class);
-
-        assertEquals(encoder.getName(), "saml1_scoped_name");
-        assertEquals(encoder.getNamespace(), SAMLConstants.SAML1_ATTR_NAMESPACE_URI);
-        assertEquals(encoder.getScopeType(),"attribute");
-        assertEquals(encoder.getScopeDelimiter(),"@");
-        assertEquals(encoder.getScopeAttributeName(),"Scope");
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1ScopedDefault.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
+
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1ScopedStringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "saml1_scoped_name");
+        assertNull(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE));
+        assertNull(rule.get(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_TYPE));
+        assertNull(rule.get(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_ATTR_NAME));
+        assertNull(rule.get(SAML1ScopedStringAttributeTranscoder.PROP_SCOPE_DELIMITER));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml1ScopedNoName.xml", SAML1ScopedStringAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml1ScopedNoName.xml", Collection.class);
     }
-}
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1StringAttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1StringAttributeEncoderParserTest.java
index 9cd4a60..3767ed8 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1StringAttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1StringAttributeEncoderParserTest.java
@@ -17,39 +17,55 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML1StringAttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1StringAttributeEncoder;
-import net.shibboleth.idp.saml.xml.SAMLConstants;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML1AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1StringAttributeTranscoder;
 
 /**
  * Test for {@link SAML1StringAttributeEncoderParser}.
  */
 public class SAML1StringAttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
 
-    @Test public void newNameSpace() {
-        final SAML1StringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1String.xml", SAML1StringAttributeEncoder.class);
+    @Test public void newNamespace() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1String.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "SAML1_STRING_ATTRIBUTE_NAME");
-        assertEquals(encoder.getNamespace(),"SAML1_STRING_ATTRIBUTE_NAME_SPACE");
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1StringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "SAML1_STRING_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE), "SAML1_STRING_ATTRIBUTE_NAME_SPACE");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
 
     
     @Test public void defaultCase() {
-        final SAML1StringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1StringDefault.xml", SAML1StringAttributeEncoder.class);
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1StringDefault.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "ATTRIBUTE");
-        assertEquals(encoder.getNamespace(), SAMLConstants.SAML1_ATTR_NAMESPACE_URI);
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1StringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "ATTRIBUTE");
+        assertNull(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml1StringNoName.xml", SAML1StringAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml1StringNoName.xml", Collection.class);
     }
-}
+    
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1XMLObjectAttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1XMLObjectAttributeEncoderParserTest.java
index ccda6b2..ccb118b 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1XMLObjectAttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML1XMLObjectAttributeEncoderParserTest.java
@@ -17,38 +17,53 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML1XMLObjectAttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML1XMLObjectAttributeEncoder;
-import net.shibboleth.idp.saml.xml.SAMLConstants;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML1AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML1XMLObjectAttributeTranscoder;
 
 /**
  * Test for {@link SAML1XMLObjectAttributeEncoderParser}.
  */
 public class SAML1XMLObjectAttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
 
-    @Test public void resolver() {
-        final SAML1XMLObjectAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1XmlObject.xml", SAML1XMLObjectAttributeEncoder.class);
+    @Test public void newNamespace() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1XmlObject.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "SAML1_XMLObject_ATTRIBUTE_NAME");
-        assertEquals(encoder.getNamespace(),"SAML1_XMLObject_ATTRIBUTE_NAME_SPACE");
-    }
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1XMLObjectAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "SAML1_XMLObject_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE), "SAML1_XMLObject_ATTRIBUTE_NAME_SPACE");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
+}
     
     @Test public void defaultCase() {
-        final SAML1XMLObjectAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml1XmlObjectDefault.xml", SAML1XMLObjectAttributeEncoder.class);
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml1XmlObjectDefault.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "XMLObject_ATTRIBUTE");
-        assertEquals(encoder.getNamespace(), SAMLConstants.SAML1_ATTR_NAMESPACE_URI);
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML1XMLObjectAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAME), "XMLObject_ATTRIBUTE");
+        assertNull(rule.get(AbstractSAML1AttributeTranscoder.PROP_NAMESPACE));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml1XmlObjectNoName.xml", SAML1XMLObjectAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml1XmlObjectNoName.xml", Collection.class);
     }
 }
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2Base64AttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2Base64AttributeEncoderParserTest.java
index bef5195..a880331 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2Base64AttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2Base64AttributeEncoderParserTest.java
@@ -17,41 +17,55 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
-import org.opensaml.saml.saml2.core.Attribute;
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML2Base64AttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2ByteAttributeEncoder;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML2AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2ByteAttributeTranscoder;
 
 /**
  * Test for {@link SAML2Base64AttributeEncoderParser}.
  */
 public class SAML2Base64AttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
 
-    @Test public void resolver() {
-        final SAML2ByteAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2Base64.xml", SAML2ByteAttributeEncoder.class);
+    @Test public void newNameFormat() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2Base64.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "Saml2Base64_ATTRIBUTE_NAME");
-        assertEquals(encoder.getFriendlyName(),"Saml2Base64_ATTRIBUTE_FRIENDLY_NAME"); 
-        assertEquals(encoder.getNameFormat(),"Saml2Base64_ATTRIBUTE_NAME_FORMAT");
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2ByteAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "Saml2Base64_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT), "Saml2Base64_ATTRIBUTE_NAME_FORMAT");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME), "Saml2Base64_ATTRIBUTE_FRIENDLY_NAME");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test public void defaultCase() {
-        final SAML2ByteAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2Base64Default.xml", SAML2ByteAttributeEncoder.class);
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2Base64Default.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "Base64Name");
-        assertNull(encoder.getFriendlyName()); 
-        assertEquals(encoder.getNameFormat(), Attribute.URI_REFERENCE);
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2ByteAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "Base64Name");
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT));
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml2Base64NoName.xml", SAML2ByteAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml2Base64NoName.xml", Collection.class);
     }
 }
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2ScopedStringAttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2ScopedStringAttributeEncoderParserTest.java
index 0dcabfa..651b75b 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2ScopedStringAttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2ScopedStringAttributeEncoderParserTest.java
@@ -17,16 +17,20 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
-import org.opensaml.saml.saml2.core.Attribute;
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML2ScopedStringAttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2ScopedStringAttributeEncoder;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML2AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2ScopedStringAttributeTranscoder;
 
 /**
  * Test for {@link SAML2ScopedStringAttributeEncoderParser}.
@@ -34,30 +38,40 @@ import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2ScopedStringAttribut
 public class SAML2ScopedStringAttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
 
     @Test public void resolver() {
-        final SAML2ScopedStringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2Scoped.xml", SAML2ScopedStringAttributeEncoder.class);
-
-        assertEquals(encoder.getName(), "ATTRIBUTE_NAME");
-        assertEquals(encoder.getFriendlyName(),"ATTRIBUTE_FRIENDLY_NAME"); 
-        assertEquals(encoder.getNameFormat(),"ATTRIBUTE_NAME_FORMAT");
-        assertEquals(encoder.getScopeType(),"attribute");
-        assertEquals(encoder.getScopeAttributeName(),"scopeAttrib");
-        assertEquals(encoder.getScopeDelimiter(),"###");
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2Scoped.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
+
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2ScopedStringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT), "ATTRIBUTE_NAME_FORMAT");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME), "ATTRIBUTE_FRIENDLY_NAME");
+        assertEquals(rule.get(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_TYPE), "attribute");
+        assertEquals(rule.get(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_ATTR_NAME), "scopeAttrib");
+        assertEquals(rule.get(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_DELIMITER), "###");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test public void defaultCase() {
-        final SAML2ScopedStringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2ScopedDefault.xml", SAML2ScopedStringAttributeEncoder.class);
-
-        assertEquals(encoder.getName(), "name");
-        assertNull(encoder.getFriendlyName()); 
-        assertEquals(encoder.getNameFormat(), Attribute.URI_REFERENCE);
-        assertEquals(encoder.getScopeType(),"inline");
-        assertEquals(encoder.getScopeDelimiter(),"@");
-        assertEquals(encoder.getScopeAttributeName(),"Scope");
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2ScopedDefault.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
+
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2ScopedStringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "name");
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT));
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME));
+        assertNull(rule.get(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_TYPE));
+        assertNull(rule.get(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_ATTR_NAME));
+        assertNull(rule.get(SAML2ScopedStringAttributeTranscoder.PROP_SCOPE_DELIMITER));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml2ScopedNoName.xml", SAML2ScopedStringAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml2ScopedNoName.xml", Collection.class);
     }
 }
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2StringAttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2StringAttributeEncoderParserTest.java
index 0961d4e..109e53d 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2StringAttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2StringAttributeEncoderParserTest.java
@@ -17,75 +17,56 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
-import org.opensaml.saml.saml2.core.Attribute;
 import org.springframework.beans.factory.BeanDefinitionStoreException;
-import org.springframework.context.support.GenericApplicationContext;
 import org.testng.annotations.Test;
 
-import com.google.common.base.Predicates;
-
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML2StringAttributeEncoderParser;
-import net.shibboleth.idp.profile.logic.ScriptedPredicate;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2StringAttributeEncoder;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML2AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2StringAttributeTranscoder;
 
 /**
  * Test for {@link SAML2StringAttributeEncoderParser}.
  */
 public class SAML2StringAttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
   
-    @Test public void resolver() {
-        final SAML2StringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2String.xml", SAML2StringAttributeEncoder.class);
+    @Test public void newNameFormat() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2String.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "Saml2String_ATTRIBUTE_NAME");
-        assertEquals(encoder.getFriendlyName(),"Saml2String_ATTRIBUTE_FRIENDLY_NAME"); 
-        assertEquals(encoder.getNameFormat(),"Saml2String_ATTRIBUTE_NAME_FORMAT");
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2StringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "Saml2String_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT), "Saml2String_ATTRIBUTE_NAME_FORMAT");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME), "Saml2String_ATTRIBUTE_FRIENDLY_NAME");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test public void defaultCase() {
-        final SAML2StringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2StringDefault.xml", SAML2StringAttributeEncoder.class);
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2StringDefault.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertSame(encoder.getActivationCondition(), Predicates.alwaysTrue());
-        assertTrue(encoder.getActivationCondition().test(null));
-        assertEquals(encoder.getName(), "Saml2StringName");
-        assertNull(encoder.getFriendlyName()); 
-        assertEquals(encoder.getNameFormat(), Attribute.URI_REFERENCE);
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2StringAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "Saml2StringName");
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT));
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml2StringNoName.xml", SAML2StringAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml2StringNoName.xml", Collection.class);
     }
     
-    @Test public void conditional() {
-        final GenericApplicationContext context = new GenericApplicationContext();
-        setTestContext(context);
-
-        loadFile(ENCODER_FILE_PATH + "predicates.xml", context);
-        
-        final SAML2StringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2StringConditional.xml", SAML2StringAttributeEncoder.class, context);
-
-        assertSame(encoder.getActivationCondition(), Predicates.alwaysFalse());
-        assertFalse(encoder.getActivationCondition().test(null));
-    }
-
-    @Test public void conditionalScript() {
-        final GenericApplicationContext context = new GenericApplicationContext();
-        setTestContext(context);
-        
-        final SAML2StringAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2String.xml", SAML2StringAttributeEncoder.class, context);
-
-        assertTrue(encoder.getActivationCondition() instanceof ScriptedPredicate);
-        assertFalse(encoder.getActivationCondition().test(null));
-    }
-
-}
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2XMLObjectAttributeEncoderParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2XMLObjectAttributeEncoderParserTest.java
index a74e957..fa68ada 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2XMLObjectAttributeEncoderParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/enc/SAML2XMLObjectAttributeEncoderParserTest.java
@@ -17,41 +17,56 @@
 
 package net.shibboleth.idp.attribute.resolver.spring.enc;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
+import static org.testng.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.Predicate;
 
-import org.opensaml.saml.saml2.core.Attribute;
 import org.springframework.beans.factory.BeanDefinitionStoreException;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.enc.impl.SAML2XMLObjectAttributeEncoderParser;
-import net.shibboleth.idp.saml.attribute.encoding.impl.SAML2XMLObjectAttributeEncoder;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
+import net.shibboleth.idp.saml.attribute.transcoding.AbstractSAML2AttributeTranscoder;
+import net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2XMLObjectAttributeTranscoder;
 
 /**
  * Test for {@link SAML2XMLObjectAttributeEncoderParser}.
  */
 public class SAML2XMLObjectAttributeEncoderParserTest extends BaseAttributeDefinitionParserTest {
 
-    @Test public void resolver() {
-        final SAML2XMLObjectAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2XmlObject.xml", SAML2XMLObjectAttributeEncoder.class);
+    @Test public void newNameFormat() {
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2XmlObject.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "Saml2XmlObject_ATTRIBUTE_NAME");
-        assertEquals(encoder.getFriendlyName(),"Saml2XmlObject_ATTRIBUTE_FRIENDLY_NAME"); 
-        assertEquals(encoder.getNameFormat(),"Saml2XmlObject_ATTRIBUTE_NAME_FORMAT");
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2XMLObjectAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "Saml2XmlObject_ATTRIBUTE_NAME");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT), "Saml2XmlObject_ATTRIBUTE_NAME_FORMAT");
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME), "Saml2XmlObject_ATTRIBUTE_FRIENDLY_NAME");
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
 
     @Test public void defaultCase() {
-        final SAML2XMLObjectAttributeEncoder encoder =
-                getAttributeEncoder("resolver/saml2XmlObjectDefault.xml", SAML2XMLObjectAttributeEncoder.class);
+        final Collection<Map<String,Object>> rules =
+                getAttributeTranscoderRule("resolver/saml2XmlObjectDefault.xml", Collection.class);
+        assertEquals(rules.size(), 1);
+        
+        final Map<String,Object> rule = rules.iterator().next();
 
-        assertEquals(encoder.getName(), "XmlObjectName");
-        assertNull(encoder.getFriendlyName()); 
-        assertEquals(encoder.getNameFormat(), Attribute.URI_REFERENCE);
+        assertTrue(rule.get(AttributeTranscoderRegistry.PROP_TRANSCODER) instanceof SAML2XMLObjectAttributeTranscoder);
+        assertEquals(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME), "XmlObjectName");
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_NAME_FORMAT));
+        assertNull(rule.get(AbstractSAML2AttributeTranscoder.PROP_FRIENDLY_NAME));
+        assertFalse(((Predicate) rule.get(AttributeTranscoderRegistry.PROP_CONDITION)).test(null));
     }
     
     @Test(expectedExceptions={BeanDefinitionStoreException.class,})  public void noName() {
-        getAttributeEncoder("resolver/saml2XmlObjectNoName.xml", SAML2XMLObjectAttributeEncoder.class);
+        getAttributeTranscoderRule("resolver/saml2XmlObjectNoName.xml", Collection.class);
     }
-}
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/customBean.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/customBean.xml
index ef730da..31ef1f6 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/customBean.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/customBean.xml
@@ -10,12 +10,16 @@
                            
        default-init-method="initialize"
        default-destroy-method="destroy">
+       
     <util:map id="shibboleth.CustomScriptObject">
         <entry key="foo" value="bar"/>
-    </util:map>    
+    </util:map>
+        
     <util:map id="other.CustomScriptObject">
         <entry key="bar" value="foo"/>
-    </util:map>    
+    </util:map>
+    
+    <bean id="shibboleth.Predicate" class="com.google.common.base.Predicates" factory-method="alwaysFalse"/>
     
     <bean id="shibboleth.PropertySourcesPlaceholderConfigurer"
         class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/idp-571.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/idp-571.xml
index 81ca522..304812b 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/idp-571.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/idp-571.xml
@@ -8,13 +8,10 @@
     <AttributeEncoder xsi:type="SAML2String"  name="skillsoftdept" friendlyName="dept name for skillsoft" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" />
 
     <Script><![CDATA[
-
        importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);
 
         // Create attribute to be returned from definition
         skillsoftdept = new BasicAttribute("skillsoftdept");
-
-
     ]]></Script>
     
   </AttributeDefinition>
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64.xml
index d41c048..7246be4 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64.xml
@@ -4,6 +4,10 @@
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="SAML1_BASE64_ATTRIBUTE_NAME" 
 	namespace="SAML1_BASE64_ATTRIBUTE_NAME_SPACE"
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
-/> 
- 
\ No newline at end of file
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+
+</AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64Default.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64Default.xml
index 972e98b..20b8a07 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64Default.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Base64Default.xml
@@ -1,4 +1,6 @@
 <AttributeEncoder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mace:shibboleth:2.0:resolver"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
-    xsi:type="SAML1Base64" name="Base64_ATTRIBUTE"/> 
+    xsi:type="SAML1Base64"
+    name="Base64_ATTRIBUTE"
+    activationConditionRef="shibboleth.Predicate"/> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Scoped.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Scoped.xml
index 0e73efd..5386708 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Scoped.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1Scoped.xml
@@ -7,5 +7,11 @@
 	scopeType="attribute"
 	scopeAttribute="saml1ScopeAttrib"
 	scopeDelimiter="#@#"
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"/> 
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+	
+</AttributeEncoder>
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1ScopedDefault.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1ScopedDefault.xml
index 39f4943..13366a5 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1ScopedDefault.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1ScopedDefault.xml
@@ -1,5 +1,6 @@
 <AttributeEncoder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mace:shibboleth:2.0:resolver"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
     xsi:type="SAML1ScopedString"
-	name="saml1_scoped_name" /> 
+	name="saml1_scoped_name"
+	activationConditionRef="shibboleth.Predicate"/> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1String.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1String.xml
index c78ae5b..d4af1c4 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1String.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1String.xml
@@ -4,6 +4,10 @@
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="SAML1_STRING_ATTRIBUTE_NAME" 
 	namespace="SAML1_STRING_ATTRIBUTE_NAME_SPACE"
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
-/> 
- 
\ No newline at end of file
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+
+</AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1StringDefault.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1StringDefault.xml
index dfae337..d351751 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1StringDefault.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1StringDefault.xml
@@ -1,5 +1,6 @@
 <AttributeEncoder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mace:shibboleth:2.0:resolver"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
     xsi:type="SAML1String"
-	name="ATTRIBUTE"/> 
+	name="ATTRIBUTE"
+	activationConditionRef="shibboleth.Predicate"/>
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObject.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObject.xml
index baa15a5..3f012fb 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObject.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObject.xml
@@ -4,6 +4,10 @@
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="SAML1_XMLObject_ATTRIBUTE_NAME" 
 	namespace="SAML1_XMLObject_ATTRIBUTE_NAME_SPACE"
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
-/> 
- 
\ No newline at end of file
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+	
+</AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObjectDefault.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObjectDefault.xml
index 7da2157..ded115f 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObjectDefault.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml1XmlObjectDefault.xml
@@ -3,5 +3,6 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="XMLObject_ATTRIBUTE"
+	activationConditionRef="shibboleth.Predicate"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"/> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64.xml
index 3681d25..24216d5 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64.xml
@@ -5,5 +5,10 @@
 	name="Saml2Base64_ATTRIBUTE_NAME" 
 	nameFormat="Saml2Base64_ATTRIBUTE_NAME_FORMAT"
 	friendlyName="Saml2Base64_ATTRIBUTE_FRIENDLY_NAME"
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"
-/> 
\ No newline at end of file
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+	
+</AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64Default.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64Default.xml
index 430b049..a0d61fc 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64Default.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Base64Default.xml
@@ -3,5 +3,6 @@
     xsi:type="SAML2Base64"
  	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="Base64Name"
+	activationConditionRef="shibboleth.Predicate"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"/> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Scoped.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Scoped.xml
index 4b01de5..7b6502d 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Scoped.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2Scoped.xml
@@ -8,5 +8,10 @@
 	scopeType="attribute"
 	scopeAttribute="scopeAttrib"
 	scopeDelimiter="###"
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd" /> 
- 
\ No newline at end of file
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+	
+</AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2ScopedDefault.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2ScopedDefault.xml
index 7f0778b..a44248a 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2ScopedDefault.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2ScopedDefault.xml
@@ -3,5 +3,6 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="name"
+	activationConditionRef="shibboleth.Predicate"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"/> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2String.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2String.xml
index 1300dd2..1c2cdff 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2String.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2String.xml
@@ -9,5 +9,6 @@
 
     <ActivationConditionScript>
         <Script>false</Script>
-    </ActivationConditionScript>	
+    </ActivationConditionScript>
+    
 </AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringConditional.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringConditional.xml
index 741d16b..63c1736 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringConditional.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringConditional.xml
@@ -3,6 +3,6 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="Saml2StringConditional"
-	activationConditionRef="predicate"
+	activationConditionRef="shibboleth.Predicate"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd" /> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringDefault.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringDefault.xml
index ef45b88..1f04ab4 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringDefault.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2StringDefault.xml
@@ -3,5 +3,6 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="Saml2StringName"
+	activationConditionRef="shibboleth.Predicate"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd" /> 
  
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObject.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObject.xml
index 0ef9d0e..9e69400 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObject.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObject.xml
@@ -5,4 +5,10 @@
 	name="Saml2XmlObject_ATTRIBUTE_NAME" 
 	nameFormat="Saml2XmlObject_ATTRIBUTE_NAME_FORMAT"
 	friendlyName="Saml2XmlObject_ATTRIBUTE_FRIENDLY_NAME" 
-	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"/> 
\ No newline at end of file
+	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+
+    <ActivationConditionScript>
+        <Script>false</Script>
+    </ActivationConditionScript>
+	
+</AttributeEncoder>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObjectDefault.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObjectDefault.xml
index f77cbf9..2339c03 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObjectDefault.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/enc/resolver/saml2XmlObjectDefault.xml
@@ -3,5 +3,6 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 	xmlns="urn:mace:shibboleth:2.0:resolver"
 	name="XmlObjectName"
+	activationConditionRef="shibboleth.Predicate"
 	xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd"/> 
  
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/conf/attribute-registry.xml b/idp-conf/src/main/resources/conf/attribute-registry.xml
index aba47dd..7a56789 100644
--- a/idp-conf/src/main/resources/conf/attribute-registry.xml
+++ b/idp-conf/src/main/resources/conf/attribute-registry.xml
@@ -12,6 +12,7 @@
        default-init-method="initialize"
        default-destroy-method="destroy">
 
+    <!--
     <bean id="SAML2StringTranscoder"
         class="net.shibboleth.idp.saml.attribute.transcoding.impl.SAML2StringAttributeTranscoder" />
     <bean id="SAML2ScopedStringTranscoder"
@@ -45,6 +46,7 @@
         </map>
 
     </util:list>
+    -->
     
     <util:map id="DefaultNamingRegistry">
         <entry key="#{T(org.opensaml.saml.saml2.core.Attribute)}">
diff --git a/idp-conf/src/main/resources/system/conf/services-system.xml b/idp-conf/src/main/resources/system/conf/services-system.xml
index 543d8a9..97c5675 100644
--- a/idp-conf/src/main/resources/system/conf/services-system.xml
+++ b/idp-conf/src/main/resources/system/conf/services-system.xml
@@ -79,6 +79,7 @@
     </bean>
     <util:list id ="shibboleth.DefaultAttributeRegistryResources">
         <value>%{idp.home}/conf/attribute-registry.xml</value>
+        <value>%{idp.home}/conf/attribute-resolver.xml</value>
     </util:list>
 
     <bean id="shibboleth.RelyingPartyResolverService" class="net.shibboleth.ext.spring.service.ReloadableSpringService"
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/impl/AddAttributeStatementToAssertion.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/impl/AddAttributeStatementToAssertion.java
index ed2fe75..06b14da 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/impl/AddAttributeStatementToAssertion.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/impl/AddAttributeStatementToAssertion.java
@@ -19,18 +19,15 @@ package net.shibboleth.idp.saml.saml1.profile.impl;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Set;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import net.shibboleth.idp.attribute.AttributeEncoder;
 import net.shibboleth.idp.attribute.AttributeEncodingException;
 import net.shibboleth.idp.attribute.IdPAttribute;
 import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
 import net.shibboleth.idp.profile.IdPEventIds;
-import net.shibboleth.idp.saml.attribute.encoding.SAML1AttributeEncoder;
 import net.shibboleth.idp.saml.profile.impl.BaseAddAttributeStatementToAssertion;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.NullableElements;
@@ -43,7 +40,6 @@ import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.saml.common.SAMLObjectBuilder;
-import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml1.core.Assertion;
 import org.opensaml.saml.saml1.core.Attribute;
 import org.opensaml.saml.saml1.core.AttributeStatement;
@@ -182,44 +178,10 @@ public class AddAttributeStatementToAssertion extends BaseAddAttributeStatementT
                     throws AttributeEncodingException {
 
         log.debug("{} Attempting to encode attribute {} as a SAML 1 Attribute", getLogPrefix(), attribute.getId());
-        
-        boolean added = false;
 
         // Uses the new registry.
-        if (super.encodeAttribute(registry, profileRequestContext, attribute, Attribute.class, results) > 0) {
-            added = true;
-        }
-        
-        // TODO: migrate legacy code into an alternate registry call via resolver
-        
-        final Set<AttributeEncoder<?>> encoders = attribute.getEncoders();
-        if (encoders.isEmpty()) {
-            log.debug("{} Attribute {} does not have any encoders, nothing to do", getLogPrefix(), attribute.getId());
-            return;
-        }
-        
-        for (final AttributeEncoder<?> encoder : encoders) {
-            if (SAMLConstants.SAML11P_NS.equals(encoder.getProtocol())
-                    && encoder instanceof SAML1AttributeEncoder
-                    && encoder.getActivationCondition().test(profileRequestContext)) {
-                log.debug("{} Encoding attribute {} as a SAML 1 Attribute", getLogPrefix(), attribute.getId());
-                try {
-                    added = true;
-                    results.add((Attribute) encoder.encode(attribute));
-                } catch (final AttributeEncodingException e) {
-                    if (isIgnoringUnencodableAttributes()) {
-                        log.debug("{} Unable to encode attribute {} as SAML 1 attribute", getLogPrefix(),
-                                attribute.getId(), e);
-                    } else {
-                        throw e;
-                    }
-                }
-            }
-        }
-
-        if (!added) {
-            log.debug(
-                    "{} Attribute {} did not have a usable SAML 1 Attribute encoder associated with it, nothing to do",
+        if (super.encodeAttribute(registry, profileRequestContext, attribute, Attribute.class, results) == 0) {
+            log.debug("{} Attribute {} did not have SAML 1 Attribute transcoder instructions associated, nothing to do",
                     getLogPrefix(), attribute.getId());
         }
     }
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAttributeStatementToAssertion.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAttributeStatementToAssertion.java
index 72b94bd..502873c 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAttributeStatementToAssertion.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAttributeStatementToAssertion.java
@@ -19,18 +19,15 @@ package net.shibboleth.idp.saml.saml2.profile.impl;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Set;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import net.shibboleth.idp.attribute.AttributeEncoder;
 import net.shibboleth.idp.attribute.AttributeEncodingException;
 import net.shibboleth.idp.attribute.IdPAttribute;
 import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
 import net.shibboleth.idp.profile.IdPEventIds;
-import net.shibboleth.idp.saml.attribute.encoding.SAML2AttributeEncoder;
 import net.shibboleth.idp.saml.profile.impl.BaseAddAttributeStatementToAssertion;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.NullableElements;
@@ -43,7 +40,6 @@ import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.saml.common.SAMLObjectBuilder;
-import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml2.core.Assertion;
 import org.opensaml.saml.saml2.core.Attribute;
 import org.opensaml.saml.saml2.core.AttributeStatement;
@@ -184,44 +180,10 @@ public class AddAttributeStatementToAssertion extends BaseAddAttributeStatementT
                     throws AttributeEncodingException {
 
         log.debug("{} Attempting to encode attribute {} as a SAML 2 Attribute", getLogPrefix(), attribute.getId());
-        
-        boolean added = false;
 
         // Uses the new registry.
-        if (super.encodeAttribute(registry, profileRequestContext, attribute, Attribute.class, results) > 0) {
-            added = true;
-        }
-        
-        // TODO: migrate legacy code into an alternate registry call via resolver
-        
-        final Set<AttributeEncoder<?>> encoders = attribute.getEncoders();
-        if (encoders.isEmpty()) {
-            log.debug("{} Attribute {} does not have any encoders, nothing to do", getLogPrefix(), attribute.getId());
-            return;
-        }
-
-        for (final AttributeEncoder<?> encoder : encoders) {
-            if (SAMLConstants.SAML20P_NS.equals(encoder.getProtocol())
-                    && encoder instanceof SAML2AttributeEncoder
-                    && encoder.getActivationCondition().test(profileRequestContext)) {
-                log.debug("{} Encoding attribute {} as a SAML 2 Attribute", getLogPrefix(), attribute.getId());
-                try {
-                    results.add((Attribute) encoder.encode(attribute));
-                    added = true;
-                } catch (final AttributeEncodingException e) {
-                    if (isIgnoringUnencodableAttributes()) {
-                        log.debug("{} Unable to encode attribute {} as SAML 2 attribute", getLogPrefix(),
-                                attribute.getId(), e);
-                    } else {
-                        throw e;
-                    }
-                }
-            }
-        }
-
-        if (!added) {
-            log.debug(
-                    "{} Attribute {} did not have a usable SAML 2 Attribute encoder associated with it, nothing to do",
+        if (super.encodeAttribute(registry, profileRequestContext, attribute, Attribute.class, results) == 0) {
+            log.debug("{} Attribute {} did not have SAML 2 Attribute transcoder instructions associated, nothing to do",
                     getLogPrefix(), attribute.getId());
         }
     }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list