Fix serialization error for TLDTagAttribute by splitting out object data into serializable and wrapper objects as we do in TLDTagElement.
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockCMAttributeDeclaration.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockCMAttributeDeclaration.java
new file mode 100644
index 0000000..35e50ff
--- /dev/null
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockCMAttributeDeclaration.java
@@ -0,0 +1,46 @@
+package org.eclipse.jst.jsf.core.tests.mock;
+
+import java.util.Enumeration;
+
+import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+
+public class MockCMAttributeDeclaration extends MockCMNode implements
+        CMAttributeDeclaration
+{
+
+    private CMDataType _cmType;
+
+    public MockCMAttributeDeclaration(String nodeName, CMDataType cmType)
+    {
+        super(nodeName, CMNode.ATTRIBUTE_DECLARATION);
+        _cmType = cmType;
+    }
+
+    public String getAttrName()
+    {
+        return super.getNodeName();
+    }
+
+    public CMDataType getAttrType()
+    {
+        return _cmType;
+    }
+
+    public String getDefaultValue()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Enumeration getEnumAttr()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getUsage()
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockCMNode.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockCMNode.java
new file mode 100644
index 0000000..f8b38a3
--- /dev/null
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockCMNode.java
@@ -0,0 +1,52 @@
+package org.eclipse.jst.jsf.core.tests.mock;
+
+import junit.framework.Assert;
+
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+
+public class MockCMNode implements CMNode
+{
+    private final String _nodeName;
+    private final int _nodeType;
+
+    public MockCMNode(final String nodeName, final int nodeType)
+    {
+        _nodeName = nodeName;
+        switch(nodeType)
+        {
+        case CMNode.ANY_ELEMENT:
+        case CMNode.ATTRIBUTE_DECLARATION:
+        case CMNode.DATA_TYPE:
+        case CMNode.DOCUMENT:
+        case CMNode.DOCUMENTATION:
+        case CMNode.ELEMENT_DECLARATION:
+        case CMNode.ENTITY_DECLARATION:
+        case CMNode.GROUP:
+        case CMNode.NAME_SPACE:
+            _nodeType = nodeType;
+        break;
+        default:
+            _nodeType = -1;
+            Assert.fail("Invalid type: "+nodeType);
+        }
+    }
+    public String getNodeName()
+    {
+        return _nodeName;
+    }
+
+    public int getNodeType()
+    {
+        return _nodeType;
+    }
+
+    public boolean supports(String propertyName)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getProperty(String propertyName)
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockJSPTagRegistry.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockJSPTagRegistry.java
index e5b62d1..05719ac 100644
--- a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockJSPTagRegistry.java
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockJSPTagRegistry.java
@@ -12,7 +12,6 @@
 import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.TagElement;
 import org.eclipse.jst.jsf.core.internal.tld.ITLDConstants;
 import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry;
-import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagHandlerElement;
 
 public class MockJSPTagRegistry implements ITagRegistry
 {
@@ -130,6 +129,10 @@
     
     private static class MyTagElement extends TagElement
     {
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
         private final String    _name;
         private final String    _uri;
         
@@ -164,6 +167,7 @@
             return null;
         }
 
+        @SuppressWarnings("rawtypes")
         @Override
         public Map getAttributeHandlers()
         {
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockTLDAttributeDeclaration.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockTLDAttributeDeclaration.java
new file mode 100644
index 0000000..502f881
--- /dev/null
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/mock/MockTLDAttributeDeclaration.java
@@ -0,0 +1,63 @@
+package org.eclipse.jst.jsf.core.tests.mock;
+
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDataTypeImpl;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDAttributeDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+
+public class MockTLDAttributeDeclaration extends MockCMAttributeDeclaration
+        implements TLDAttributeDeclaration
+{
+
+    private final String _description;
+    private final String _id;
+    private final boolean _required;
+
+    public MockTLDAttributeDeclaration(String nodeName, CMDataType cmType, String description, String id, boolean required)
+    {
+        super(nodeName, cmType);
+        _description = description;
+        _id = id;
+        _required = required;
+    }
+
+    public MockTLDAttributeDeclaration(final String nodeName, String description, String id, boolean required)
+    {
+        this(nodeName, new CMDataTypeImpl("foo data type name"), description, id, required);
+    }
+    public String getDescription()
+    {
+        return _description;
+    }
+
+    public String getId()
+    {
+        return _id;
+    }
+
+    public CMDocument getOwnerDocument()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getRtexprvalue()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getType()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isFragment()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isRequired()
+    {
+        return _required;
+    }
+
+}
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/serialization/TLDAttributeSerializationTests.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/serialization/TLDAttributeSerializationTests.java
new file mode 100644
index 0000000..ba2e9f9
--- /dev/null
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/serialization/TLDAttributeSerializationTests.java
@@ -0,0 +1,52 @@
+package org.eclipse.jst.jsf.core.tests.serialization;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.eclipse.jst.jsf.core.tests.mock.MockTLDAttributeDeclaration;
+import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagAttribute;
+import org.eclipse.jst.jsf.test.util.junit4.NoPluginEnvironment;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(NoPluginEnvironment.class)
+public class TLDAttributeSerializationTests
+{
+    private MockTLDAttributeDeclaration _decl;
+    private TLDTagAttribute _attribute;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        
+        _decl = new MockTLDAttributeDeclaration("mockAttr", "mockDesc", "mockId", true);
+        _attribute = new TLDTagAttribute(_decl);
+    }
+    
+    @Test
+    public void testWriteRead() throws Exception
+    {
+        assertFalse(_attribute.hasBeenDeserialized());
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        ObjectOutputStream serializationStream = new ObjectOutputStream(stream);
+        serializationStream.writeObject(_attribute);
+        ByteArrayInputStream inStream = new ByteArrayInputStream(stream.toByteArray());
+        ObjectInputStream deserializeStream = new ObjectInputStream(inStream);
+        Object readObject = deserializeStream.readObject();
+        assertNotNull(readObject);
+        assertTrue(readObject instanceof TLDTagAttribute);
+        TLDTagAttribute tagAttribute = (TLDTagAttribute) readObject;
+        assertEquals("mockAttr", tagAttribute.getName());
+        assertEquals("mockDesc", tagAttribute.getDescription());
+        assertEquals(true, tagAttribute.isRequired());
+        assertTrue(tagAttribute.hasBeenDeserialized());
+    }
+}
\ No newline at end of file