private void ReadPropertyCustom(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
			short serializerTypeIdentifierOriginal = reader.ReadInt16();
            bool typeIdentifier = (serializerTypeIdentifierOriginal & 0x4000) == 0x4000;
            short serializerTypeIdentifier = (short)(serializerTypeIdentifierOriginal & ~0x4000);

			Property property = new Property(PropertyType.Value);
			property.PropertyDeclaration = this.GetPropertyDeclaration(attributeIdentifier);
	
			switch (serializerTypeIdentifier)
			{
				// PropertyReference
				case 0x0089:
					short identifier = reader.ReadInt16();
					if (typeIdentifier)
					{
						TypeDeclaration declaringType = this.GetTypeDeclaration(identifier);
						string propertyName = reader.ReadString();
						property.Value = new PropertyDeclaration(propertyName, declaringType);
					}
					else
					{
						property.Value = this.GetPropertyDeclaration(identifier);
					}
					break;
	
				case 0x002e: // Boolean
					int value = reader.ReadByte();
					property.Value = (value == 0x01) ? "true" : "false";
					break;
	
				case 0x02e8: // SolidColorBrush
					switch (reader.ReadByte())
					{
						case 0x01: // KnownSolidColor
							uint color = reader.ReadUInt32();
							switch (color)
							{
								case 0x00ffffff:
									property.Value = "Transparent";
									break;
	
								default:
									property.Value = KnownColors.KnownColorFromUInt(color);
									break;
							}
							break;
	
						case 0x02: // OtherColor
							property.Value = reader.ReadString();
							break;
	
						default:
							throw new NotSupportedException();
					}
					break;
	
				case 0x02e9: // IntCollection
					using (StringWriter writer = new StringWriter())
					{
						byte format = reader.ReadByte();
						int count = reader.ReadInt32();
	
						switch (format)
						{
							case 0x01: // Consecutive
								for (int i = 0; i < count; i++)
								{
									if (i != 0)
									{
										writer.Write(",");
									}
	
									int number = reader.ReadInt32();
									writer.Write(number.ToString());
									if (number > count)
									{
										break;
									}
								}
								break;
	
							case 0x02: // Byte
								for (int i = 0; i < count; i++)
								{
									if (i != 0)
									{
										writer.Write(",");
									}

									int number = reader.ReadByte();
									writer.Write(number.ToString());
								}
								break;
	
							case 0x03: // UInt16
								for (int i = 0; i < count; i++)
								{
									if (i != 0)
									{
										writer.Write(",");
									}

									int number = reader.ReadUInt16();
									writer.Write(number.ToString());
								}
								break;
	
							case 0x04: // UInt32
								throw new NotSupportedException();
	
							default:
								throw new NotSupportedException();
						}
	
						property.Value = writer.ToString();
					}
					break;
	
				case 0x02ea: // PathData
					property.Value = PathDataParser.ParseStreamGeometry(reader);
					break;
	
				case 0x02ec: // Point
					using (StringWriter writer = new StringWriter())
					{
						int count = reader.ReadInt32();
						for (int i = 0; i < count; i++)
						{
							if (i != 0)
							{
								writer.Write(" ");
							}
	
							for (int j = 0; j < 2; j++)
							{
								if (j != 0)
								{
									writer.Write(",");
								}
	
								double number = reader.ReadCompressedDouble();
								writer.Write(number.ToString());
							}
						}
	
						property.Value = writer.ToString();
					}
					break;
	
				case 0x02eb: // Point3D
				case 0x02f0: // Vector3D
					using (StringWriter writer = new StringWriter())
					{
						int count = reader.ReadInt32();
						for (int i = 0; i < count; i++)
						{
							if (i != 0)
							{
								writer.Write(" ");
							}
	
							for (int j = 0; j < 3; j++)
							{
								if (j != 0)
								{
									writer.Write(",");
								}
	
								double number = reader.ReadCompressedDouble();
								writer.Write(number.ToString());
							}
						}
	
						property.Value = writer.ToString();
					}
					break;
	
				default:
                    property.Value = String.Format("Not supported serializer type identifier: 0x{0:x}", serializerTypeIdentifier);
                    break;
                    //throw new NotSupportedException();
			}
	
			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
		}
		private void ReadKeyElementStart(BamlBinaryReader reader)
		{
			short typeIdentifier = reader.ReadInt16();

			byte flags = reader.ReadByte();
			bool createUsingTypeConverter = ((flags & 1) != 0);
			bool injected = ((flags & 2) != 0);

			int position = reader.ReadInt32();
			bool shared = reader.ReadBoolean();
			bool sharedSet = reader.ReadBoolean();
	
			Property keyProperty = new Property(PropertyType.Complex);
			keyProperty.PropertyDeclaration = new PropertyDeclaration("x:Key");
			// At least for the case where we are processing the key of a dictionary,
			// we should not assume that the key is a type. This is particularly true
			// when the type is a ComponentResourceKey.
			//
			//keyProperty.Value = this.CreateTypeExtension(typeIdentifier);
			keyProperty.Value = this.CreateTypeExtension(typeIdentifier, false);

			Element dictionary = (Element)this.elementStack.Peek();
			this.AddDictionaryEntry(dictionary, position, keyProperty);
			this.elementStack.Push(keyProperty.Value);
		}
		private void ReadOptimizedStaticResource(BamlBinaryReader reader)
		{
			byte extension = reader.ReadByte(); // num1
			short valueIdentifier = reader.ReadInt16();

			bool typeExtension = ((extension & 1) == 1);
			bool staticExtension = ((extension & 2) == 2);

			object element = null;

			if (typeExtension)
			{
				Element innerElement = this.CreateTypeExtension(valueIdentifier);
				element = innerElement;
			}
			else if (staticExtension)
			{
				Element innerElement = new Element();
				innerElement.TypeDeclaration = new TypeDeclaration("x:Static");
				// innerElement.TypeDeclaration = new TypeDeclaration("StaticExtension", "System.Windows.Markup);

				ResourceName resourceName = (ResourceName) this.GetResourceName(valueIdentifier);
				innerElement.Arguments.Add(resourceName);

				element = innerElement;
			}
			else
			{
				string value = (string)this.stringTable[valueIdentifier];
				element = value;
			}

			this.staticResourceTable.Add(element);
		}
		private void ReadTypeInfo(BamlBinaryReader reader)
		{
			short typeIdentifier = reader.ReadInt16();
			short assemblyIdentifier = reader.ReadInt16();
			string typeFullName = reader.ReadString();
	
			assemblyIdentifier = (short) (assemblyIdentifier & 0x0fff);
			string assembly = (string) this.assemblyTable[assemblyIdentifier];

			TypeDeclaration typeDeclaration = null;

			int index = typeFullName.LastIndexOf('.');
			if (index != -1)
			{
				string name = typeFullName.Substring(index + 1);
				string namespaceName = typeFullName.Substring(0, index);
				typeDeclaration = new TypeDeclaration(name, namespaceName, assembly);
			}
			else
			{
				typeDeclaration = new TypeDeclaration(typeFullName, string.Empty, assembly);
			}

			this.typeTable.Add(typeIdentifier, typeDeclaration);
		}
		private void ReadStaticResourceStart(BamlBinaryReader reader)
		{
			short typeIdentifier = reader.ReadInt16();
			byte flags = reader.ReadByte(); // 1 = CreateUsingTypeConverter, 2 = Injected

			Element element = new Element();
			element.TypeDeclaration = this.GetTypeDeclaration(typeIdentifier);

			this.elementStack.Push(element);

			this.staticResourceTable.Add(element);
		}
		private void AddElementToTree(Element element, BamlBinaryReader reader)
		{
			if (this.rootElement == null)
			{
				this.rootElement = element;
			}
			else
			{
				Property property = this.elementStack.Peek() as Property;
				if (property != null)
				{
					switch (property.PropertyType)
					{
						case PropertyType.List:
						case PropertyType.Dictionary:
							IList elements = (IList)property.Value;
							elements.Add(element);
							break;

						case PropertyType.Complex:
							property.Value = element;
							break;

						default:
							throw new NotSupportedException();
					}
				}
				else
				{
					Element parent = this.elementStack.Peek() as Element;

					if (this.dictionaryKeyPositionTable.Contains(parent))
					{
						int currentPosition = (int) (reader.BaseStream.Position - 1);

						if (!this.dictionaryKeyStartTable.Contains(parent))
						{
							this.dictionaryKeyStartTable.Add(parent, currentPosition);
						}

						int startPosition = (int)this.dictionaryKeyStartTable[parent];

						int position = currentPosition - startPosition;

						IDictionary keyPositionTable = (IDictionary)this.dictionaryKeyPositionTable[parent];
						if ((keyPositionTable != null) && (keyPositionTable.Contains(position)))
						{
							IList list = (IList)keyPositionTable[position];
							foreach (Property keyProperty in list)
							{
								element.Properties.Add(keyProperty);
							}
						}
					}

					if (parent != null)
					{
						// The element could be a parameter to a constructor - e.g. the Type
						// for a ComponentResourceKey in which case it should be an argument
						// of that element.
						//
						if (this.constructorParameterTable.Count > 0 &&
							this.constructorParameterTable[this.constructorParameterTable.Count - 1] == parent)
						{
							parent.Arguments.Add(element);
						}
						else
							this.AddContent(parent, element);
					}
					else
					{
						throw new NotSupportedException();
					}
				}
			}
		}
		private void ReadPresentationOptionsAttribute(BamlBinaryReader reader)
		{
			string value = reader.ReadString();
			short nameIdentifier = reader.ReadInt16();
	
			Property property = new Property(PropertyType.Value);
			property.PropertyDeclaration = new PropertyDeclaration("PresentationOptions:" + this.stringTable[nameIdentifier]);
			property.Value = value;
	
			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
		}
		private void ReadDefAttribute(BamlBinaryReader reader)
		{
			string value = reader.ReadString();
			short attributeIdentifier = reader.ReadInt16();
	
			Property property = new Property(PropertyType.Declaration);
	
			switch (attributeIdentifier)
			{
				case -1:
					property.PropertyDeclaration = new PropertyDeclaration("x:Name");
					break;
	
				case -2:
					property.PropertyDeclaration = new PropertyDeclaration("x:Uid");
					break;
	
				default:
					property.PropertyDeclaration = this.GetPropertyDeclaration(attributeIdentifier);
					break;
			}
	
			property.Value = value;
	
			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
		}
		private void ReadDefAttributeKeyString(BamlBinaryReader reader)
		{
			short valueIdentifier = reader.ReadInt16();
			int position = reader.ReadInt32();
			bool shared = reader.ReadBoolean();
			bool sharedSet = reader.ReadBoolean();
			
			string key = (string) this.stringTable[valueIdentifier];
			if (key == null)
			{
				throw new NotSupportedException();
			}
	
			Property keyProperty = new Property(PropertyType.Value);
			keyProperty.PropertyDeclaration = new PropertyDeclaration("x:Key");
			keyProperty.Value = key;
	
			Element dictionary = (Element)this.elementStack.Peek();

			this.AddDictionaryEntry(dictionary, position, keyProperty);
		}
		private void ReadXmlnsProperty(BamlBinaryReader reader)
		{
			string prefix = reader.ReadString();
			string xmlNamespace = reader.ReadString();
	
			string[] assemblies = new string[reader.ReadInt16()];
			for (int i = 0; i < assemblies.Length; i++)
			{
				assemblies[i] = (string) this.assemblyTable[reader.ReadInt16()];
			}

			Property property = new Property(PropertyType.Namespace);
			property.PropertyDeclaration = new PropertyDeclaration(prefix, new TypeDeclaration("XmlNamespace", null, null));
			property.Value = xmlNamespace;

			this.namespaceManager.AddMapping(prefix, xmlNamespace);
	
			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
		}
		private void ReadNamespaceMapping(BamlBinaryReader reader)
		{
			string xmlNamespace = reader.ReadString();
			string clrNamespace = reader.ReadString();
			short assemblyIdentifier = reader.ReadInt16();
			string assembly = (string) this.assemblyTable[assemblyIdentifier];

			this.namespaceManager.AddNamespaceMapping(xmlNamespace, clrNamespace, assembly);
		}
		private void ReadPropertyComplexStart(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
	
			Property property = new Property(PropertyType.Complex);
			property.PropertyDeclaration = this.GetPropertyDeclaration(attributeIdentifier);

            //if (property.PropertyDeclaration.Name == "RelativeTransform")
            //{
            //    Console.WriteLine();
            //}

			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
	
			this.elementStack.Push(property);
		}
		private void ReadPropertyDictionaryStart(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
	
			Property property = new Property(PropertyType.Dictionary);
			property.Value = new ArrayList();
			property.PropertyDeclaration = this.GetPropertyDeclaration(attributeIdentifier);
	
			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
	
			this.elementStack.Push(property);
		}
		private void ReadContentProperty(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
	
			Element element = (Element) this.elementStack.Peek();
	
			Property contentProperty = this.GetContentProperty(element);
			if (contentProperty == null)
			{
				contentProperty = new Property(PropertyType.Content);
				element.Properties.Add(contentProperty);
			}

			PropertyDeclaration propertyName = this.GetPropertyDeclaration(attributeIdentifier);
			if ((contentProperty.PropertyDeclaration != null) && (contentProperty.PropertyDeclaration != propertyName))
			{
				throw new NotSupportedException();
			}

			contentProperty.PropertyDeclaration = propertyName;
		}
			private static void AddPathPoint(BamlBinaryReader reader, StringBuilder sb)
			{
				sb.AppendFormat("{0},{1} ", reader.ReadCompressedDouble(), reader.ReadCompressedDouble());
			}
		private void ReadDefAttributeKeyType(BamlBinaryReader reader)
		{
			short typeIdentifier = reader.ReadInt16();
			reader.ReadByte();
			int position = reader.ReadInt32();
			bool shared = reader.ReadBoolean();
			bool sharedSet = reader.ReadBoolean();
	
			Property keyProperty = new Property(PropertyType.Complex);
			keyProperty.PropertyDeclaration = new PropertyDeclaration("x:Key");
			keyProperty.Value = this.CreateTypeExtension(typeIdentifier);
	
			Element dictionary = (Element)this.elementStack.Peek();

			this.AddDictionaryEntry(dictionary, position, keyProperty);
		}
			private static double ReadPathDouble(BamlBinaryReader reader, bool isInt)
			{
				if (isInt)
					return reader.ReadInt32() * 1E-06;

				return reader.ReadCompressedDouble();
			}
		private void ReadText(BamlBinaryReader reader)
		{
			string value = reader.ReadString();
			ReadText(value);
		}
		private void ReadAssemblyInfo(BamlBinaryReader reader)
		{
			short assemblyIdentifier = reader.ReadInt16();
			string assemblyName = reader.ReadString();
			this.assemblyTable.Add(assemblyIdentifier, assemblyName);
		}
		private void ReadTextWithId(BamlBinaryReader reader)
		{
			short id = reader.ReadInt16();
			string value = this.stringTable[id] as string;
			ReadText(value);
		}
		private void ReadStringInfo(BamlBinaryReader reader)
		{
			short stringIdentifier = reader.ReadInt16();
			string value = reader.ReadString();

			// This isn't a bug but more of a usability issue. MS tends to use 
			// single character identifiers which makes it difficult to find 
			// the associated resource.
			//
			if (null != value && value.Length == 1)
				value = string.Format("[{0}] {1}", stringIdentifier, value);

			this.stringTable.Add(stringIdentifier, value);
		}
		private void ReadTextWithConverter(BamlBinaryReader reader)
		{
			string value = reader.ReadString();
			short converterTypeIdentifier = reader.ReadInt16();
			ReadText(value);	
		}
		private void ReadAttributeInfo(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
			short ownerTypeIdentifier = reader.ReadInt16();
			BamlAttributeUsage attributeUsage = (BamlAttributeUsage) reader.ReadByte();
			string attributeName = reader.ReadString();

			TypeDeclaration declaringType = this.GetTypeDeclaration(ownerTypeIdentifier);
			PropertyDeclaration propertyName = new PropertyDeclaration(attributeName, declaringType);
			this.propertyTable.Add(attributeIdentifier, propertyName);
		}
		public BamlTranslator(Stream stream):base(null, stream)
		{
			BamlBinaryReader reader = new BamlBinaryReader(stream);
	
			int length = reader.ReadInt32();
			string format = new string(new BinaryReader(stream, Encoding.Unicode).ReadChars(length >> 1));
			if (format != "MSBAML")
			{
                throw new NotSupportedException(String.Format("Not supported file format: {0}", format));
			}
	
			int readerVersion = reader.ReadInt32();
			int updateVersion = reader.ReadInt32();
			int writerVersion = reader.ReadInt32();
			if ((readerVersion != 0x00600000) || (updateVersion != 0x00600000) || (writerVersion != 0x00600000))
			{
                throw new NotSupportedException(String.Format("Not supported baml version: {0:x}", readerVersion));
			}
	
			while (reader.BaseStream.Position < reader.BaseStream.Length)
			{
				BamlRecordType recordType = (BamlRecordType) reader.ReadByte();
	
				long position = reader.BaseStream.Position;
				int size = 0;
	
				switch (recordType)
				{
					case BamlRecordType.XmlnsProperty:
					case BamlRecordType.PresentationOptionsAttribute:
					case BamlRecordType.PIMapping:
					case BamlRecordType.AssemblyInfo:
					case BamlRecordType.Property:
					case BamlRecordType.PropertyWithConverter:
					case BamlRecordType.PropertyCustom:
					case BamlRecordType.DefAttribute:
					case BamlRecordType.DefAttributeKeyString:
					case BamlRecordType.TypeInfo:
					case BamlRecordType.AttributeInfo:
					case BamlRecordType.StringInfo:
					case BamlRecordType.Text:
					case BamlRecordType.TextWithConverter:
					case BamlRecordType.TextWithId:
						size = reader.ReadCompressedInt32();
						break;
				}
	
				// Console.WriteLine(recordType.ToString());
	
				switch (recordType)
				{
					case BamlRecordType.DocumentStart:
						bool loadAsync = reader.ReadBoolean();
						int maxAsyncRecords = reader.ReadInt32();
						bool debugBaml = reader.ReadBoolean();
						break;
	
					case BamlRecordType.DocumentEnd:
						break;
	
					case BamlRecordType.ElementStart:
						this.namespaceManager.OnElementStart();
						this.ReadElementStart(reader);
						break;
	
					case BamlRecordType.ElementEnd:
						this.ReadElementEnd();
						this.namespaceManager.OnElementEnd();
						break;
	
					case BamlRecordType.KeyElementStart:
						this.ReadKeyElementStart(reader);
						break;
	
					case BamlRecordType.KeyElementEnd:
						this.ReadKeyElementEnd();
						break;
	
					case BamlRecordType.XmlnsProperty:
						this.ReadXmlnsProperty(reader);
						break;
	
					case BamlRecordType.PIMapping:
						this.ReadNamespaceMapping(reader);
						break;
	
					case BamlRecordType.PresentationOptionsAttribute:
						this.ReadPresentationOptionsAttribute(reader);
						break;
	
					case BamlRecordType.AssemblyInfo:
						this.ReadAssemblyInfo(reader);
						break;
	
					case BamlRecordType.StringInfo:
						this.ReadStringInfo(reader);
						break;
	
					case BamlRecordType.ConnectionId:
						reader.ReadInt32(); // ConnectionId
						break;
	
					case BamlRecordType.Property:
						this.ReadPropertyRecord(reader);
						break;
	
					case BamlRecordType.PropertyWithConverter:
						this.ReadPropertyWithConverter(reader);
						break;
	
					case BamlRecordType.PropertyWithExtension:
						this.ReadPropertyWithExtension(reader);
						break;
	
					case BamlRecordType.PropertyTypeReference:
						this.ReadPropertyTypeReference(reader);
						break;
	
					case BamlRecordType.PropertyWithStaticResourceId:
						this.ReadPropertyWithStaticResourceIdentifier(reader);
						break;
	
					case BamlRecordType.ContentProperty:
						this.ReadContentProperty(reader);
						break;
	
					case BamlRecordType.TypeInfo:
						this.ReadTypeInfo(reader);
						break;
	
					case BamlRecordType.AttributeInfo:
						this.ReadAttributeInfo(reader);
						break;
	
					case BamlRecordType.DefAttribute:
						this.ReadDefAttribute(reader);
						break;
	
					case BamlRecordType.DefAttributeKeyString:
						this.ReadDefAttributeKeyString(reader);
						break;
	
					case BamlRecordType.DefAttributeKeyType:
						this.ReadDefAttributeKeyType(reader);
						break;
	
					case BamlRecordType.Text:
						this.ReadText(reader);
						break;
	
					case BamlRecordType.TextWithConverter:
						this.ReadTextWithConverter(reader);
						break;
	
					case BamlRecordType.PropertyCustom:
						this.ReadPropertyCustom(reader);
						break;
	
					case BamlRecordType.PropertyListStart:
						this.ReadPropertyListStart(reader);
						break;
	
					case BamlRecordType.PropertyListEnd:
						this.ReadPropertyListEnd();
						break;
	
					case BamlRecordType.PropertyDictionaryStart:
						this.ReadPropertyDictionaryStart(reader);
						break;
	
					case BamlRecordType.PropertyDictionaryEnd:
						this.ReadPropertyDictionaryEnd();
						break;
	
					case BamlRecordType.PropertyComplexStart:
						this.ReadPropertyComplexStart(reader);
						break;
	
					case BamlRecordType.PropertyComplexEnd:
						this.ReadPropertyComplexEnd();
						break;
	
					case BamlRecordType.ConstructorParametersStart:
						this.ReadConstructorParametersStart();
						break;
	
					case BamlRecordType.ConstructorParametersEnd:
						this.ReadConstructorParametersEnd();
						break;
	
					case BamlRecordType.ConstructorParameterType:
						this.ReadConstructorParameterType(reader);
						break;
	
					case BamlRecordType.DeferableContentStart:
						int contentSize = reader.ReadInt32();
						break;
	
					case BamlRecordType.StaticResourceStart:
						this.ReadStaticResourceStart(reader);
						break;

					case BamlRecordType.StaticResourceEnd:
						this.ReadStaticResourceEnd(reader);
						break;

					case BamlRecordType.StaticResourceId:
						this.ReadStaticResourceIdentifier(reader);
						break;

					case BamlRecordType.OptimizedStaticResource:
						this.ReadOptimizedStaticResource(reader);
						break;
	
					case BamlRecordType.LineNumberAndPosition:
						this.lineNumber = reader.ReadInt32(); // LineNumber
						this.linePosition = reader.ReadInt32(); // Position
						// Console.WriteLine(lineNumber.ToString() + "," + linePosition.ToString());
						break;
	
					case BamlRecordType.LinePosition:
						this.linePosition = reader.ReadInt32(); // Position
						break;

					case BamlRecordType.TextWithId:
						this.ReadTextWithId(reader);
						break;

					default:
						throw new NotSupportedException(recordType.ToString());
				}
	
				if (size > 0)
				{
					reader.BaseStream.Position = position + size;
				}
			}
		}
		private void ReadStaticResourceEnd(BamlBinaryReader reader)
		{
			this.elementStack.Pop();
		}
			internal static object ParseStreamGeometry(BamlBinaryReader reader)
			{
				StringBuilder sb = new StringBuilder();
				bool shouldClose = false;
				char lastChar = '\0';

				while (true)
				{
					byte b = reader.ReadByte();
					bool bit1 = (b & 0x10) == 0x10;
					bool bit2 = (b & 0x20) == 0x20;
					bool bit3 = (b & 0x40) == 0x40;
					bool bit4 = (b & 0x80) == 0x80;

					switch (b & 0xF)
					{
						case 0x0: //Begin
							{
								shouldClose = bit2;

								AddPathCommand('M', ref lastChar, sb);
								AddPathPoint(reader, sb, bit3, bit4);
								break;
							}
						case 0x1: //LineTo
							{
								AddPathCommand('L', ref lastChar, sb);
								AddPathPoint(reader, sb, bit3, bit4);
								break;
							}
						case 0x2: //QuadraticBezierTo
							{
								AddPathCommand('Q', ref lastChar, sb);
								AddPathPoint(reader, sb, bit3, bit4);
								AddPathPoint(reader, sb);
								break;
							}
						case 0x3: //BezierTo
							{
								AddPathCommand('C', ref lastChar, sb);
								AddPathPoint(reader, sb, bit3, bit4);
								AddPathPoint(reader, sb);
								AddPathPoint(reader, sb);
								break;
							}
						case 0x4: //PolyLineTo
							{
								bool isStroked = bit1;
								bool isSmooth = bit2;
								AddPathCommand('L', ref lastChar, sb);
								int count = reader.ReadInt32();

								for (int i = 0; i < count; i++)
									AddPathPoint(reader, sb);
								break;
							}
						case 0x5: //PolyQuadraticBezierTo
							{
								AddPathCommand('Q', ref lastChar, sb);
								int count = reader.ReadInt32();
								//System.Diagnostics.Debug.Assert(count % 2 == 0);
								for (int i = 0; i < count; i++)
									AddPathPoint(reader, sb);
								break;
							}
						case 0x6: //PolyBezierTo
							{
								AddPathCommand('C', ref lastChar, sb);
								int count = reader.ReadInt32();
								//System.Diagnostics.Debug.Assert(count % 3 == 0);
								for (int i = 0; i < count; i++)
									AddPathPoint(reader, sb);
								break;
							}
						case 0x7: //ArcTo
							{
								double endPtX = ReadPathDouble(reader, bit3);
								double endPtY = ReadPathDouble(reader, bit4);
								byte arcInfo = reader.ReadByte();
								bool isLarge = (arcInfo & 0xF) != 0;
								bool clockWise = (arcInfo & 0xF0) != 0;
								double sizeX = reader.ReadCompressedDouble();
								double sizeY = reader.ReadCompressedDouble();
								double angle = reader.ReadCompressedDouble();
								sb.AppendFormat("A {0},{1} {2} {3} {4} {5},{6} ", sizeX, sizeY, angle, isLarge ? 1 : 0, clockWise ? 1 : 0, endPtX, endPtY);
								lastChar = 'A';
								break;
							}
						case 0x8: //Closed
							{
								if (shouldClose)
								{
									sb.Append("Z");
								}
								else if (sb.Length > 0)
								{
									// trim off the ending space
									sb.Remove(sb.Length - 1, 0);
								}

								return sb.ToString();
							}
						case 0x9: //FillRule
							{
								sb.Insert(0, bit1 ? "F1 " : "F0 ");
								lastChar = 'F';
								break;
							}
						default:
							throw new InvalidOperationException();
					}
				}
			}
		private void ReadConstructorParameterType(BamlBinaryReader reader)
		{
			short typeIdentifier = reader.ReadInt16();
	
			TypeDeclaration elementName = this.GetTypeDeclaration(typeIdentifier);
	
			Element element = (Element)this.elementStack.Peek();
			element.Arguments.Add(elementName);
		}
			private static void AddPathPoint(BamlBinaryReader reader, StringBuilder sb, bool flag1, bool flag2)
			{
				sb.AppendFormat("{0},{1} ", ReadPathDouble(reader, flag1), ReadPathDouble(reader, flag2));
			}
		private void ReadPropertyWithExtension(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
	
			// 0x025b StaticResource
			// 0x027a TemplateBinding
			// 0x00bd DynamicResource
			short extension = reader.ReadInt16();
			short valueIdentifier = reader.ReadInt16();

			bool typeExtension = ((extension & 0x4000) == 0x4000); 
			bool staticExtension = ((extension & 0x2000) == 0x2000);

			extension = (short) (extension & 0x0fff);
			
			Property property = new Property(PropertyType.Complex);
			property.PropertyDeclaration = this.GetPropertyDeclaration(attributeIdentifier);
	
			short typeIdentifier = (short) -(extension & 0x0fff);
	
			Element element = new Element();
			element.TypeDeclaration = this.GetTypeDeclaration(typeIdentifier);

			switch (extension)
			{
				case 0x00bd: // DynamicResource
				case 0x025b: // StaticResource
					{
						if (typeExtension)
						{
							Element innerElement = this.CreateTypeExtension(valueIdentifier);
							element.Arguments.Add(innerElement);
						}
						else if (staticExtension)
						{
							Element innerElement = new Element();
							innerElement.TypeDeclaration = new TypeDeclaration("x:Static");
							// innerElement.TypeDeclaration = new TypeDeclaration("StaticExtension", "System.Windows.Markup);

							ResourceName resourceName = (ResourceName) this.GetResourceName(valueIdentifier);
							innerElement.Arguments.Add(resourceName);

							element.Arguments.Add(innerElement);
						}
						else
						{
							string value = (string)this.stringTable[valueIdentifier];
							element.Arguments.Add(value);
						}
					}
					break;

				case 0x25a: // Static
					{
						ResourceName resourceName = (ResourceName) this.GetResourceName(valueIdentifier);
						element.Arguments.Add(resourceName);
					}
					break;

				case 0x027a: // TemplateBinding
					{
						PropertyDeclaration propertyName = this.GetPropertyDeclaration(valueIdentifier);
						element.Arguments.Add(propertyName);
					}
					break;
				
				default:
					throw new NotSupportedException("Unknown property with extension");
			}

			property.Value = element;
	
			Element parent = (Element) this.elementStack.Peek();
			parent.Properties.Add(property);
		}
		private void ReadPropertyWithConverter(BamlBinaryReader reader)
		{
			short attributeIdentifier = reader.ReadInt16();
			string value = reader.ReadString();
			short converterTypeIdentifier = reader.ReadInt16();
	
			Property property = new Property(PropertyType.Value);
			property.PropertyDeclaration = this.GetPropertyDeclaration(attributeIdentifier);
			property.Value = value;
	
			Element element = (Element)this.elementStack.Peek();
			element.Properties.Add(property);
		}