[NUI] Adjust directory (#903)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Xaml / XamlParser.cs
index 38d78b8..fa00be6 100755 (executable)
@@ -34,420 +34,367 @@ using System.Xml;
 using Tizen.NUI.Binding;
 using Tizen.NUI.BaseComponents;
 using Tizen.NUI.UIComponents;
-using Tizen.NUI.Internals;
+using Tizen.NUI.Binding.Internals;
 
 namespace Tizen.NUI.Xaml
 {
-       static class XamlParser
-       {
-               public const string XFUri = "http://xamarin.com/schemas/2014/forms";
-               public const string NUI2018Uri = "http://tizen.org/Tizen.NUI/2018/XAML";
-               public const string X2006Uri = "http://schemas.microsoft.com/winfx/2006/xaml";
-               public const string X2009Uri = "http://schemas.microsoft.com/winfx/2009/xaml";
-               public const string McUri = "http://schemas.openxmlformats.org/markup-compatibility/2006";
-
-               public static void ParseXaml(RootNode rootNode, XmlReader reader)
-               {
-                       IList<KeyValuePair<string, string>> xmlns;
-                       var attributes = ParseXamlAttributes(reader, out xmlns);
-                       var prefixes = PrefixesToIgnore(xmlns);
-                       (rootNode.IgnorablePrefixes ?? (rootNode.IgnorablePrefixes=new List<string>())).AddRange(prefixes);
-                       rootNode.Properties.AddRange(attributes);
-                       ParseXamlElementFor(rootNode, reader);
-               }
-
-               static void ParseXamlElementFor(IElementNode node, XmlReader reader)
-               {
-                       Debug.Assert(reader.NodeType == XmlNodeType.Element);
-
-                       var elementName = reader.Name;
-                       var isEmpty = reader.IsEmptyElement;
-
-                       if (isEmpty)
-                               return;
-
-                       while (reader.Read())
-                       {
-                               switch (reader.NodeType)
-                               {
-                                       case XmlNodeType.EndElement:
-                                               Debug.Assert(reader.Name == elementName); //make sure we close the right element
-                                               return;
-                                       case XmlNodeType.Element:
-                                               // 1. Property Element.
-                                               if (reader.Name.Contains("."))
-                                               {
-                                                       XmlName name;
-                                                       if (reader.Name.StartsWith(elementName + ".", StringComparison.Ordinal))
-                                                               name = new XmlName(reader.NamespaceURI, reader.Name.Substring(elementName.Length + 1));
-                                                       else //Attached DP
-                                                               name = new XmlName(reader.NamespaceURI, reader.LocalName);
-
-                                                       var prop = ReadNode(reader);
-                                                       if (prop != null)
-                                                               node.Properties.Add(name, prop);
-                                               }
-                                               // 2. Xaml2009 primitives, x:Arguments, ...
-                                               else if (reader.NamespaceURI == X2009Uri && reader.LocalName == "Arguments")
-                                               {
-                                                       var prop = ReadNode(reader);
-                                                       if (prop != null)
-                                                               node.Properties.Add(XmlName.xArguments, prop);
-                                               }
-                                               // 3. DataTemplate (should be handled by 4.)
-                                               else if ((node.XmlType.NamespaceUri == XFUri || node.XmlType.NamespaceUri == NUI2018Uri) &&
-                                                        (node.XmlType.Name == "DataTemplate" || node.XmlType.Name == "ControlTemplate"))
-                                               {
-                                                       var prop = ReadNode(reader, true);
-                                                       if (prop != null)
-                                                               node.Properties.Add(XmlName._CreateContent, prop);
-                                               }
-                                               // 4. Implicit content, implicit collection, or collection syntax. Add to CollectionItems, resolve case later.
-                                               else
-                                               {
-                                                       var item = ReadNode(reader, true);
-                                                       if (item != null)
-                                                               node.CollectionItems.Add(item);
-                                               }
-                                               break;
-                                       case XmlNodeType.Whitespace:
-                                               break;
-                                       case XmlNodeType.Text:
-                                       case XmlNodeType.CDATA:
-                                               if (node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode)
-                                                       ((ValueNode)node.CollectionItems[0]).Value += reader.Value.Trim();
-                                               else
-                                                       node.CollectionItems.Add(new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader));
-                                               break;
-                                       default:
-                                               Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
-                                               break;
-                               }
-                       }
-               }
-
-               static INode ReadNode(XmlReader reader, bool nested = false)
-               {
-                       var skipFirstRead = nested;
-                       Debug.Assert(reader.NodeType == XmlNodeType.Element);
-                       var name = reader.Name;
-                       List<INode> nodes = new List<INode>();
-                       INode node = null;
-
-                       while (skipFirstRead || reader.Read())
-                       {
-                               skipFirstRead = false;
-
-                               switch (reader.NodeType)
-                               {
-                                       case XmlNodeType.EndElement:
-                                               Debug.Assert(reader.Name == name);
-                                               if (nodes.Count == 0) //Empty element
-                                                       return null;
-                                               if (nodes.Count == 1)
-                                                       return nodes[0];
-                                               return new ListNode(nodes, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
-                                                       ((IXmlLineInfo)reader).LinePosition);
-                                       case XmlNodeType.Element:
-                                               var isEmpty = reader.IsEmptyElement && reader.Name == name;
-                                               var elementName = reader.Name;
-                                               var elementNsUri = reader.NamespaceURI;
-                                               var elementXmlInfo = (IXmlLineInfo)reader;
-                                               IList<KeyValuePair<string, string>> xmlns;
-
-                                               var attributes = ParseXamlAttributes(reader, out xmlns);
-                                               var prefixes = PrefixesToIgnore(xmlns);
-
-                                               IList<XmlType> typeArguments = null;
-                                               if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments))
-                                               {
-                                                       typeArguments =
-                                                               ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList<XmlType>;
-                                               }
-
-                                               node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri,
-                                                       reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition);
-                                               ((IElementNode)node).Properties.AddRange(attributes);
-                                               (node.IgnorablePrefixes ?? (node.IgnorablePrefixes = new List<string>())).AddRange(prefixes);
-
-                                               ParseXamlElementFor((IElementNode)node, reader);
-                                               nodes.Add(node);
-                                               if (isEmpty || nested)
-                                                       return node;
-                                               break;
-                                       case XmlNodeType.Text:
-                                               node = new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
-                                                       ((IXmlLineInfo)reader).LinePosition);
-                                               nodes.Add(node);
-                                               break;
-                                       case XmlNodeType.Whitespace:
-                                               break;
-                                       default:
-                                               Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
-                                               break;
-                               }
-                       }
-                       throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader);
-               }
-
-               static IList<KeyValuePair<XmlName, INode>> ParseXamlAttributes(XmlReader reader, out IList<KeyValuePair<string,string>> xmlns)
-               {
-                       Debug.Assert(reader.NodeType == XmlNodeType.Element);
-                       var attributes = new List<KeyValuePair<XmlName, INode>>();
-                       xmlns = new List<KeyValuePair<string, string>>();
-                       for (var i = 0; i < reader.AttributeCount; i++)
-                       {
-                               reader.MoveToAttribute(i);
-
-                               //skip xmlns
-                               if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/") {
-                                       xmlns.Add(new KeyValuePair<string, string>(reader.LocalName, reader.Value));
-                                       continue;
-                               }
-
-                               var namespaceUri = reader.NamespaceURI;
-                               if (reader.LocalName.Contains(".") && namespaceUri == "")
-                                       namespaceUri = ((IXmlNamespaceResolver)reader).LookupNamespace("");
-                               var propertyName = new XmlName(namespaceUri, reader.LocalName);
-
-                               object value = reader.Value;
-
-                               if (reader.NamespaceURI == X2006Uri)
-                               {
-                                       switch (reader.Name) {
-                                       case "x:Key":
-                                               propertyName = XmlName.xKey;
-                                               break;
-                                       case "x:Name":
-                                               propertyName = XmlName.xName;
-                                               break;
-                                       case "x:Class":
-                                       case "x:FieldModifier":
-                                               continue;
-                                       default:
-                                               Debug.WriteLine("Unhandled attribute {0}", reader.Name);
-                                               continue;
-                                       }
+    internal static class XamlParser
+    {
+        public const string XFUri = "http://tizen.org/Tizen.NUI/2018/XAML";
+        public const string NUI2018Uri = "http://tizen.org/Tizen.NUI/2018/XAML";
+        public const string X2006Uri = "http://schemas.microsoft.com/winfx/2006/xaml";
+        public const string X2009Uri = "http://schemas.microsoft.com/winfx/2009/xaml";
+        public const string McUri = "http://schemas.openxmlformats.org/markup-compatibility/2006";
+
+        public static void ParseXaml(RootNode rootNode, XmlReader reader)
+        {
+            IList<KeyValuePair<string, string>> xmlns;
+            var attributes = ParseXamlAttributes(reader, out xmlns);
+            var prefixes = PrefixesToIgnore(xmlns);
+            (rootNode.IgnorablePrefixes ?? (rootNode.IgnorablePrefixes=new List<string>())).AddRange(prefixes);
+            rootNode.Properties.AddRange(attributes);
+            ParseXamlElementFor(rootNode, reader);
+        }
+
+        static void ParseXamlElementFor(IElementNode node, XmlReader reader)
+        {
+            Debug.Assert(reader.NodeType == XmlNodeType.Element);
+
+            var elementName = reader.Name;
+            var isEmpty = reader.IsEmptyElement;
+
+            if (isEmpty)
+                return;
+
+            while (reader.Read())
+            {
+                switch (reader.NodeType)
+                {
+                    case XmlNodeType.EndElement:
+                        Debug.Assert(reader.Name == elementName); //make sure we close the right element
+                        return;
+                    case XmlNodeType.Element:
+                        // 1. Property Element.
+                        if (reader.Name.Contains("."))
+                        {
+                            XmlName name;
+                            if (reader.Name.StartsWith(elementName + ".", StringComparison.Ordinal))
+                                name = new XmlName(reader.NamespaceURI, reader.Name.Substring(elementName.Length + 1));
+                            else //Attached DP
+                                name = new XmlName(reader.NamespaceURI, reader.LocalName);
+
+                            var prop = ReadNode(reader);
+                            if (prop != null)
+                                node.Properties.Add(name, prop);
+                        }
+                        // 2. Xaml2009 primitives, x:Arguments, ...
+                        else if (reader.NamespaceURI == X2009Uri && reader.LocalName == "Arguments")
+                        {
+                            var prop = ReadNode(reader);
+                            if (prop != null)
+                                node.Properties.Add(XmlName.xArguments, prop);
+                        }
+                        // 3. DataTemplate (should be handled by 4.)
+                        else if ((node.XmlType.NamespaceUri == XFUri || node.XmlType.NamespaceUri == NUI2018Uri) &&
+                                 (node.XmlType.Name == "DataTemplate" || node.XmlType.Name == "ControlTemplate"))
+                        {
+                            var prop = ReadNode(reader, true);
+                            if (prop != null)
+                                node.Properties.Add(XmlName._CreateContent, prop);
+                        }
+                        // 4. Implicit content, implicit collection, or collection syntax. Add to CollectionItems, resolve case later.
+                        else
+                        {
+                            var item = ReadNode(reader, true);
+                            if (item != null)
+                                node.CollectionItems.Add(item);
+                        }
+                        break;
+                    case XmlNodeType.Whitespace:
+                        break;
+                    case XmlNodeType.Text:
+                    case XmlNodeType.CDATA:
+                        if (node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode)
+                            ((ValueNode)node.CollectionItems[0]).Value += reader.Value.Trim();
+                        else
+                            node.CollectionItems.Add(new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader));
+                        break;
+                    default:
+                        Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
+                        break;
                 }
+            }
+        }
 
-                               if (reader.NamespaceURI == X2009Uri)
-                               {
-                                       switch (reader.Name) {
-                                       case "x:Key":
-                                               propertyName = XmlName.xKey;
-                                               break;
-                                       case "x:Name":
-                                               propertyName = XmlName.xName;
-                                               break;
-                                       case "x:TypeArguments":
-                                               propertyName = XmlName.xTypeArguments;
-                                               value = TypeArgumentsParser.ParseExpression((string)value, (IXmlNamespaceResolver)reader, (IXmlLineInfo)reader);
-                                               break;
-                                       case "x:DataType":
-                                               propertyName = XmlName.xDataType;
-                                               break;
-                                       case "x:Class":
-                                       case "x:FieldModifier":
-                                               continue;
-                                       case "x:FactoryMethod":
-                                               propertyName = XmlName.xFactoryMethod;
-                                               break;
-                                       case "x:Arguments":
-                                               propertyName = XmlName.xArguments;
-                                               break;
-                                       default:
-                                               Debug.WriteLine("Unhandled attribute {0}", reader.Name);
-                                               continue;
-                                       }
-                               }
-
-                               var propertyNode = GetValueNode(value, reader);
-                               attributes.Add(new KeyValuePair<XmlName, INode>(propertyName, propertyNode));
-                       }
-                       reader.MoveToElement();
-                       return attributes;
-               }
-
-               static IList<string> PrefixesToIgnore(IList<KeyValuePair<string, string>> xmlns)
-               {
-                       var prefixes = new List<string>();
-                       foreach (var kvp in xmlns) {
-                               var prefix = kvp.Key;
-
-                               string typeName = null, ns = null, asm = null, targetPlatform = null;
-                               XmlnsHelper.ParseXmlns(kvp.Value, out typeName, out ns, out asm, out targetPlatform);
-                               if (targetPlatform == null)
-                                       continue;
-                               try {
-                                       if (targetPlatform != Device.RuntimePlatform)
-                                       {
-                                               // Special case for Windows backward compatibility
-                                               if (targetPlatform == "Windows" && Device.RuntimePlatform == Device.UWP)
-                                                       continue;
-                                               
-                                               prefixes.Add(prefix);
-                                       }
-                               } catch (InvalidOperationException) {
-                                       prefixes.Add(prefix);
-                               }
-                       }
-                       return prefixes;
-               }
-
-               static IValueNode GetValueNode(object value, XmlReader reader)
-               {
-                       var valueString = value as string;
-                       if (valueString != null && valueString.Trim().StartsWith("{}", StringComparison.Ordinal))
-                       {
-                               return new ValueNode(valueString.Substring(2), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
-                                       ((IXmlLineInfo)reader).LinePosition);
-                       }
-                       if (valueString != null && valueString.Trim().StartsWith("{", StringComparison.Ordinal))
-                       {
-                               return new MarkupNode(valueString.Trim(), reader as IXmlNamespaceResolver, ((IXmlLineInfo)reader).LineNumber,
-                                       ((IXmlLineInfo)reader).LinePosition);
-                       }
-                       return new ValueNode(value, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
-                               ((IXmlLineInfo)reader).LinePosition);
-               }
-
-               static IList<XmlnsDefinitionAttribute> s_xmlnsDefinitions;
-
-               static void GatherXmlnsDefinitionAttributes()
-               {
-                       //this could be extended to look for [XmlnsDefinition] in all assemblies
-                       var assemblies = new [] {
-                               typeof(View).GetTypeInfo().Assembly,
-                               typeof(XamlLoader).GetTypeInfo().Assembly,
-                       };
-
-                       s_xmlnsDefinitions = new List<XmlnsDefinitionAttribute>();
-
-                       foreach (var assembly in assemblies)
-                               foreach (XmlnsDefinitionAttribute attribute in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute))) {
-                                       s_xmlnsDefinitions.Add(attribute);
-                                       attribute.AssemblyName = attribute.AssemblyName ?? assembly.FullName;
-                               }
-               }
-
-               public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly,
-                       out XamlParseException exception)
-               {
-                       if (s_xmlnsDefinitions == null)
-                               GatherXmlnsDefinitionAttributes();
-
-                       var namespaceURI = xmlType.NamespaceUri;
-                       var elementName = xmlType.Name;
-                       var typeArguments = xmlType.TypeArguments;
-                       exception = null;
-
-                       var lookupAssemblies = new List<XmlnsDefinitionAttribute>();
-                       var lookupNames = new List<string>();
-
-                       foreach (var xmlnsDef in s_xmlnsDefinitions) {
-                               if (xmlnsDef.XmlNamespace != namespaceURI)
-                                       continue;
-                               lookupAssemblies.Add(xmlnsDef);
-                       }
-
-                       if (lookupAssemblies.Count == 0) {
-                               string ns, asmstring, _;
-                               XmlnsHelper.ParseXmlns(namespaceURI, out _, out ns, out asmstring, out _);
-                               lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns) {
-                                       AssemblyName = asmstring ?? currentAssembly.FullName
-                               });
-                       }
-
-                       lookupNames.Add(elementName);
-                       lookupNames.Add(elementName + "Extension");
-
-                       for (var i = 0; i < lookupNames.Count; i++)
-                       {
-                               var name = lookupNames[i];
-                               if (name.Contains(":"))
-                                       name = name.Substring(name.LastIndexOf(':') + 1);
-                               if (typeArguments != null)
-                                       name += "`" + typeArguments.Count; //this will return an open generic Type
-                               lookupNames[i] = name;
-                       }
-
-                       Type type = null;
-                       foreach (var asm in lookupAssemblies) {
-                               foreach (var name in lookupNames)
-                                       if ((type = Type.GetType($"{asm.ClrNamespace}.{name}, {asm.AssemblyName}")) != null)
-                                               break;
-                               if (type != null)
-                                       break;
-                       }
+        static INode ReadNode(XmlReader reader, bool nested = false)
+        {
+            var skipFirstRead = nested;
+            Debug.Assert(reader.NodeType == XmlNodeType.Element);
+            var name = reader.Name;
+            List<INode> nodes = new List<INode>();
+            INode node = null;
 
-            if (type == null)
+            while (skipFirstRead || reader.Read())
             {
-                List<Tuple<string, Assembly>> lookupAssemblies2 = new List<Tuple<string, Assembly>>();
-                if (namespaceURI == NUI2018Uri)
+                skipFirstRead = false;
+
+                switch (reader.NodeType)
                 {
-                    // Got the type of Tizen.NUI wiedget here, then CreateValueVisitor will create the instance of Tizen.NUI widget
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("Tizen.NUI", typeof(Tizen.NUI.BaseComponents.View).GetTypeInfo().Assembly));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("Tizen.NUI.BaseComponents", typeof(Tizen.NUI.BaseComponents.View).GetTypeInfo().Assembly));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("Tizen.NUI.UIComponents", typeof(Tizen.NUI.BaseComponents.View).GetTypeInfo().Assembly));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("Tizen.NUI.Xaml", typeof(XamlLoader).GetTypeInfo().Assembly));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("Tizen.NUI.Binding", typeof(Tizen.NUI.BaseComponents.View).GetTypeInfo().Assembly));
+                    case XmlNodeType.EndElement:
+                        Debug.Assert(reader.Name == name);
+                        if (nodes.Count == 0) //Empty element
+                            return null;
+                        if (nodes.Count == 1)
+                            return nodes[0];
+                        return new ListNode(nodes, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
+                            ((IXmlLineInfo)reader).LinePosition);
+                    case XmlNodeType.Element:
+                        var isEmpty = reader.IsEmptyElement && reader.Name == name;
+                        var elementName = reader.Name;
+                        var elementNsUri = reader.NamespaceURI;
+                        var elementXmlInfo = (IXmlLineInfo)reader;
+                        IList<KeyValuePair<string, string>> xmlns;
+
+                        var attributes = ParseXamlAttributes(reader, out xmlns);
+                        var prefixes = PrefixesToIgnore(xmlns);
+
+                        IList<XmlType> typeArguments = null;
+                        if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments))
+                        {
+                            typeArguments =
+                                ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList<XmlType>;
+                        }
+
+                        node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri,
+                            reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition);
+                        ((IElementNode)node).Properties.AddRange(attributes);
+                        (node.IgnorablePrefixes ?? (node.IgnorablePrefixes = new List<string>()))?.AddRange(prefixes);
+
+                        ParseXamlElementFor((IElementNode)node, reader);
+                        nodes.Add(node);
+                        if (isEmpty || nested)
+                            return node;
+                        break;
+                    case XmlNodeType.Text:
+                        node = new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
+                            ((IXmlLineInfo)reader).LinePosition);
+                        nodes.Add(node);
+                        break;
+                    case XmlNodeType.Whitespace:
+                        break;
+                    default:
+                        Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
+                        break;
                 }
-                else if (namespaceURI == X2009Uri || namespaceURI == X2006Uri)
-                {
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("Tizen.NUI.Xaml", typeof(XamlLoader).GetTypeInfo().Assembly));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("System", typeof(object).GetTypeInfo().Assembly));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>("System", typeof(Uri).GetTypeInfo().Assembly)); //System.dll
+            }
+            throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader);
+        }
+
+        static IList<KeyValuePair<XmlName, INode>> ParseXamlAttributes(XmlReader reader, out IList<KeyValuePair<string,string>> xmlns)
+        {
+            Debug.Assert(reader.NodeType == XmlNodeType.Element);
+            var attributes = new List<KeyValuePair<XmlName, INode>>();
+            xmlns = new List<KeyValuePair<string, string>>();
+            for (var i = 0; i < reader.AttributeCount; i++)
+            {
+                reader.MoveToAttribute(i);
+
+                //skip xmlns
+                if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/") {
+                    xmlns.Add(new KeyValuePair<string, string>(reader.LocalName, reader.Value));
+                    continue;
                 }
-                else
+
+                var namespaceUri = reader.NamespaceURI;
+                if (reader.LocalName.Contains(".") && namespaceUri == "")
+                    namespaceUri = ((IXmlNamespaceResolver)reader).LookupNamespace("");
+                var propertyName = new XmlName(namespaceUri, reader.LocalName);
+
+                object value = reader.Value;
+
+                if (reader.NamespaceURI == X2006Uri)
                 {
-                    string ns;
-                    string typename;
-                    string asmstring;
-                    Assembly asm;
-                    XmlnsHelper.ParseXmlns(namespaceURI, out typename, out ns, out asmstring, out _);
-                    asm = asmstring == null ? currentAssembly : Assembly.Load(new AssemblyName(asmstring));
-                    lookupAssemblies2.Add(new Tuple<string, Assembly>(ns, asm));
+                    switch (reader.Name) {
+                    case "x:Key":
+                        propertyName = XmlName.xKey;
+                        break;
+                    case "x:Name":
+                        propertyName = XmlName.xName;
+                        break;
+                    case "x:Class":
+                    case "x:FieldModifier":
+                        continue;
+                    default:
+                        Debug.WriteLine("Unhandled attribute {0}", reader.Name);
+                        continue;
+                    }
                 }
 
-                foreach (var asm in lookupAssemblies2)
+                if (reader.NamespaceURI == X2009Uri)
                 {
-                    if (type != null)
+                    switch (reader.Name) {
+                    case "x:Key":
+                        propertyName = XmlName.xKey;
+                        break;
+                    case "x:Name":
+                        propertyName = XmlName.xName;
+                        break;
+                    case "x:TypeArguments":
+                        propertyName = XmlName.xTypeArguments;
+                        value = TypeArgumentsParser.ParseExpression((string)value, (IXmlNamespaceResolver)reader, (IXmlLineInfo)reader);
+                        break;
+                    case "x:DataType":
+                        propertyName = XmlName.xDataType;
+                        break;
+                    case "x:Class":
+                    case "x:FieldModifier":
+                        continue;
+                    case "x:FactoryMethod":
+                        propertyName = XmlName.xFactoryMethod;
+                        break;
+                    case "x:Arguments":
+                        propertyName = XmlName.xArguments;
                         break;
-                    foreach (var name in lookupNames)
+                    default:
+                        Debug.WriteLine("Unhandled attribute {0}", reader.Name);
+                        continue;
+                    }
+                }
+
+                var propertyNode = GetValueNode(value, reader);
+                attributes.Add(new KeyValuePair<XmlName, INode>(propertyName, propertyNode));
+            }
+            reader.MoveToElement();
+            return attributes;
+        }
+
+        static IList<string> PrefixesToIgnore(IList<KeyValuePair<string, string>> xmlns)
+        {
+            var prefixes = new List<string>();
+            foreach (var kvp in xmlns) {
+                var prefix = kvp.Key;
+
+                string typeName = null, ns = null, asm = null;
+                XmlnsHelper.ParseXmlns(kvp.Value, out typeName, out ns, out asm);
+            }
+            return prefixes;
+        }
+
+        static IValueNode GetValueNode(object value, XmlReader reader)
+        {
+            var valueString = value as string;
+            if (valueString != null && valueString.Trim().StartsWith("{}", StringComparison.Ordinal))
+            {
+                return new ValueNode(valueString.Substring(2), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
+                    ((IXmlLineInfo)reader).LinePosition);
+            }
+            if (valueString != null && valueString.Trim().StartsWith("{", StringComparison.Ordinal))
+            {
+                return new MarkupNode(valueString.Trim(), reader as IXmlNamespaceResolver, ((IXmlLineInfo)reader).LineNumber,
+                    ((IXmlLineInfo)reader).LinePosition);
+            }
+            return new ValueNode(value, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber,
+                ((IXmlLineInfo)reader).LinePosition);
+        }
+
+        static IList<XmlnsDefinitionAttribute> s_xmlnsDefinitions;
+        public static IList<Assembly> s_assemblies = new List<Assembly>();// = new Assembly[]{};
+
+        static void GatherXmlnsDefinitionAttributes()
+        {
+            //this could be extended to look for [XmlnsDefinition] in all assemblies
+            // var assemblies = new [] {
+            //         typeof(View).GetTypeInfo().Assembly,
+            //         //typeof(XamlLoader).GetTypeInfo().Assembly,
+            // };
+            // s_assemblies = new Assembly[]{typeof(View).GetTypeInfo().Assembly};
+            s_assemblies.Add(typeof(View).GetTypeInfo().Assembly);
+
+            s_xmlnsDefinitions = new List<XmlnsDefinitionAttribute>();
+
+            foreach (var assembly in s_assemblies)
+                foreach (XmlnsDefinitionAttribute attribute in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute))) {
+                    s_xmlnsDefinitions.Add(attribute);
+                    attribute.AssemblyName = attribute.AssemblyName ?? assembly.FullName;
+                }
+        }
+
+        public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly,
+            out XamlParseException exception)
+        {
+            if (s_xmlnsDefinitions == null)
+                GatherXmlnsDefinitionAttributes();
+
+            var namespaceURI = xmlType.NamespaceUri;
+            var elementName = xmlType.Name;
+            var typeArguments = xmlType.TypeArguments;
+            exception = null;
+
+            var lookupAssemblies = new List<XmlnsDefinitionAttribute>();
+            var lookupNames = new List<string>();
+
+            foreach (var xmlnsDef in s_xmlnsDefinitions) {
+                if (xmlnsDef.XmlNamespace != namespaceURI)
+                    continue;
+                lookupAssemblies.Add(xmlnsDef);
+            }
+
+            if (lookupAssemblies.Count == 0) {
+                string ns, asmstring, _;
+                XmlnsHelper.ParseXmlns(namespaceURI, out _, out ns, out asmstring);
+                lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns) {
+                    AssemblyName = asmstring ?? currentAssembly.FullName
+                });
+            }
+
+            lookupNames.Add(elementName);
+            lookupNames.Add(elementName + "Extension");
+
+            for (var i = 0; i < lookupNames.Count; i++)
+            {
+                var name = lookupNames[i];
+                if (name.Contains(":"))
+                    name = name.Substring(name.LastIndexOf(':') + 1);
+                if (typeArguments != null)
+                    name += "`" + typeArguments.Count; //this will return an open generic Type
+                lookupNames[i] = name;
+            }
+
+            Type type = null;
+            foreach (var asm in lookupAssemblies) {
+                foreach (var name in lookupNames)
+                    if ((type = Type.GetType($"{asm.ClrNamespace}.{name}, {asm.AssemblyName}")) != null)
+                        break;
+                if (type != null)
+                    break;
+            }
+
+            if (type != null && typeArguments != null)
+            {
+                XamlParseException innerexception = null;
+                var args = typeArguments.Select(delegate(XmlType xmltype)
+                {
+                    XamlParseException xpe;
+                    var t = GetElementType(xmltype, xmlInfo, currentAssembly, out xpe);
+                    if (xpe != null)
                     {
-                        if (type != null)
-                            break;
-                        type = asm.Item2.GetType(asm.Item1 + "." + name);
+                        innerexception = xpe;
+                        return null;
                     }
+                    return t;
+                }).ToArray();
+                if (innerexception != null)
+                {
+                    exception = innerexception;
+                    return null;
                 }
+                type = type.MakeGenericType(args);
             }
 
-                       if (type != null && typeArguments != null)
-                       {
-                               XamlParseException innerexception = null;
-                               var args = typeArguments.Select(delegate(XmlType xmltype)
-                               {
-                                       XamlParseException xpe;
-                                       var t = GetElementType(xmltype, xmlInfo, currentAssembly, out xpe);
-                                       if (xpe != null)
-                                       {
-                                               innerexception = xpe;
-                                               return null;
-                                       }
-                                       return t;
-                               }).ToArray();
-                               if (innerexception != null)
-                               {
-                                       exception = innerexception;
-                                       return null;
-                               }
-                               type = type.MakeGenericType(args);
-                       }
-
-                       if (type == null)
-                               exception = new XamlParseException($"Type {elementName} not found in xmlns {namespaceURI}", xmlInfo);
-
-                       return type;
-               }
-       }
+            if (type == null)
+                exception = new XamlParseException($"Type {elementName} not found in xmlns {namespaceURI}", xmlInfo);
+
+            return type;
+        }
+    }
 }
\ No newline at end of file