diff --git a/docsys b/docsys
index 2ba01eabb08038d8d6671972157e6bc2515bcf8f..7b8bf5606c8b1d7af1088f9b48243d851ac983b3 160000
--- a/docsys
+++ b/docsys
@@ -1 +1 @@
-Subproject commit 2ba01eabb08038d8d6671972157e6bc2515bcf8f
+Subproject commit 7b8bf5606c8b1d7af1088f9b48243d851ac983b3
diff --git a/include/gen/SkinPartition.h b/include/gen/SkinPartition.h
index aa75225da2cb22f5eba9008ac07a1e4c5da64192..03f3b2a8622c1801a1fa9f1abd309bf41ebb30b1 100644
--- a/include/gen/SkinPartition.h
+++ b/include/gen/SkinPartition.h
@@ -86,6 +86,7 @@ struct SkinPartition {
 	//--BEGIN MISC CUSTOM CODE--//
 	/*! Calculate proper value of numTriangles field. */
 	unsigned short numTrianglesCalc() const;
+	unsigned short numTrianglesCalc(const NifInfo &) const;
 	//--END CUSTOM CODE--//
 };
 
diff --git a/include/gen/enums.h b/include/gen/enums.h
index 3c46bf0036fd3618b518c9789e45ef9771fa811e..ce2570644b295e8696259bb0513461d5eea4257d 100644
--- a/include/gen/enums.h
+++ b/include/gen/enums.h
@@ -117,6 +117,21 @@ enum HavokMaterial {
 	SKY_HAV_MAT_MATERIALSTONEASSTAIRS = 1886078335, /*!< Material Stone As Stairs */
 	SKY_HAV_MAT_MATERIAL_BLADE_2HAND = 2022742644, /*!< Material Blade 2Hand */
 	SKY_HAV_MAT_MATERIAL_BOTTLE_SMALL = 2025794648, /*!< MaterialBottleSmall */
+	SKY_HAV_MAT_SAND = 2168343821, /*!< Sand */
+	SKY_HAV_MAT_HEAVY_METAL = 2229413539, /*!< Heavy Metal */
+	SKY_HAV_MAT_MATERIAL_BLADE_1HAND_SMALL = 2617944780, /*!< Material Blade 1Hand Small, */
+	SKY_HAV_MAT_STAIRSBROKENSTONE = 2892392795, /*!< Stairs Broken Stone */
+	SKY_HAV_MAT_ORGANIC = 2974920155, /*!< Organic */
+	SKY_HAV_MAT_HEAVY_WOOD = 3070783559, /*!< Heavy Wood */
+	SKY_HAV_MAT_MATERIAL_CHAIN = 3074114406, /*!< MaterialChain */
+	SKY_HAV_MAT_DIRT = 3106094762, /*!< Dirt */
+	SKY_HAV_MAT_MATERIALCOIN = 3589100606, /*!< Material Coin */
+	SKY_HAV_MAT_MATERIALARROW = 3725505938, /*!< MaterialArrow */
+	SKY_HAV_MAT_GLASS = 3739830338, /*!< GLASS */
+	SKY_HAV_MAT_STONE = 3741512247, /*!< Stone */
+	SKY_HAV_MAT_CLOTH = 3839073443, /*!< Cloth */
+	SKY_HAV_MAT_MATERIAL_BLUNT_2HAND = 3969592277, /*!< Material Blunt 2Hand */
+	SKY_HAV_MAT_MATERIAL_BOULDER_MEDIUM = 4283869410, /*!< MaterialBoulderMedium */
 };
 
 ostream & operator<<( ostream & out, HavokMaterial const & val );
@@ -491,7 +506,7 @@ enum AlphaFormat {
 ostream & operator<<( ostream & out, AlphaFormat const & val );
 
 enum BoundVolumeType {
-	BASE_BV = -1, /*!< Default */
+	BASE_BV = 0xffffffff, /*!< Default */
 	SPHERE_BV = 0, /*!< Sphere */
 	BOX_BV = 1, /*!< Box */
 	CAPSULE_BV = 2, /*!< Capsule */
diff --git a/include/obj/NiGeometryData.h b/include/obj/NiGeometryData.h
index 51a623889ca4b263854fdb735a2e5cc0dc56d564..a32d2455398175f70913ff7ba7cacb4d98e1a930 100644
--- a/include/obj/NiGeometryData.h
+++ b/include/obj/NiGeometryData.h
@@ -256,8 +256,8 @@ public:
    NIFLIB_API void SetTangents( const vector<Vector3 >& value );
 
 private:
-   unsigned short numUvSetsCalc() const;
-   unsigned short bsNumUvSetsCalc() const;
+   unsigned short numUvSetsCalc(const NifInfo &) const;
+   unsigned short bsNumUvSetsCalc(const NifInfo &) const;
 
 	//--END CUSTOM CODE--//
 protected:
diff --git a/include/obj/NiLookAtController.h b/include/obj/NiLookAtController.h
index 3cd7e47c5902900b59f8c73b05b8c276fbf28042..08197a45362ec0e59f73ec615744e3f664968e74 100644
--- a/include/obj/NiLookAtController.h
+++ b/include/obj/NiLookAtController.h
@@ -14,9 +14,6 @@ All rights reserved.  Please see niflib.h for license. */
 //--END CUSTOM CODE--//
 
 #include "NiTimeController.h"
-
-// Include structures
-#include "../Ref.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
@@ -63,7 +60,7 @@ protected:
 	/*! Unknown. */
 	unsigned short unknown1;
 	/*! Link to the node to look at? */
-	Ref<NiNode > lookAtNode;
+	NiNode * lookAtNode;
 public:
 	/*! NIFLIB_HIDDEN function.  For internal use only. */
 	NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
diff --git a/include/obj/NiTriShapeData.h b/include/obj/NiTriShapeData.h
index bf21c8d3c87e19c3739cc491d698ee6f3f016bf5..fe4ecc8fdf000bdd1e0224fba5d4f32e5ac256e2 100644
--- a/include/obj/NiTriShapeData.h
+++ b/include/obj/NiTriShapeData.h
@@ -109,12 +109,17 @@ public:
 	 */
 	NIFLIB_API virtual void SetTriangles( const vector<Triangle> & in );
 
+private:
+	bool hasTrianglesCalc(const NifInfo & info) const {
+		return (triangles.size() > 0);
+	};
+
 	//--END CUSTOM CODE--//
 protected:
 	/*! Num Triangles times 3. */
 	unsigned int numTrianglePoints;
 	/*! Do we have triangle data? */
-	bool hasTriangles;
+	mutable bool hasTriangles;
 	/*! Triangle data. */
 	vector<Triangle > triangles;
 	/*! Number of shared normals groups. */
diff --git a/include/obj/bhkMoppBvTreeShape.h b/include/obj/bhkMoppBvTreeShape.h
index 10bd9af1bb3262af67c0e82f45ca650adc0e5e0f..cf30c843396cfc644e37cf3063d86cdb0839f317 100644
--- a/include/obj/bhkMoppBvTreeShape.h
+++ b/include/obj/bhkMoppBvTreeShape.h
@@ -140,6 +140,11 @@ public:
 	 */
 	NIFLIB_API virtual void CalcMassProperties(float density, bool solid, float &mass, float &volume, Vector3 &center, InertiaMatrix& inertia);
 
+private:
+	unsigned int moppDataSizeCalc(const NifInfo & info) const {
+		return (unsigned int)((info.version <= 0x0A000100) ? (oldMoppData.size() + 1) : moppData.size());
+	};
+
 	//--END CUSTOM CODE--//
 protected:
 	/*! The shape. */
diff --git a/src/gen/SkinPartition.cpp b/src/gen/SkinPartition.cpp
index 8157299a2caa96104b31fec98b36f78f70d4c36f..3864fa36034f10b166d1fac67f44b1638045b8cb 100644
--- a/src/gen/SkinPartition.cpp
+++ b/src/gen/SkinPartition.cpp
@@ -68,4 +68,8 @@ unsigned short SkinPartition::numTrianglesCalc() const {
 	return len;
 };
 
+unsigned short SkinPartition::numTrianglesCalc(const NifInfo & info) const {
+	return numTrianglesCalc();
+}
+
 //--END CUSTOM CODE--//
diff --git a/src/gen/enums.cpp b/src/gen/enums.cpp
index c1ed2ce75e3011af45cdf913ba1f07c2f99d1a64..f431ac60ab6ff6b0722b456c28b9eef489854330 100644
--- a/src/gen/enums.cpp
+++ b/src/gen/enums.cpp
@@ -202,6 +202,21 @@ ostream & operator<<( ostream & out, HavokMaterial const & val ) {
 		case SKY_HAV_MAT_MATERIALSTONEASSTAIRS: return out << "SKY_HAV_MAT_MATERIALSTONEASSTAIRS";
 		case SKY_HAV_MAT_MATERIAL_BLADE_2HAND: return out << "SKY_HAV_MAT_MATERIAL_BLADE_2HAND";
 		case SKY_HAV_MAT_MATERIAL_BOTTLE_SMALL: return out << "SKY_HAV_MAT_MATERIAL_BOTTLE_SMALL";
+		case SKY_HAV_MAT_SAND: return out << "SKY_HAV_MAT_SAND";
+		case SKY_HAV_MAT_HEAVY_METAL: return out << "SKY_HAV_MAT_HEAVY_METAL";
+		case SKY_HAV_MAT_MATERIAL_BLADE_1HAND_SMALL: return out << "SKY_HAV_MAT_MATERIAL_BLADE_1HAND_SMALL";
+		case SKY_HAV_MAT_STAIRSBROKENSTONE: return out << "SKY_HAV_MAT_STAIRSBROKENSTONE";
+		case SKY_HAV_MAT_ORGANIC: return out << "SKY_HAV_MAT_ORGANIC";
+		case SKY_HAV_MAT_HEAVY_WOOD: return out << "SKY_HAV_MAT_HEAVY_WOOD";
+		case SKY_HAV_MAT_MATERIAL_CHAIN: return out << "SKY_HAV_MAT_MATERIAL_CHAIN";
+		case SKY_HAV_MAT_DIRT: return out << "SKY_HAV_MAT_DIRT";
+		case SKY_HAV_MAT_MATERIALCOIN: return out << "SKY_HAV_MAT_MATERIALCOIN";
+		case SKY_HAV_MAT_MATERIALARROW: return out << "SKY_HAV_MAT_MATERIALARROW";
+		case SKY_HAV_MAT_GLASS: return out << "SKY_HAV_MAT_GLASS";
+		case SKY_HAV_MAT_STONE: return out << "SKY_HAV_MAT_STONE";
+		case SKY_HAV_MAT_CLOTH: return out << "SKY_HAV_MAT_CLOTH";
+		case SKY_HAV_MAT_MATERIAL_BLUNT_2HAND: return out << "SKY_HAV_MAT_MATERIAL_BLUNT_2HAND";
+		case SKY_HAV_MAT_MATERIAL_BOULDER_MEDIUM: return out << "SKY_HAV_MAT_MATERIAL_BOULDER_MEDIUM";
 		default: return out << "Invalid Value! - " << (unsigned int)(val);
 	}
 }
diff --git a/src/obj/NiGeometryData.cpp b/src/obj/NiGeometryData.cpp
index 5d080b6668841ad5fd07ddb01c67aeb3c78f00f0..799bfd00904f6c335c8388d81abc848ad1c22d22 100644
--- a/src/obj/NiGeometryData.cpp
+++ b/src/obj/NiGeometryData.cpp
@@ -157,8 +157,8 @@ void NiGeometryData::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 	//--END CUSTOM CODE--//
 
 	NiObject::Write( out, link_map, missing_link_stack, info );
-	bsNumUvSets = bsNumUvSetsCalc();
-	numUvSets = numUvSetsCalc();
+	bsNumUvSets = bsNumUvSetsCalc(info);
+	numUvSets = numUvSetsCalc(info);
 	numVertices = (unsigned short)(vertices.size());
 	if ( info.version >= 0x0A020000 ) {
 		NifStream( unknownInt, out, info );
@@ -297,8 +297,6 @@ std::string NiGeometryData::asString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << NiObject::asString();
-	bsNumUvSets = bsNumUvSetsCalc();
-	numUvSets = numUvSetsCalc();
 	numVertices = (unsigned short)(vertices.size());
 	out << "  Unknown Int:  " << unknownInt << endl;
 	if ( (!IsDerivedType(NiPSysData::TYPE)) ) {
@@ -719,11 +717,11 @@ void NiGeometryData::SetTangents( const vector<Vector3 >& value ) {
    tangents = value;
 }
 
-unsigned short NiGeometryData::numUvSetsCalc() const {
+unsigned short NiGeometryData::numUvSetsCalc(const NifInfo & info) const {
   return (numUvSets & (~63))  | (unsigned short)(uvSets.size() & 63);
 }
 
-unsigned short NiGeometryData::bsNumUvSetsCalc() const {
+unsigned short NiGeometryData::bsNumUvSetsCalc(const NifInfo & info) const {
   return (numUvSets & (~1))  | (unsigned short)(uvSets.size() & 1);
 }
 
diff --git a/src/obj/NiLookAtController.cpp b/src/obj/NiLookAtController.cpp
index b5efbee9a6b0be2fa781d7799e71969a61957f39..14dfb2e67f2ec48bf1df1c3f7dda6adcc33e5cef 100644
--- a/src/obj/NiLookAtController.cpp
+++ b/src/obj/NiLookAtController.cpp
@@ -112,14 +112,14 @@ void NiLookAtController::FixLinks( const map<unsigned int,NiObjectRef> & objects
 std::list<NiObjectRef> NiLookAtController::GetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = NiTimeController::GetRefs();
-	if ( lookAtNode != NULL )
-		refs.push_back(StaticCast<NiObject>(lookAtNode));
 	return refs;
 }
 
 std::list<NiObject *> NiLookAtController::GetPtrs() const {
 	list<NiObject *> ptrs;
 	ptrs = NiTimeController::GetPtrs();
+	if ( lookAtNode != NULL )
+		ptrs.push_back((NiObject *)(lookAtNode));
 	return ptrs;
 }
 
diff --git a/src/obj/NiSkinPartition.cpp b/src/obj/NiSkinPartition.cpp
index d71082bf2b348e201cb50be62b43091a330313e1..8d2bb76247b45aaab41491533d71b624adfa621c 100644
--- a/src/obj/NiSkinPartition.cpp
+++ b/src/obj/NiSkinPartition.cpp
@@ -218,7 +218,7 @@ void NiSkinPartition::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 		skinPartitionBlocks[i1].numWeightsPerVertex = (unsigned short)((skinPartitionBlocks[i1].vertexWeights.size() > 0) ? skinPartitionBlocks[i1].vertexWeights[0].size() : 0);
 		skinPartitionBlocks[i1].numStrips = (unsigned short)(skinPartitionBlocks[i1].stripLengths.size());
 		skinPartitionBlocks[i1].numBones = (unsigned short)(skinPartitionBlocks[i1].bones.size());
-		skinPartitionBlocks[i1].numTriangles = skinPartitionBlocks[i1].numTrianglesCalc();
+		skinPartitionBlocks[i1].numTriangles = skinPartitionBlocks[i1].numTrianglesCalc(info);
 		skinPartitionBlocks[i1].numVertices = (unsigned short)(skinPartitionBlocks[i1].vertexMap.size());
 		NifStream( skinPartitionBlocks[i1].numVertices, out, info );
 		NifStream( skinPartitionBlocks[i1].numTriangles, out, info );
@@ -352,7 +352,6 @@ std::string NiSkinPartition::asString( bool verbose ) const {
 		skinPartitionBlocks[i1].numWeightsPerVertex = (unsigned short)((skinPartitionBlocks[i1].vertexWeights.size() > 0) ? skinPartitionBlocks[i1].vertexWeights[0].size() : 0);
 		skinPartitionBlocks[i1].numStrips = (unsigned short)(skinPartitionBlocks[i1].stripLengths.size());
 		skinPartitionBlocks[i1].numBones = (unsigned short)(skinPartitionBlocks[i1].bones.size());
-		skinPartitionBlocks[i1].numTriangles = skinPartitionBlocks[i1].numTrianglesCalc();
 		skinPartitionBlocks[i1].numVertices = (unsigned short)(skinPartitionBlocks[i1].vertexMap.size());
 		out << "    Num Vertices:  " << skinPartitionBlocks[i1].numVertices << endl;
 		out << "    Num Triangles:  " << skinPartitionBlocks[i1].numTriangles << endl;
diff --git a/src/obj/NiTriShapeData.cpp b/src/obj/NiTriShapeData.cpp
index f9b538c29b919b45c3ce6befdfa777c7aab0c45d..3dde37b9592ac54e8dafb1efbc5cb1afc895d00c 100644
--- a/src/obj/NiTriShapeData.cpp
+++ b/src/obj/NiTriShapeData.cpp
@@ -83,6 +83,7 @@ void NiTriShapeData::Write( ostream& out, const map<NiObjectRef,unsigned int> &
 
 	NiTriBasedGeomData::Write( out, link_map, missing_link_stack, info );
 	numMatchGroups = (unsigned short)(matchGroups.size());
+	hasTriangles = hasTrianglesCalc(info);
 	NifStream( numTrianglePoints, out, info );
 	if ( info.version >= 0x0A010000 ) {
 		NifStream( hasTriangles, out, info );
diff --git a/src/obj/bhkMoppBvTreeShape.cpp b/src/obj/bhkMoppBvTreeShape.cpp
index 9f26181258b53d009c4f7cb86995c0b92dc3f5fc..1d05ce0e577dab30b99d371ed805ffbef1c345b4 100644
--- a/src/obj/bhkMoppBvTreeShape.cpp
+++ b/src/obj/bhkMoppBvTreeShape.cpp
@@ -78,7 +78,7 @@ void bhkMoppBvTreeShape::Write( ostream& out, const map<NiObjectRef,unsigned int
 	//--END CUSTOM CODE--//
 
 	bhkBvTreeShape::Write( out, link_map, missing_link_stack, info );
-	moppDataSize = (unsigned int)(oldMoppData.size());
+	moppDataSize = moppDataSizeCalc(info);
 	if ( info.version < VER_3_3_0_13 ) {
 		WritePtr32( &(*shape), out );
 	} else {
@@ -128,7 +128,6 @@ std::string bhkMoppBvTreeShape::asString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << bhkBvTreeShape::asString();
-	moppDataSize = (unsigned int)(oldMoppData.size());
 	out << "  Shape:  " << shape << endl;
 	out << "  Material:  " << material << endl;
 	out << "  Unknown Int 1:  " << unknownInt1 << endl;