/// <summary>
		/// Parse binary block.
		/// </summary>
		public Managed Parse(BinaryParser parser)
		{
			var texture = this.context.Resolve<Texture>();
			texture.NameHash = parser.ConsumeUInt32();
			texture.Flags = parser.ConsumeUInt32();
			texture.FormatSW = (ImageFormat)parser.ConsumeByte();
			texture.FormatHW = (ImageFormat)parser.ConsumeByte();

			float x = parser.ConsumeFloat();
			float y = parser.ConsumeFloat();
			texture.UVScale = new Vector2(x, y);

			texture.Image = this.ParseImage(parser);

			var e = parser.ConsumeBool();
			//parser.Expect(false);

			return texture;
		}
		/// <summary>
		/// Parse binary block.
		/// </summary>
		public Managed Parse(BinaryParser parser)
		{
			var anim = this.context.Resolve<Anim>();
			anim.NameHash = parser.ConsumeUInt32();

			anim.Skeleton.HashReference = parser.ConsumeUInt32();
			var numBones = parser.ConsumeUInt32();
			var boneFlags = parser.ConsumeUInt32();

			for (var numFrames = parser.ConsumeUInt32(); numFrames > 0; --numFrames)
			{
				var frameId = parser.ConsumeUInt32();
				if (frameId == Hash.Get("CIwAnimKeyFrame"))
				{
					var frame = this.context.Resolve<AnimKeyFrame>();
					parser.Expect((uint)0x0);
					frame.Time = parser.ConsumeFloat();
					var type = parser.ConsumeByte();
					var someVec = parser.ConsumeVector3();
					parser.Expect(0x01);

					anim.AddFrame(frame);

					uint num;
					bool b;
					switch (type)
					{
						case 2:
							parser.ConsumeUInt32(); // 0x01FFFFF, 0x01FFFFE
							num = parser.ConsumeUInt32();
							b = parser.ConsumeBool();

							for (uint index = 0; index < num; ++index)
							{
								var bone = frame.Bones[(int)index];
								bone.BindingPos = parser.ConsumeVector3();
								bone.BindingRot = parser.ConsumeQuaternion();
							}
							break;
						case 3:
							parser.ConsumeUInt32(); // 0x00002000, 1
							num = parser.ConsumeUInt32();
							b = parser.ConsumeBool();
							for (uint index = 0; index < num; ++index)
							{
								parser.ConsumeQuaternion();
							}
							break;
						default:
							throw new NotImplementedException();
					}
					continue;
				}
				throw new NotImplementedException();

				//this.m_KeyFrames.Serialise(serialise);
			}
			anim.Duration = parser.ConsumeFloat();
			var aaa = parser.ConsumeUInt32();
			return anim;
			//throw new NotImplementedException();

			//serialise.Fixed(ref this.m_TransformPrecision);
			//serialise.ManagedHash(ref this.m_OfsAnim);
			//serialise.DebugWrite(256);
		}
		private void ParseModelBlockVerts(BinaryParser parser, Model model, uint name, uint size, uint numItems, ushort flags)
		{
			var uniqueValues = parser.ConsumeUInt16();
			var streamMesh = (model.Meshes[0]);
			streamMesh.Vertices.Clear();
			var itemsToRead = (int)uniqueValues;
			streamMesh.Vertices.EnsureAt((int)numItems - 1);
			for (int i = 0; i < itemsToRead; ++i)
			{
				float x = parser.ConsumeFloat();
				parser.Skip(1);
				streamMesh.Vertices[i] = new Vector3(x, 0, 0);
			}
			for (int i = 0; i < itemsToRead; ++i)
			{
				float x = parser.ConsumeFloat();
				parser.Skip(1);
				streamMesh.Vertices[i] = new Vector3(streamMesh.Vertices[i].X, x, 0);
			}
			for (int i = 0; i < itemsToRead; ++i)
			{
				float x = parser.ConsumeFloat();
				parser.Skip(1);
				streamMesh.Vertices[i] = new Vector3(streamMesh.Vertices[i].X, streamMesh.Vertices[i].Y, x);
			}
			while (itemsToRead < numItems)
			{
				streamMesh.Vertices[itemsToRead] = streamMesh.Vertices[parser.ConsumeUInt16()];
				++itemsToRead;
			}

			//var len = this.uniqueValues; // this.numItems; //

			//this.Resize(this.numItems);

			//if (serialise.IsWriting())
			//{
			//    throw new NotImplementedException();
			//}

			//for (int i = 0; i < len; ++i)
			//{
			//    short x = (short)(this.verts[i].X - mediane);
			//    serialise.Int16(ref x);
			//    this.verts[i].X = x + mediane;
			//}

			//for (int i = 0; i < len; ++i)
			//{
			//    short y = (short)(this.verts[i].Y - mediane);
			//    serialise.Int16(ref y);
			//    this.verts[i].Y = y + mediane;
			//}

			//for (int i = 0; i < len; ++i)
			//{
			//    short z = (short)(this.verts[i].Z - mediane);
			//    serialise.Int16(ref z);
			//    this.verts[i].Z = z + mediane;
			//}

			//ushort[] links = new ushort[this.numItems - this.uniqueValues];
			//serialise.Serialise(ref links);
			//for (int i = this.uniqueValues; i < this.numItems; ++i)
			//{
			//    this.verts[i] = this.verts[links[i - this.uniqueValues]];
			//}
		}
		/// <summary>
		/// Parse binary block.
		/// </summary>
		public Managed Parse(BinaryParser parser)
		{
			var model = this.context.Resolve<Model>();
			model.NameHash = parser.ConsumeUInt32();
			model.Flags = parser.ConsumeUInt32();
			var numVerts = parser.ConsumeUInt32();
			var numVertsUnique = parser.ConsumeUInt32();
			model.Center = parser.ConsumeVector3();
			model.Radius = parser.ConsumeFloat();
			var streamMesh = this.context.Resolve<Mesh>();
			model.Meshes.Add(streamMesh);

			streamMesh.NameHash = parser.ConsumeUInt32();
			//parser.Expect((uint)0x466dbf2a);

			var num = parser.ConsumeUInt32();
			for (; num > 0; --num)
			{
				var type = parser.ConsumeUInt32();

				var name = parser.ConsumeUInt32();
				var size = parser.ConsumeUInt32();
				var numItems = parser.ConsumeUInt32();
				var flags = parser.ConsumeUInt16();

				if (type == Hash.Get("CIwModelBlockGLUVs"))
				{
					this.ParseModelBlockGLUVs(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockCols"))
				{
					this.ParseModelBlockCols(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockGLTriList"))
				{
					this.ParseModelBlockGLTriList(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockNorms"))
				{
					this.ParseModelBlockNorms(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockVerts"))
				{
					this.ParseModelBlockVerts(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockVerts2D"))
				{
					this.ParseModelBlockVerts2D(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockBiTangents"))
				{
					this.ParseModelBlockBiTangents(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockTangents"))
				{
					this.ParseModelBlockTangents(parser, model, name, size, numItems, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelBlockChunk"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockChunkTree"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockChunkVerts"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockCols16"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockFaceFlags"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockGLPrimBase"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockGLRenderEdges"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockGLRenderVerts"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockGLTriStrip"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockGLUVs2"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockIndGroups"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimBase"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimF3"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimF4"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimFT3"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimFT4"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimG3"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimG4"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimGen3"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimGen4"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimGT3"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockPrimGT4"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockRenderEdges"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockRenderVerts"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelBlockSWOptim1"))
				{
					throw new NotImplementedException();
				}

				throw new FormatException("Unknown element");
			}

			num = parser.ConsumeUInt32();
			for (; num > 0; --num)
			{
				var type = parser.ConsumeUInt32();
				var name = parser.ConsumeUInt32();
				var flags = parser.ConsumeUInt32();

				if (type == Hash.Get("CIwModelExtPos"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelExtSelSet"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelExtSelSetEdge"))
				{
					throw new NotImplementedException();
				}
				if (type == Hash.Get("CIwModelExtSelSetFace"))
				{
					this.ParseModelExtSelSetFace(parser, model, name, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelExtSelSetVert"))
				{
					this.ParseModelExtSelSetVert(parser, model, name, flags);
					continue;
				}
				if (type == Hash.Get("CIwModelExtSphere"))
				{
					throw new NotImplementedException();
				}

				throw new FormatException("Unknown element");
			}

			num = parser.ConsumeUInt32();
			uint[] materials = new uint[num];
			for (uint matIndex = 0; matIndex < num; ++matIndex)
			{
				materials[matIndex] = parser.ConsumeUInt32();
			}

			foreach (var mesh in model.Meshes)
			{
				foreach (Surface submesh in mesh.Surfaces)
				{
					submesh.Material.HashReference = materials[submesh.Material.HashReference];
				}
			}

			return model;
		}