diff --git a/include/gen/ByteColor4.h b/include/gen/ByteColor4.h
new file mode 100644
index 0000000000000000000000000000000000000000..1228d9bd762215134510c5334ff0956bf9215d2b
--- /dev/null
+++ b/include/gen/ByteColor4.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+//---THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT---//
+
+//To change this file, alter the niftools/docsys/nifxml_niflib.py Python script.
+
+#ifndef _BYTECOLOR4_H_
+#define _BYTECOLOR4_H_
+
+#include "../NIF_IO.h"
+
+namespace Niflib {
+
+
+/*!
+ * 
+ */
+struct ByteColor4 {
+	/*! Default Constructor */
+	NIFLIB_API ByteColor4();
+	/*! Default Destructor */
+	NIFLIB_API ~ByteColor4();
+	/*! Copy Constructor */
+	NIFLIB_API ByteColor4( const ByteColor4 & src );
+	/*! Copy Operator */
+	NIFLIB_API ByteColor4 & operator=( const ByteColor4 & src );
+	/*!
+	 * Red color component.
+	 */
+	byte r;
+	/*!
+	 * Green color component.
+	 */
+	byte g;
+	/*!
+	 * Blue color component.
+	 */
+	byte b;
+	/*!
+	 * Alpha color component.
+	 */
+	byte a;
+};
+
+}
+#endif
diff --git a/include/gen/MultiTextureElement.h b/include/gen/MultiTextureElement.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f37657ac23d242211f13c65d9c7c15cc73e900d
--- /dev/null
+++ b/include/gen/MultiTextureElement.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+//---THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT---//
+
+//To change this file, alter the niftools/docsys/nifxml_niflib.py Python script.
+
+#ifndef _MULTITEXTUREELEMENT_H_
+#define _MULTITEXTUREELEMENT_H_
+
+#include "../NIF_IO.h"
+
+// Include structures
+#include "../Ref.h"
+namespace Niflib {
+
+// Forward define of referenced NIF objects
+class NiImage;
+
+/*!
+ * 
+ */
+struct MultiTextureElement {
+	/*! Default Constructor */
+	NIFLIB_API MultiTextureElement();
+	/*! Default Destructor */
+	NIFLIB_API ~MultiTextureElement();
+	/*! Copy Constructor */
+	NIFLIB_API MultiTextureElement( const MultiTextureElement & src );
+	/*! Copy Operator */
+	NIFLIB_API MultiTextureElement & operator=( const MultiTextureElement & src );
+	/*!
+	 * Looks like a memory address, so probably a bool.
+	 */
+	bool hasImage;
+	/*!
+	 * Link to the texture image.
+	 */
+	Ref<NiImage > image;
+	/*!
+	 * Unkown.  Usually 3 but sometimes 0.
+	 */
+	unsigned int unknownInt1;
+	/*!
+	 * Unkown. Usually 2.
+	 */
+	unsigned int unknownInt2;
+	/*!
+	 * Unkown. Usually 1.
+	 */
+	unsigned int unknownInt3;
+	/*!
+	 * Unknown.  Usually 0.
+	 */
+	short unknownShort1;
+	/*!
+	 * Unknown.  Usually -75.
+	 */
+	short unknownShort2;
+	/*!
+	 * Unknown.  Usually 0 but sometimes 257
+	 */
+	short unknownShort3;
+};
+
+}
+#endif
diff --git a/include/gen/OldSkinData.h b/include/gen/OldSkinData.h
new file mode 100644
index 0000000000000000000000000000000000000000..9be6564f451b2369113068c0cc21cf1c50905d55
--- /dev/null
+++ b/include/gen/OldSkinData.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+//---THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT---//
+
+//To change this file, alter the niftools/docsys/nifxml_niflib.py Python script.
+
+#ifndef _OLDSKINDATA_H_
+#define _OLDSKINDATA_H_
+
+#include "../NIF_IO.h"
+
+namespace Niflib {
+
+
+/*!
+ * Used to store skin weights in NiTriShapeSkinController.
+ */
+struct OldSkinData {
+	/*! Default Constructor */
+	NIFLIB_API OldSkinData();
+	/*! Default Destructor */
+	NIFLIB_API ~OldSkinData();
+	/*! Copy Constructor */
+	NIFLIB_API OldSkinData( const OldSkinData & src );
+	/*! Copy Operator */
+	NIFLIB_API OldSkinData & operator=( const OldSkinData & src );
+	/*!
+	 * The amount that this bone affects the vertex.
+	 */
+	float vertexWeight;
+	/*!
+	 * The index of the vertex that this weight applies to.
+	 */
+	unsigned short vertexIndex;
+	/*!
+	 * Unknown.  Perhaps some sort of offset?
+	 */
+	Vector3 unknownVector;
+};
+
+}
+#endif
diff --git a/include/gen/enums.h b/include/gen/enums.h
index e6c97484db5555433aaedd479a8e3bee462930a1..541417521bb5871b6fc99b86c85a5bb14cb69667 100644
--- a/include/gen/enums.h
+++ b/include/gen/enums.h
@@ -120,8 +120,8 @@ ostream & operator<<( ostream & out, MipMapFormat const & val );
 
 /*!
  * This enum defines the various actions used in conjunction with the
- * stencil buffer.                 For a detailed description of the
- * individual options please refer to the OpenGL docs.
+ * stencil buffer.         For a detailed description of the individual
+ * options please refer to the OpenGL docs.
  */
 enum StencilAction {
 	ACTION_KEEP = 0, /*!< ACTION_KEEP */
diff --git a/include/gen/obj_defines.h b/include/gen/obj_defines.h
index a8769005c8ec637718d4091fc8f390a916152b74..59af5ee1d5dd3136fcfa96a3f25d43c1a2cd8b8c 100644
--- a/include/gen/obj_defines.h
+++ b/include/gen/obj_defines.h
@@ -18,6 +18,15 @@ All rights reserved.  Please see niflib.h for license. */
 Ref<AParticleModifier > nextModifier; \
 NiParticleSystemController * controller; \
 
+#define NI_P_SYS_COLLIDER_MEMBERS \
+float bounce; \
+bool spawnOnCollide; \
+bool dieOnCollide; \
+Ref<NiPSysSpawnModifier > spawnModifier; \
+NiObject * parent; \
+Ref<NiObject > nextCollider; \
+Ref<NiNode > colliderObject; \
+
 #define BHK_REF_OBJECT_MEMBERS \
 
 #define BHK_SERIALIZABLE_MEMBERS \
@@ -90,6 +99,7 @@ Ref<NiCollisionObject > collisionObject; \
 
 #define NI_DYNAMIC_EFFECT_MEMBERS \
 bool switchState; \
+mutable unsigned int numAffectedNodeListPointers; \
 mutable unsigned int numAffectedNodes; \
 vector<unsigned int > affectedNodeListPointers; \
 vector<Ref<NiAVObject > > affectedNodes; \
@@ -282,13 +292,6 @@ vector<Ref<NiTriStripsData > > stripsData; \
 mutable unsigned int numDataLayers; \
 vector<OblivionColFilter > dataLayers; \
 
-#define BHK_MESH_SHAPE_MEMBERS \
-array<8,int > unknown; \
-mutable int unknownCount; \
-vector< array<3,float > > unknownFloats; \
-mutable unsigned int numStripsData; \
-vector<Ref<NiTriStripsData > > stripsData; \
-
 #define BHK_PACKED_NI_TRI_STRIPS_SHAPE_MEMBERS \
 mutable unsigned short numSubShapes; \
 vector<OblivionSubShape > subShapes; \
@@ -404,6 +407,22 @@ vector<float > sizes; \
 #define NI_BINARY_EXTRA_DATA_MEMBERS \
 ByteArray binaryData; \
 
+#define NI_BINARY_VOXEL_EXTRA_DATA_MEMBERS \
+unsigned int unknownInt; \
+Ref<NiBinaryVoxelData > data; \
+
+#define NI_BINARY_VOXEL_DATA_MEMBERS \
+unsigned short unknownShort1; \
+unsigned short unknownShort2; \
+unsigned short unknownShort3; \
+array<7,float > unknown7Floats; \
+array< 7, array<12,byte > > unknownBytes1; \
+mutable unsigned int numUnknownVectors; \
+vector<Float4 > unknownVectors; \
+mutable unsigned int numUnknownBytes2; \
+vector<byte > unknownBytes2; \
+array<5,unsigned int > unknown5Ints; \
+
 #define NI_BLEND_BOOL_INTERPOLATOR_MEMBERS \
 byte boolValue; \
 
@@ -557,7 +576,7 @@ float floatData; \
 
 #define NI_FLOAT_EXTRA_DATA_CONTROLLER_MEMBERS \
 Ref<NiObject > unknownLink; \
-string unknownString; \
+string controllerData; \
 
 #define NI_FLOAT_INTERPOLATOR_MEMBERS \
 float floatValue; \
@@ -679,6 +698,8 @@ vector<Ref<NiAVObject > > children; \
 mutable unsigned int numEffects; \
 vector<Ref<NiDynamicEffect > > effects; \
 
+#define NI_BONE_MEMBERS \
+
 #define AVOID_NODE_MEMBERS \
 
 #define FX_WIDGET_MEMBERS \
@@ -931,10 +952,12 @@ mutable unsigned int numVisibilityKeys_; \
 vector<Key<byte > > visibilityKeys_; \
 
 #define NI_P_SYS_EMITTER_DECLINATION_CTLR_MEMBERS \
+Ref<NiFloatData > data; \
 
 #define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_MEMBERS \
 
 #define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_MEMBERS \
+Ref<NiFloatData > data; \
 
 #define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_MEMBERS \
 Ref<NiFloatData > unknownLink; \
@@ -975,18 +998,14 @@ vector<Ref<NiNode > > meshes; \
 unsigned int unknownInt; \
 
 #define NI_P_SYS_PLANAR_COLLIDER_MEMBERS \
-float bounce; \
-bool spawnOnCollide; \
-bool dieOnCollide; \
-Ref<NiPSysSpawnModifier > spawnModifier; \
-NiObject * parent; \
-Ref<NiObject > unknownLink_; \
-Ref<NiNode > colliderObject; \
 float width; \
 float height; \
 Vector3 xAxis; \
 Vector3 yAxis; \
 
+#define NI_P_SYS_SPHERICAL_COLLIDER_MEMBERS \
+float radius; \
+
 #define NI_P_SYS_POSITION_MODIFIER_MEMBERS \
 
 #define NI_P_SYS_RESET_ON_LOOP_CTLR_MEMBERS \
@@ -1045,7 +1064,7 @@ Vector3 translation; \
 float scale; \
 mutable unsigned int numBones; \
 Ref<NiSkinPartition > skinPartition; \
-byte unknownByte; \
+byte hasVertexWeights; \
 vector<SkinData > boneList; \
 
 #define NI_SKIN_INSTANCE_MEMBERS \
@@ -1055,6 +1074,12 @@ NiNode * skeletonRoot; \
 mutable unsigned int numBones; \
 vector<NiNode * > bones; \
 
+#define NI_TRI_SHAPE_SKIN_CONTROLLER_MEMBERS \
+mutable unsigned int numBones; \
+mutable vector<unsigned int > vertexCounts; \
+vector<NiBone * > bones; \
+vector< vector<OldSkinData > > boneData; \
+
 #define NI_CLOD_SKIN_INSTANCE_MEMBERS \
 
 #define NI_SKIN_PARTITION_MEMBERS \
@@ -1138,27 +1163,26 @@ unsigned int operation; \
 Ref<NiFloatData > data; \
 
 #define NI_TEXTURE_MODE_PROPERTY_MEMBERS \
-array<3,short > unknown3Shorts; \
+short unknownShort; \
+array<2,short > unknown2Shorts; \
 
 #define NI_IMAGE_MEMBERS \
-byte external_; \
-string file; \
-array<4,short > unknown4Shorts; \
+byte external; \
+string fileName; \
+Ref<NiRawImageData > imageData; \
+unsigned int unknownInt1; \
+unsigned int unknownInt2; \
 
 #define NI_TEXTURE_PROPERTY_MEMBERS \
 unsigned short flags; \
 Ref<NiImage > image; \
+unsigned int unknownInt1; \
+unsigned int unknownInt2; \
 
 #define NI_MULTI_TEXTURE_PROPERTY_MEMBERS \
 unsigned short flags; \
-unsigned int unknownInt1; \
-unsigned int unknownInt2; \
-Ref<NiImage > image; \
-unsigned int unknownInt3; \
-unsigned int unknownInt4; \
-unsigned int unknownInt5; \
-array<11,short > unknownShorts; \
-array<11,short > unknownExtraShorts; \
+unsigned int unknownInt; \
+array<5,MultiTextureElement > textureElements; \
 
 #define NI_TEXTURING_PROPERTY_MEMBERS \
 unsigned short flags; \
@@ -1271,238 +1295,10 @@ CompareMode function; \
 #define NI_RAW_IMAGE_DATA_MEMBERS \
 mutable unsigned int width; \
 mutable unsigned int height; \
-unsigned int unknownInt; \
-vector< vector<ByteColor3 > > imageData; \
-
-#else
-#define NI_OBJECT_MEMBERS
-#define A_KEYED_DATA_MEMBERS
-#define A_PARTICLE_MODIFIER_MEMBERS
-#define BHK_REF_OBJECT_MEMBERS
-#define BHK_SERIALIZABLE_MEMBERS
-#define ABHK_CONSTRAINT_MEMBERS
-#define ABHK_RAGDOLL_CONSTRAINT_MEMBERS
-#define BHK_SHAPE_MEMBERS
-#define ABHK_SHAPE_COLLECTION_MEMBERS
-#define BHK_SPHERE_REP_SHAPE_MEMBERS
-#define BHK_CONVEX_SHAPE_MEMBERS
-#define BHK_WORLD_OBJECT_MEMBERS
-#define BHK_ENTITY_MEMBERS
-#define NI_COLLISION_OBJECT_MEMBERS
-#define NI_EXTRA_DATA_MEMBERS
-#define NI_INTERPOLATOR_MEMBERS
-#define NI_BLEND_INTERPOLATOR_MEMBERS
-#define NI_B_SPLINE_INTERPOLATOR_MEMBERS
-#define NI_OBJECT_N_E_T_MEMBERS
-#define NI_A_V_OBJECT_MEMBERS
-#define NI_DYNAMIC_EFFECT_MEMBERS
-#define NI_LIGHT_MEMBERS
-#define NI_PROPERTY_MEMBERS
-#define NI_P_SYS_MODIFIER_MEMBERS
-#define NI_P_SYS_EMITTER_MEMBERS
-#define NI_P_SYS_VOLUME_EMITTER_MEMBERS
-#define NI_TIME_CONTROLLER_MEMBERS
-#define A_BONE_L_O_D_CONTROLLER_MEMBERS
-#define NI_SINGLE_INTERPOLATOR_CONTROLLER_MEMBERS
-#define A_P_SYS_CTLR_MEMBERS
-#define NI_GEOMETRY_MEMBERS
-#define NI_TRI_BASED_GEOM_MEMBERS
-#define NI_GEOMETRY_DATA_MEMBERS
-#define NI_TRI_BASED_GEOM_DATA_MEMBERS
-#define A_P_SYS_DATA_MEMBERS
-#define BHK_BLEND_COLLISION_OBJECT_MEMBERS
-#define BHK_BLEND_CONTROLLER_MEMBERS
-#define BHK_BOX_SHAPE_MEMBERS
-#define BHK_CAPSULE_SHAPE_MEMBERS
-#define BHK_COLLISION_OBJECT_MEMBERS
-#define BHK_CONVEX_VERTICES_SHAPE_MEMBERS
-#define BHK_HINGE_CONSTRAINT_MEMBERS
-#define BHK_LIMITED_HINGE_CONSTRAINT_MEMBERS
-#define BHK_LIST_SHAPE_MEMBERS
-#define BHK_MALLEABLE_CONSTRAINT_MEMBERS
-#define BHK_MOPP_BV_TREE_SHAPE_MEMBERS
-#define BHK_MULTI_SPHERE_SHAPE_MEMBERS
-#define BHK_NI_TRI_STRIPS_SHAPE_MEMBERS
-#define BHK_MESH_SHAPE_MEMBERS
-#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_MEMBERS
-#define BHK_PRISMATIC_CONSTRAINT_MEMBERS
-#define BHK_RAGDOLL_CONSTRAINT_MEMBERS
-#define BHK_RIGID_BODY_MEMBERS
-#define BHK_RIGID_BODY_T_MEMBERS
-#define BHK_SIMPLE_SHAPE_PHANTOM_MEMBERS
-#define BHK_S_P_COLLISION_OBJECT_MEMBERS
-#define BHK_SPHERE_SHAPE_MEMBERS
-#define BHK_STIFF_SPRING_CONSTRAINT_MEMBERS
-#define BHK_TRANSFORM_SHAPE_MEMBERS
-#define BHK_CONVEX_TRANSFORM_SHAPE_MEMBERS
-#define B_S_BOUND_MEMBERS
-#define B_S_FURNITURE_MARKER_MEMBERS
-#define B_S_PARENT_VELOCITY_MODIFIER_MEMBERS
-#define B_S_P_SYS_ARRAY_EMITTER_MEMBERS
-#define B_S_X_FLAGS_MEMBERS
-#define HK_PACKED_NI_TRI_STRIPS_DATA_MEMBERS
-#define NI_ALPHA_CONTROLLER_MEMBERS
-#define NI_ALPHA_PROPERTY_MEMBERS
-#define NI_AMBIENT_LIGHT_MEMBERS
-#define NI_AUTO_NORMAL_PARTICLES_DATA_MEMBERS
-#define NI_BINARY_EXTRA_DATA_MEMBERS
-#define NI_BLEND_BOOL_INTERPOLATOR_MEMBERS
-#define NI_BLEND_FLOAT_INTERPOLATOR_MEMBERS
-#define NI_BLEND_POINT3_INTERPOLATOR_MEMBERS
-#define NI_BLEND_TRANSFORM_INTERPOLATOR_MEMBERS
-#define NI_BONE_L_O_D_CONTROLLER_MEMBERS
-#define NI_BOOL_DATA_MEMBERS
-#define NI_BOOLEAN_EXTRA_DATA_MEMBERS
-#define NI_BOOL_INTERPOLATOR_MEMBERS
-#define NI_BOOL_TIMELINE_INTERPOLATOR_MEMBERS
-#define NI_B_S_BONE_L_O_D_CONTROLLER_MEMBERS
-#define NI_B_SPLINE_BASIS_DATA_MEMBERS
-#define NI_B_SPLINE_COMP_FLOAT_INTERPOLATOR_MEMBERS
-#define NI_B_SPLINE_COMP_POINT3_INTERPOLATOR_MEMBERS
-#define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_MEMBERS
-#define NI_B_SPLINE_DATA_MEMBERS
-#define NI_CAMERA_MEMBERS
-#define NI_COLLISION_DATA_MEMBERS
-#define NI_COLOR_DATA_MEMBERS
-#define NI_COLOR_EXTRA_DATA_MEMBERS
-#define NI_CONTROLLER_MANAGER_MEMBERS
-#define NI_SEQUENCE_MEMBERS
-#define NI_CONTROLLER_SEQUENCE_MEMBERS
-#define NI_DEFAULT_A_V_OBJECT_PALETTE_MEMBERS
-#define NI_DIRECTIONAL_LIGHT_MEMBERS
-#define NI_DITHER_PROPERTY_MEMBERS
-#define NI_FLIP_CONTROLLER_MEMBERS
-#define NI_ROLL_CONTROLLER_MEMBERS
-#define NI_FLOAT_DATA_MEMBERS
-#define NI_FLOAT_EXTRA_DATA_MEMBERS
-#define NI_FLOAT_EXTRA_DATA_CONTROLLER_MEMBERS
-#define NI_FLOAT_INTERPOLATOR_MEMBERS
-#define NI_FLOATS_EXTRA_DATA_MEMBERS
-#define NI_FOG_PROPERTY_MEMBERS
-#define NI_GEOM_MORPHER_CONTROLLER_MEMBERS
-#define NI_GRAVITY_MEMBERS
-#define NI_INTEGER_EXTRA_DATA_MEMBERS
-#define NI_INTEGERS_EXTRA_DATA_MEMBERS
-#define NI_KEYFRAME_CONTROLLER_MEMBERS
-#define B_S_KEYFRAME_CONTROLLER_MEMBERS
-#define NI_KEYFRAME_DATA_MEMBERS
-#define NI_LIGHT_COLOR_CONTROLLER_MEMBERS
-#define NI_LIGHT_DIMMER_CONTROLLER_MEMBERS
-#define NI_LOOK_AT_CONTROLLER_MEMBERS
-#define NI_LOOK_AT_INTERPOLATOR_MEMBERS
-#define NI_MATERIAL_COLOR_CONTROLLER_MEMBERS
-#define NI_MATERIAL_PROPERTY_MEMBERS
-#define NI_MESH_P_SYS_DATA_MEMBERS
-#define NI_MORPH_DATA_MEMBERS
-#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_MEMBERS
-#define NI_NODE_MEMBERS
-#define AVOID_NODE_MEMBERS
-#define FX_WIDGET_MEMBERS
-#define FX_BUTTON_MEMBERS
-#define FX_RADIO_BUTTON_MEMBERS
-#define NI_BILLBOARD_NODE_MEMBERS
-#define NI_B_S_ANIMATION_NODE_MEMBERS
-#define NI_B_S_PARTICLE_NODE_MEMBERS
-#define NI_L_O_D_NODE_MEMBERS
-#define NI_PALETTE_MEMBERS
-#define NI_PARTICLE_BOMB_MEMBERS
-#define NI_PARTICLE_COLOR_MODIFIER_MEMBERS
-#define NI_PARTICLE_GROW_FADE_MEMBERS
-#define NI_PARTICLE_MESH_MODIFIER_MEMBERS
-#define NI_PARTICLE_ROTATION_MEMBERS
-#define NI_PARTICLES_MEMBERS
-#define NI_AUTO_NORMAL_PARTICLES_MEMBERS
-#define NI_PARTICLE_MESHES_MEMBERS
-#define NI_PARTICLES_DATA_MEMBERS
-#define NI_PARTICLE_MESHES_DATA_MEMBERS
-#define NI_PARTICLE_SYSTEM_MEMBERS
-#define NI_MESH_PARTICLE_SYSTEM_MEMBERS
-#define NI_PARTICLE_SYSTEM_CONTROLLER_MEMBERS
-#define NI_B_S_P_ARRAY_CONTROLLER_MEMBERS
-#define NI_PATH_CONTROLLER_MEMBERS
-#define NI_PATH_INTERPOLATOR_MEMBERS
-#define NI_PIXEL_DATA_MEMBERS
-#define NI_PLANAR_COLLIDER_MEMBERS
-#define NI_POINT3_INTERPOLATOR_MEMBERS
-#define NI_POINT_LIGHT_MEMBERS
-#define NI_POS_DATA_MEMBERS
-#define NI_P_SYS_AGE_DEATH_MODIFIER_MEMBERS
-#define NI_P_SYS_BOMB_MODIFIER_MEMBERS
-#define NI_P_SYS_BOUND_UPDATE_MODIFIER_MEMBERS
-#define NI_P_SYS_BOX_EMITTER_MEMBERS
-#define NI_P_SYS_COLLIDER_MANAGER_MEMBERS
-#define NI_P_SYS_COLOR_MODIFIER_MEMBERS
-#define NI_P_SYS_CYLINDER_EMITTER_MEMBERS
-#define NI_P_SYS_DATA_MEMBERS
-#define NI_P_SYS_DRAG_MODIFIER_MEMBERS
-#define NI_P_SYS_EMITTER_CTLR_MEMBERS
-#define NI_P_SYS_EMITTER_CTLR_DATA_MEMBERS
-#define NI_P_SYS_EMITTER_DECLINATION_CTLR_MEMBERS
-#define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_MEMBERS
-#define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_MEMBERS
-#define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_MEMBERS
-#define NI_P_SYS_EMITTER_SPEED_CTLR_MEMBERS
-#define NI_P_SYS_GRAVITY_MODIFIER_MEMBERS
-#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_MEMBERS
-#define NI_P_SYS_GROW_FADE_MODIFIER_MEMBERS
-#define NI_P_SYS_MESH_EMITTER_MEMBERS
-#define NI_P_SYS_MESH_UPDATE_MODIFIER_MEMBERS
-#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_MEMBERS
-#define NI_P_SYS_PLANAR_COLLIDER_MEMBERS
-#define NI_P_SYS_POSITION_MODIFIER_MEMBERS
-#define NI_P_SYS_RESET_ON_LOOP_CTLR_MEMBERS
-#define NI_P_SYS_ROTATION_MODIFIER_MEMBERS
-#define NI_P_SYS_SPAWN_MODIFIER_MEMBERS
-#define NI_P_SYS_SPHERE_EMITTER_MEMBERS
-#define NI_P_SYS_UPDATE_CTLR_MEMBERS
-#define NI_L_O_D_DATA_MEMBERS
-#define NI_RANGE_L_O_D_DATA_MEMBERS
-#define NI_SCREEN_L_O_D_DATA_MEMBERS
-#define NI_ROTATING_PARTICLES_MEMBERS
-#define NI_ROTATING_PARTICLES_DATA_MEMBERS
-#define NI_SEQUENCE_STREAM_HELPER_MEMBERS
-#define NI_SHADE_PROPERTY_MEMBERS
-#define NI_SKIN_DATA_MEMBERS
-#define NI_SKIN_INSTANCE_MEMBERS
-#define NI_CLOD_SKIN_INSTANCE_MEMBERS
-#define NI_SKIN_PARTITION_MEMBERS
-#define NI_SOURCE_TEXTURE_MEMBERS
-#define NI_SPECULAR_PROPERTY_MEMBERS
-#define NI_SPHERICAL_COLLIDER_MEMBERS
-#define NI_SPOT_LIGHT_MEMBERS
-#define NI_STENCIL_PROPERTY_MEMBERS
-#define NI_STRING_EXTRA_DATA_MEMBERS
-#define NI_STRING_PALETTE_MEMBERS
-#define NI_STRINGS_EXTRA_DATA_MEMBERS
-#define NI_TEXT_KEY_EXTRA_DATA_MEMBERS
-#define NI_TEXTURE_EFFECT_MEMBERS
-#define NI_TEXTURE_TRANSFORM_CONTROLLER_MEMBERS
-#define NI_TEXTURE_MODE_PROPERTY_MEMBERS
-#define NI_IMAGE_MEMBERS
-#define NI_TEXTURE_PROPERTY_MEMBERS
-#define NI_MULTI_TEXTURE_PROPERTY_MEMBERS
-#define NI_TEXTURING_PROPERTY_MEMBERS
-#define NI_TRANSFORM_CONTROLLER_MEMBERS
-#define NI_TRANSFORM_DATA_MEMBERS
-#define NI_TRANSFORM_INTERPOLATOR_MEMBERS
-#define NI_TRI_SHAPE_MEMBERS
-#define NI_TRI_SHAPE_DATA_MEMBERS
-#define NI_TRI_STRIPS_MEMBERS
-#define NI_TRI_STRIPS_DATA_MEMBERS
-#define NI_CLOD_MEMBERS
-#define NI_CLOD_DATA_MEMBERS
-#define NI_U_V_CONTROLLER_MEMBERS
-#define NI_U_V_DATA_MEMBERS
-#define NI_VECTOR_EXTRA_DATA_MEMBERS
-#define NI_VERTEX_COLOR_PROPERTY_MEMBERS
-#define NI_VERT_WEIGHTS_EXTRA_DATA_MEMBERS
-#define NI_VIS_CONTROLLER_MEMBERS
-#define NI_VIS_DATA_MEMBERS
-#define NI_WIREFRAME_PROPERTY_MEMBERS
-#define NI_Z_BUFFER_PROPERTY_MEMBERS
-#define ROOT_COLLISION_NODE_MEMBERS
-#define NI_RAW_IMAGE_DATA_MEMBERS
-#endif
+unsigned int imageType; \
+vector< vector<ByteColor3 > > rgbImageData; \
+vector< vector<ByteColor4 > > rgbaImageData; \
+
 
 #define NI_OBJECT_PARENT
 
@@ -1514,6 +1310,10 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define A_PARTICLE_MODIFIER_CONSTRUCT  : nextModifier(NULL), controller(NULL)
 
+#define NI_P_SYS_COLLIDER_PARENT NiObject
+
+#define NI_P_SYS_COLLIDER_CONSTRUCT  : bounce(0.0f), spawnOnCollide(false), dieOnCollide(false), spawnModifier(NULL), parent(NULL), nextCollider(NULL), colliderObject(NULL)
+
 #define BHK_REF_OBJECT_PARENT NiObject
 
 #define BHK_REF_OBJECT_CONSTRUCT 
@@ -1575,7 +1375,7 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define NI_DYNAMIC_EFFECT_PARENT NiAVObject
 
-#define NI_DYNAMIC_EFFECT_CONSTRUCT  : switchState(false), numAffectedNodes((unsigned int)0)
+#define NI_DYNAMIC_EFFECT_CONSTRUCT  : switchState(false), numAffectedNodeListPointers((unsigned int)0), numAffectedNodes((unsigned int)0)
 
 #define NI_LIGHT_PARENT NiDynamicEffect
 
@@ -1679,10 +1479,6 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define BHK_NI_TRI_STRIPS_SHAPE_CONSTRUCT  : unknownFloat1(0.1f), unknownInt1((unsigned int)0x004ABE60), unknownInt2((unsigned int)1), scale(1.0f, 1.0f, 1.0f), unknownInt3((unsigned int)0), numStripsData((unsigned int)0), numDataLayers((unsigned int)0)
 
-#define BHK_MESH_SHAPE_PARENT bhkSphereRepShape
-
-#define BHK_MESH_SHAPE_CONSTRUCT  : unknownCount((int)0), numStripsData((unsigned int)0)
-
 #define BHK_PACKED_NI_TRI_STRIPS_SHAPE_PARENT AbhkShapeCollection
 
 #define BHK_PACKED_NI_TRI_STRIPS_SHAPE_CONSTRUCT  : numSubShapes((unsigned short)0), scale(1.0f), data(NULL)
@@ -1762,6 +1558,14 @@ vector< vector<ByteColor3 > > imageData; \
 #define NI_BINARY_EXTRA_DATA_PARENT NiExtraData
 
 #define NI_BINARY_EXTRA_DATA_CONSTRUCT 
+#define NI_BINARY_VOXEL_EXTRA_DATA_PARENT NiExtraData
+
+#define NI_BINARY_VOXEL_EXTRA_DATA_CONSTRUCT  : unknownInt((unsigned int)0), data(NULL)
+
+#define NI_BINARY_VOXEL_DATA_PARENT NiObject
+
+#define NI_BINARY_VOXEL_DATA_CONSTRUCT  : unknownShort1((unsigned short)0), unknownShort2((unsigned short)0), unknownShort3((unsigned short)0), numUnknownVectors((unsigned int)0), numUnknownBytes2((unsigned int)0)
+
 #define NI_BLEND_BOOL_INTERPOLATOR_PARENT NiBlendInterpolator
 
 #define NI_BLEND_BOOL_INTERPOLATOR_CONSTRUCT  : boolValue((byte)0)
@@ -1952,6 +1756,9 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define NI_NODE_CONSTRUCT  : numChildren((unsigned int)0), numEffects((unsigned int)0)
 
+#define NI_BONE_PARENT NiNode
+
+#define NI_BONE_CONSTRUCT 
 #define AVOID_NODE_PARENT NiNode
 
 #define AVOID_NODE_CONSTRUCT 
@@ -2107,13 +1914,15 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define NI_P_SYS_EMITTER_DECLINATION_CTLR_PARENT APSysCtlr
 
-#define NI_P_SYS_EMITTER_DECLINATION_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_DECLINATION_CTLR_CONSTRUCT  : data(NULL)
+
 #define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_PARENT APSysCtlr
 
 #define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_CONSTRUCT 
 #define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_PARENT APSysCtlr
 
-#define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_CONSTRUCT  : data(NULL)
+
 #define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_PARENT APSysCtlr
 
 #define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_CONSTRUCT  : unknownLink(NULL)
@@ -2146,9 +1955,13 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define NI_P_SYS_MODIFIER_ACTIVE_CTLR_CONSTRUCT  : unknownInt((unsigned int)0)
 
-#define NI_P_SYS_PLANAR_COLLIDER_PARENT NiObject
+#define NI_P_SYS_PLANAR_COLLIDER_PARENT NiPSysCollider
 
-#define NI_P_SYS_PLANAR_COLLIDER_CONSTRUCT  : bounce(0.0f), spawnOnCollide(false), dieOnCollide(false), spawnModifier(NULL), parent(NULL), unknownLink_(NULL), colliderObject(NULL), width(0.0f), height(0.0f)
+#define NI_P_SYS_PLANAR_COLLIDER_CONSTRUCT  : width(0.0f), height(0.0f)
+
+#define NI_P_SYS_SPHERICAL_COLLIDER_PARENT NiPSysCollider
+
+#define NI_P_SYS_SPHERICAL_COLLIDER_CONSTRUCT  : radius(0.0f)
 
 #define NI_P_SYS_POSITION_MODIFIER_PARENT NiPSysModifier
 
@@ -2197,12 +2010,16 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define NI_SKIN_DATA_PARENT NiObject
 
-#define NI_SKIN_DATA_CONSTRUCT  : scale(0.0f), numBones((unsigned int)0), skinPartition(NULL), unknownByte((byte)1)
+#define NI_SKIN_DATA_CONSTRUCT  : scale(0.0f), numBones((unsigned int)0), skinPartition(NULL), hasVertexWeights((byte)1)
 
 #define NI_SKIN_INSTANCE_PARENT NiObject
 
 #define NI_SKIN_INSTANCE_CONSTRUCT  : data(NULL), skinPartition(NULL), skeletonRoot(NULL), numBones((unsigned int)0)
 
+#define NI_TRI_SHAPE_SKIN_CONTROLLER_PARENT NiTimeController
+
+#define NI_TRI_SHAPE_SKIN_CONTROLLER_CONSTRUCT  : numBones((unsigned int)0)
+
 #define NI_CLOD_SKIN_INSTANCE_PARENT NiSkinInstance
 
 #define NI_CLOD_SKIN_INSTANCE_CONSTRUCT 
@@ -2255,18 +2072,19 @@ vector< vector<ByteColor3 > > imageData; \
 
 #define NI_TEXTURE_MODE_PROPERTY_PARENT NiProperty
 
-#define NI_TEXTURE_MODE_PROPERTY_CONSTRUCT 
+#define NI_TEXTURE_MODE_PROPERTY_CONSTRUCT  : unknownShort((short)0)
+
 #define NI_IMAGE_PARENT NiObject
 
-#define NI_IMAGE_CONSTRUCT  : external_((byte)0)
+#define NI_IMAGE_CONSTRUCT  : external((byte)0), imageData(NULL), unknownInt1((unsigned int)7), unknownInt2((unsigned int)0x43008000)
 
 #define NI_TEXTURE_PROPERTY_PARENT NiProperty
 
-#define NI_TEXTURE_PROPERTY_CONSTRUCT  : flags((unsigned short)0), image(NULL)
+#define NI_TEXTURE_PROPERTY_CONSTRUCT  : flags((unsigned short)0), image(NULL), unknownInt1((unsigned int)0), unknownInt2((unsigned int)0)
 
 #define NI_MULTI_TEXTURE_PROPERTY_PARENT NiProperty
 
-#define NI_MULTI_TEXTURE_PROPERTY_CONSTRUCT  : flags((unsigned short)0), unknownInt1((unsigned int)5), unknownInt2((unsigned int)0), image(NULL), unknownInt3((unsigned int)0), unknownInt4((unsigned int)0), unknownInt5((unsigned int)0)
+#define NI_MULTI_TEXTURE_PROPERTY_CONSTRUCT  : flags((unsigned short)0), unknownInt((unsigned int)0)
 
 #define NI_TEXTURING_PROPERTY_PARENT NiProperty
 
@@ -2343,4 +2161,6 @@ vector< vector<ByteColor3 > > imageData; \
 #define ROOT_COLLISION_NODE_CONSTRUCT 
 #define NI_RAW_IMAGE_DATA_PARENT NiObject
 
-#define NI_RAW_IMAGE_DATA_CONSTRUCT  : width((unsigned int)0), height((unsigned int)0), unknownInt((unsigned int)0)
\ No newline at end of file
+#define NI_RAW_IMAGE_DATA_CONSTRUCT  : width((unsigned int)0), height((unsigned int)0), imageType((unsigned int)0)
+
+#endif
diff --git a/include/nif_versions.h b/include/nif_versions.h
index 83996aa4dd512d698daf3a24e13a25bbe75fc9e5..62be344474db999413b307365d3031762bb8d219 100644
--- a/include/nif_versions.h
+++ b/include/nif_versions.h
@@ -8,6 +8,8 @@ All rights reserved.  Please see niflib.h for license. */
 
 namespace Niflib {
 
+const unsigned VER_3_0         = 0x03000000; /*!< NIF Version 3.0 */
+const unsigned VER_3_03        = 0x03000300; /*!< NIF Version 3.03 */
 const unsigned VER_3_1         = 0x03010000; /*!< NIF Version 3.1 */
 const unsigned VER_3_3_0_13    = 0x0303000D; /*!< NIF Version 3.3.0.13 */
 const unsigned VER_4_0_0_0     = 0x04000000; /*!< NIF Version 4.0.0.0 */
diff --git a/include/obj/NiBinaryVoxelData.h b/include/obj/NiBinaryVoxelData.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e5f5ef4f6f5f1dcf2d91c30a75c7f276dcaa1e5
--- /dev/null
+++ b/include/obj/NiBinaryVoxelData.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIBINARYVOXELDATA_H_
+#define _NIBINARYVOXELDATA_H_
+
+#include "NiObject.h"
+namespace Niflib {
+
+class NiBinaryVoxelData;
+typedef Ref<NiBinaryVoxelData> NiBinaryVoxelDataRef;
+
+/*!
+ * NiBinaryVoxelData - Voxel data object.
+ */
+
+class NiBinaryVoxelData : public NI_BINARY_VOXEL_DATA_PARENT {
+public:
+	NIFLIB_API NiBinaryVoxelData();
+	NIFLIB_API ~NiBinaryVoxelData();
+	//Run-Time Type Information
+	NIFLIB_API static const Type TYPE;
+	NIFLIB_API static NiObject * Create();
+	NIFLIB_API virtual const Type & GetType() const;
+	NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual void Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	NIFLIB_API virtual string asString( bool verbose = false ) const;
+	NIFLIB_HIDDEN virtual void FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
+
+protected:
+	NI_BINARY_VOXEL_DATA_MEMBERS
+private:
+	void InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	void InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/include/obj/NiBinaryVoxelExtraData.h b/include/obj/NiBinaryVoxelExtraData.h
new file mode 100644
index 0000000000000000000000000000000000000000..37db33670d8eda7e40cc47f769c260f35dcb5cd2
--- /dev/null
+++ b/include/obj/NiBinaryVoxelExtraData.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIBINARYVOXELEXTRADATA_H_
+#define _NIBINARYVOXELEXTRADATA_H_
+
+#include "NiExtraData.h"
+
+// Include structures
+#include "../Ref.h"
+namespace Niflib {
+
+// Forward define of referenced NIF objects
+class NiBinaryVoxelData;
+class NiBinaryVoxelExtraData;
+typedef Ref<NiBinaryVoxelExtraData> NiBinaryVoxelExtraDataRef;
+
+/*!
+ * NiBinaryVoxelExtraData - Voxel extra data object.
+ */
+
+class NiBinaryVoxelExtraData : public NI_BINARY_VOXEL_EXTRA_DATA_PARENT {
+public:
+	NIFLIB_API NiBinaryVoxelExtraData();
+	NIFLIB_API ~NiBinaryVoxelExtraData();
+	//Run-Time Type Information
+	NIFLIB_API static const Type TYPE;
+	NIFLIB_API static NiObject * Create();
+	NIFLIB_API virtual const Type & GetType() const;
+	NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual void Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	NIFLIB_API virtual string asString( bool verbose = false ) const;
+	NIFLIB_HIDDEN virtual void FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
+
+protected:
+	NI_BINARY_VOXEL_EXTRA_DATA_MEMBERS
+private:
+	void InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	void InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/include/obj/NiBone.h b/include/obj/NiBone.h
new file mode 100644
index 0000000000000000000000000000000000000000..df7b6757df995589aa3e37d3fc1a87c827d8f777
--- /dev/null
+++ b/include/obj/NiBone.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIBONE_H_
+#define _NIBONE_H_
+
+#include "NiNode.h"
+namespace Niflib {
+
+class NiBone;
+typedef Ref<NiBone> NiBoneRef;
+
+/*!
+ * NiBone - A NiNode used as a skeleton bone?
+ */
+
+class NiBone : public NI_BONE_PARENT {
+public:
+	NIFLIB_API NiBone();
+	NIFLIB_API ~NiBone();
+	//Run-Time Type Information
+	NIFLIB_API static const Type TYPE;
+	NIFLIB_API static NiObject * Create();
+	NIFLIB_API virtual const Type & GetType() const;
+	NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual void Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	NIFLIB_API virtual string asString( bool verbose = false ) const;
+	NIFLIB_HIDDEN virtual void FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
+
+protected:
+	NI_BONE_MEMBERS
+private:
+	void InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	void InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/include/obj/NiImage.h b/include/obj/NiImage.h
index 56529544c4d59da6b4a493164ab47596ccd10f41..2d9af1826a96837c013108ac00d8f8b3e39896c7 100644
--- a/include/obj/NiImage.h
+++ b/include/obj/NiImage.h
@@ -11,6 +11,7 @@ namespace Niflib {
 //#include "../gen/obj_defines.h"
 
 class NiImage;
+class NiRawImageData;
 typedef Ref<NiImage> NiImageRef;
 
 /*!
diff --git a/include/obj/NiMultiTextureProperty.h b/include/obj/NiMultiTextureProperty.h
index 5994521618ebb5b916f2aacdc1ae6619c1e8dc6f..1c944b1c88e265bd4150c024fb19d85a89f9898f 100644
--- a/include/obj/NiMultiTextureProperty.h
+++ b/include/obj/NiMultiTextureProperty.h
@@ -8,6 +8,7 @@ All rights reserved.  Please see niflib.h for license. */
 
 // Include structures
 #include "../Ref.h"
+#include "../gen/MultiTextureElement.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
diff --git a/include/obj/bhkMeshShape.h b/include/obj/NiPSysCollider.h
similarity index 77%
rename from include/obj/bhkMeshShape.h
rename to include/obj/NiPSysCollider.h
index e12041d2c03f3ac3a811211b29ae0c658bf51ac4..47a0f47225a5f477f4bee1e860f2e54cd9e94be6 100644
--- a/include/obj/bhkMeshShape.h
+++ b/include/obj/NiPSysCollider.h
@@ -1,28 +1,30 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _BHKMESHSHAPE_H_
-#define _BHKMESHSHAPE_H_
+#ifndef _NIPSYSCOLLIDER_H_
+#define _NIPSYSCOLLIDER_H_
 
-#include "bhkSphereRepShape.h"
+#include "NiObject.h"
 
 // Include structures
 #include "../Ref.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
-class NiTriStripsData;
-class bhkMeshShape;
-typedef Ref<bhkMeshShape> bhkMeshShapeRef;
+class NiPSysSpawnModifier;
+class NiObject;
+class NiNode;
+class NiPSysCollider;
+typedef Ref<NiPSysCollider> NiPSysColliderRef;
 
 /*!
- * bhkMeshShape -
+ * NiPSysCollider - Particle system collider.
  */
 
-class bhkMeshShape : public BHK_MESH_SHAPE_PARENT {
+class NiPSysCollider : public NI_P_SYS_COLLIDER_PARENT {
 public:
-	NIFLIB_API bhkMeshShape();
-	NIFLIB_API ~bhkMeshShape();
+	NIFLIB_API NiPSysCollider();
+	NIFLIB_API ~NiPSysCollider();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -34,7 +36,7 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 protected:
-	BHK_MESH_SHAPE_MEMBERS
+	NI_P_SYS_COLLIDER_MEMBERS
 private:
 	void InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
 	void InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
diff --git a/include/obj/NiPSysEmitterDeclinationCtlr.h b/include/obj/NiPSysEmitterDeclinationCtlr.h
index 698aab7b92eb752f3a4de19513295509c92cbdaa..108ddd45e676258c6039be76131524ff071d43e2 100644
--- a/include/obj/NiPSysEmitterDeclinationCtlr.h
+++ b/include/obj/NiPSysEmitterDeclinationCtlr.h
@@ -11,6 +11,7 @@ namespace Niflib {
 //#include "../gen/obj_defines.h"
 
 class NiPSysEmitterDeclinationCtlr;
+class NiFloatData;
 typedef Ref<NiPSysEmitterDeclinationCtlr> NiPSysEmitterDeclinationCtlrRef;
 
 /*!
diff --git a/include/obj/NiPSysEmitterInitialRadiusCtlr.h b/include/obj/NiPSysEmitterInitialRadiusCtlr.h
index 0a200736591fb6d8cf33d53bb89dc40ec36570f5..d731f0a6661a0fdb06386bcb9360b6026415ef5e 100644
--- a/include/obj/NiPSysEmitterInitialRadiusCtlr.h
+++ b/include/obj/NiPSysEmitterInitialRadiusCtlr.h
@@ -11,6 +11,7 @@ namespace Niflib {
 //#include "../gen/obj_defines.h"
 
 class NiPSysEmitterInitialRadiusCtlr;
+class NiFloatData;
 typedef Ref<NiPSysEmitterInitialRadiusCtlr> NiPSysEmitterInitialRadiusCtlrRef;
 
 /*!
diff --git a/include/obj/NiPSysPlanarCollider.h b/include/obj/NiPSysPlanarCollider.h
index ddefa4f8521c6cce9b26cb50d3d27a6b5dfe0de3..46d10c715fa55975bfcad9d76f01adaea834fadf 100644
--- a/include/obj/NiPSysPlanarCollider.h
+++ b/include/obj/NiPSysPlanarCollider.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSPLANARCOLLIDER_H_
 #define _NIPSYSPLANARCOLLIDER_H_
 
-#include "NiObject.h"
+#include "NiPSysCollider.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiPSysSphericalCollider.h b/include/obj/NiPSysSphericalCollider.h
new file mode 100644
index 0000000000000000000000000000000000000000..9cd4c6f1aea9505c72877b850068248931a45152
--- /dev/null
+++ b/include/obj/NiPSysSphericalCollider.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIPSYSSPHERICALCOLLIDER_H_
+#define _NIPSYSSPHERICALCOLLIDER_H_
+
+#include "NiPSysCollider.h"
+namespace Niflib {
+
+class NiPSysSphericalCollider;
+typedef Ref<NiPSysSphericalCollider> NiPSysSphericalColliderRef;
+
+/*!
+ * NiPSysSphericalCollider - Unknown.
+ */
+
+class NiPSysSphericalCollider : public NI_P_SYS_SPHERICAL_COLLIDER_PARENT {
+public:
+	NIFLIB_API NiPSysSphericalCollider();
+	NIFLIB_API ~NiPSysSphericalCollider();
+	//Run-Time Type Information
+	NIFLIB_API static const Type TYPE;
+	NIFLIB_API static NiObject * Create();
+	NIFLIB_API virtual const Type & GetType() const;
+	NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual void Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	NIFLIB_API virtual string asString( bool verbose = false ) const;
+	NIFLIB_HIDDEN virtual void FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
+
+protected:
+	NI_P_SYS_SPHERICAL_COLLIDER_MEMBERS
+private:
+	void InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	void InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/include/obj/NiRawImageData.h b/include/obj/NiRawImageData.h
index 6fc05760ff37f771427acb83afcbb3ae0a0d5707..e599206eef1a8268cf1cc999faeca4a088c36cda 100644
--- a/include/obj/NiRawImageData.h
+++ b/include/obj/NiRawImageData.h
@@ -8,6 +8,7 @@ All rights reserved.  Please see niflib.h for license. */
 
 // Include structures
 #include "../gen/ByteColor3.h"
+#include "../gen/ByteColor4.h"
 namespace Niflib {
 
 class NiRawImageData;
diff --git a/include/obj/NiTriShapeSkinController.h b/include/obj/NiTriShapeSkinController.h
new file mode 100644
index 0000000000000000000000000000000000000000..d11d7adf3b5c913353a0751e94a634ea0dbc338b
--- /dev/null
+++ b/include/obj/NiTriShapeSkinController.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NITRISHAPESKINCONTROLLER_H_
+#define _NITRISHAPESKINCONTROLLER_H_
+
+#include "NiTimeController.h"
+
+// Include structures
+#include "../gen/OldSkinData.h"
+namespace Niflib {
+
+// Forward define of referenced NIF objects
+class NiBone;
+class NiTriShapeSkinController;
+typedef Ref<NiTriShapeSkinController> NiTriShapeSkinControllerRef;
+
+/*!
+ * NiTriShapeSkinController - Old version of skinning instance.
+ */
+
+class NiTriShapeSkinController : public NI_TRI_SHAPE_SKIN_CONTROLLER_PARENT {
+public:
+	NIFLIB_API NiTriShapeSkinController();
+	NIFLIB_API ~NiTriShapeSkinController();
+	//Run-Time Type Information
+	NIFLIB_API static const Type TYPE;
+	NIFLIB_API static NiObject * Create();
+	NIFLIB_API virtual const Type & GetType() const;
+	NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual void Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	NIFLIB_API virtual string asString( bool verbose = false ) const;
+	NIFLIB_HIDDEN virtual void FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
+
+protected:
+	NI_TRI_SHAPE_SKIN_CONTROLLER_MEMBERS
+private:
+	void InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info );
+	void InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const;
+	string InternalAsString( bool verbose ) const;
+	void InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info );
+	list<NiObjectRef> InternalGetRefs() const;
+};
+
+}
+#endif
diff --git a/niflib.vcproj b/niflib.vcproj
index 1e8f3033330498b07d683e34b79932cb348b58a7..d0911c9b85d9fdcbe2c07b11bd2177ac476bca9e 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -434,10 +434,6 @@
 					RelativePath=".\src\obj\bhkMalleableConstraint.cpp"
 					>
 				</File>
-				<File
-					RelativePath=".\src\obj\bhkMeshShape.cpp"
-					>
-				</File>
 				<File
 					RelativePath=".\src\obj\bhkMoppBvTreeShape.cpp"
 					>
@@ -582,6 +578,14 @@
 					RelativePath=".\src\obj\NiBinaryExtraData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiBinaryVoxelData.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\NiBinaryVoxelExtraData.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiBlendBoolInterpolator.cpp"
 					>
@@ -602,6 +606,10 @@
 					RelativePath=".\src\obj\NiBlendTransformInterpolator.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiBone.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiBoneLODController.cpp"
 					>
@@ -954,6 +962,10 @@
 					RelativePath=".\src\obj\NiPSysBoxEmitter.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiPSysCollider.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiPSysColliderManager.cpp"
 					>
@@ -1058,6 +1070,10 @@
 					RelativePath=".\src\obj\NiPSysSphereEmitter.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiPSysSphericalCollider.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiPSysUpdateCtlr.cpp"
 					>
@@ -1206,6 +1222,10 @@
 					RelativePath=".\src\obj\NiTriShapeData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiTriShapeSkinController.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiTriStrips.cpp"
 					>
@@ -1274,6 +1294,10 @@
 					RelativePath=".\src\gen\ByteColor3.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\gen\ByteColor4.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\gen\ControllerLink.cpp"
 					>
@@ -1318,6 +1342,10 @@
 					RelativePath=".\src\gen\Morph.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\gen\MultiTextureElement.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\gen\NodeGroup.cpp"
 					>
@@ -1334,6 +1362,10 @@
 					RelativePath=".\src\gen\OblivionSubShape.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\gen\OldSkinData.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\gen\Particle.cpp"
 					>
@@ -1564,10 +1596,6 @@
 					RelativePath=".\include\obj\bhkMalleableConstraint.h"
 					>
 				</File>
-				<File
-					RelativePath=".\include\obj\bhkMeshShape.h"
-					>
-				</File>
 				<File
 					RelativePath=".\include\obj\bhkMoppBvTreeShape.h"
 					>
@@ -1712,6 +1740,14 @@
 					RelativePath=".\include\obj\NiBinaryExtraData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiBinaryVoxelData.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\NiBinaryVoxelExtraData.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiBlendBoolInterpolator.h"
 					>
@@ -1732,6 +1768,10 @@
 					RelativePath=".\include\obj\NiBlendTransformInterpolator.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiBone.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiBoneLODController.h"
 					>
@@ -2084,6 +2124,10 @@
 					RelativePath=".\include\obj\NiPSysBoxEmitter.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiPSysCollider.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiPSysColliderManager.h"
 					>
@@ -2188,6 +2232,10 @@
 					RelativePath=".\include\obj\NiPSysSphereEmitter.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiPSysSphericalCollider.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiPSysUpdateCtlr.h"
 					>
@@ -2336,6 +2384,10 @@
 					RelativePath=".\include\obj\NiTriShapeData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiTriShapeSkinController.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiTriStrips.h"
 					>
@@ -2404,6 +2456,10 @@
 					RelativePath=".\include\gen\ByteColor3.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\gen\ByteColor4.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\gen\ControllerLink.h"
 					>
@@ -2456,6 +2512,10 @@
 					RelativePath=".\include\gen\Morph.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\gen\MultiTextureElement.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\gen\NodeGroup.h"
 					>
@@ -2472,6 +2532,10 @@
 					RelativePath=".\include\gen\OblivionSubShape.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\gen\OldSkinData.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\gen\Particle.h"
 					>
diff --git a/src/gen/ByteColor4.cpp b/src/gen/ByteColor4.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63a32cbfbe2a01ddb852cd5d7de5f7e0b18cdae4
--- /dev/null
+++ b/src/gen/ByteColor4.cpp
@@ -0,0 +1,29 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+//---THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT---//
+
+//To change this file, alter the niftools/docsys/nifxml_niflib.py Python script.
+
+#include "../../include/gen/ByteColor4.h"
+using namespace Niflib;
+
+//Constructor
+ByteColor4::ByteColor4() : r((byte)0), g((byte)0), b((byte)0), a((byte)0) {};
+
+//Copy Constructor
+ByteColor4::ByteColor4( const ByteColor4 & src ) {
+	*this = src;
+};
+
+//Copy Operator
+ByteColor4 & ByteColor4::operator=( const ByteColor4 & src ) {
+	this->r = src.r;
+	this->g = src.g;
+	this->b = src.b;
+	this->a = src.a;
+	return *this;
+};
+
+//Destructor
+ByteColor4::~ByteColor4() {};
diff --git a/src/gen/MultiTextureElement.cpp b/src/gen/MultiTextureElement.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..810f2a0591c43513644e9e828295dd0b70392f47
--- /dev/null
+++ b/src/gen/MultiTextureElement.cpp
@@ -0,0 +1,34 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+//---THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT---//
+
+//To change this file, alter the niftools/docsys/nifxml_niflib.py Python script.
+
+#include "../../include/gen/MultiTextureElement.h"
+#include "../../include/obj/NiImage.h"
+using namespace Niflib;
+
+//Constructor
+MultiTextureElement::MultiTextureElement() : hasImage(false), image(NULL), unknownInt1((unsigned int)3), unknownInt2((unsigned int)2), unknownInt3((unsigned int)1), unknownShort1((short)0), unknownShort2((short)-75), unknownShort3((short)0) {};
+
+//Copy Constructor
+MultiTextureElement::MultiTextureElement( const MultiTextureElement & src ) {
+	*this = src;
+};
+
+//Copy Operator
+MultiTextureElement & MultiTextureElement::operator=( const MultiTextureElement & src ) {
+	this->hasImage = src.hasImage;
+	this->image = src.image;
+	this->unknownInt1 = src.unknownInt1;
+	this->unknownInt2 = src.unknownInt2;
+	this->unknownInt3 = src.unknownInt3;
+	this->unknownShort1 = src.unknownShort1;
+	this->unknownShort2 = src.unknownShort2;
+	this->unknownShort3 = src.unknownShort3;
+	return *this;
+};
+
+//Destructor
+MultiTextureElement::~MultiTextureElement() {};
diff --git a/src/gen/OldSkinData.cpp b/src/gen/OldSkinData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0817f243473e104da49048a72b9c746a5a745f4f
--- /dev/null
+++ b/src/gen/OldSkinData.cpp
@@ -0,0 +1,28 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+//---THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT---//
+
+//To change this file, alter the niftools/docsys/nifxml_niflib.py Python script.
+
+#include "../../include/gen/OldSkinData.h"
+using namespace Niflib;
+
+//Constructor
+OldSkinData::OldSkinData() : vertexWeight(0.0f), vertexIndex((unsigned short)0) {};
+
+//Copy Constructor
+OldSkinData::OldSkinData( const OldSkinData & src ) {
+	*this = src;
+};
+
+//Copy Operator
+OldSkinData & OldSkinData::operator=( const OldSkinData & src ) {
+	this->vertexWeight = src.vertexWeight;
+	this->vertexIndex = src.vertexIndex;
+	this->unknownVector = src.unknownVector;
+	return *this;
+};
+
+//Destructor
+OldSkinData::~OldSkinData() {};
diff --git a/src/gen/SkinData.cpp b/src/gen/SkinData.cpp
index 02b2893518a4770eb6b3f11f62c0f1057d50a1d4..fdc0fd8cc578712caded0f4df1b01d9fa11c7729 100644
--- a/src/gen/SkinData.cpp
+++ b/src/gen/SkinData.cpp
@@ -7,6 +7,7 @@ All rights reserved.  Please see niflib.h for license. */
 
 #include "../../include/gen/SkinData.h"
 #include "../../include/gen/SkinWeight.h"
+#include "../../include/gen/SkinWeight.h"
 using namespace Niflib;
 
 //Constructor
diff --git a/src/gen/obj_impl.cpp b/src/gen/obj_impl.cpp
index e880b2dcdbce25d9fbc63ace8590e47898339b88..b4d89b590873474169811c9e9bb68f32048957de 100644
--- a/src/gen/obj_impl.cpp
+++ b/src/gen/obj_impl.cpp
@@ -22,7 +22,6 @@ using namespace std;
 #include "../../include/obj/bhkMoppBvTreeShape.h"
 #include "../../include/obj/bhkMultiSphereShape.h"
 #include "../../include/obj/bhkNiTriStripsShape.h"
-#include "../../include/obj/bhkMeshShape.h"
 #include "../../include/obj/bhkPackedNiTriStripsShape.h"
 #include "../../include/obj/bhkPrismaticConstraint.h"
 #include "../../include/obj/bhkRagdollConstraint.h"
@@ -45,6 +44,8 @@ using namespace std;
 #include "../../include/obj/NiAmbientLight.h"
 #include "../../include/obj/NiAutoNormalParticlesData.h"
 #include "../../include/obj/NiBinaryExtraData.h"
+#include "../../include/obj/NiBinaryVoxelExtraData.h"
+#include "../../include/obj/NiBinaryVoxelData.h"
 #include "../../include/obj/NiBlendBoolInterpolator.h"
 #include "../../include/obj/NiBlendFloatInterpolator.h"
 #include "../../include/obj/NiBlendPoint3Interpolator.h"
@@ -95,6 +96,7 @@ using namespace std;
 #include "../../include/obj/NiMorphData.h"
 #include "../../include/obj/NiMultiTargetTransformController.h"
 #include "../../include/obj/NiNode.h"
+#include "../../include/obj/NiBone.h"
 #include "../../include/obj/AvoidNode.h"
 #include "../../include/obj/FxWidget.h"
 #include "../../include/obj/FxButton.h"
@@ -148,6 +150,7 @@ using namespace std;
 #include "../../include/obj/NiPSysMeshUpdateModifier.h"
 #include "../../include/obj/NiPSysModifierActiveCtlr.h"
 #include "../../include/obj/NiPSysPlanarCollider.h"
+#include "../../include/obj/NiPSysSphericalCollider.h"
 #include "../../include/obj/NiPSysPositionModifier.h"
 #include "../../include/obj/NiPSysResetOnLoopCtlr.h"
 #include "../../include/obj/NiPSysRotationModifier.h"
@@ -162,6 +165,7 @@ using namespace std;
 #include "../../include/obj/NiShadeProperty.h"
 #include "../../include/obj/NiSkinData.h"
 #include "../../include/obj/NiSkinInstance.h"
+#include "../../include/obj/NiTriShapeSkinController.h"
 #include "../../include/obj/NiClodSkinInstance.h"
 #include "../../include/obj/NiSkinPartition.h"
 #include "../../include/obj/NiSourceTexture.h"
@@ -214,19 +218,23 @@ Ref<T> FixLink( const map<unsigned,NiObjectRef> & objects, list<unsigned int> &
 	link_stack.pop_front();
 
 	//Check if link is NULL
-	if ( info.version >= VER_3_3_0_13) {
-		if ( index == 0xFFFFFFFF) {
-			return NULL;
-		}
+	if ( info.version > VER_3_3_0_13) {
+	    if ( index == 0xFFFFFFFF) {
+		    return NULL;
+	    }
 	} else {
-		if ( index == 0 ) {
-			return NULL;
-		}
+	    if ( index == 0 ) {
+		return NULL;
+	    }
 	}
 
 	map<unsigned int,NiObjectRef>::const_iterator it = objects.find(index);
 	if ( it == objects.end() ) {
-		throw runtime_error(FIX_LINK_INDEX_ERROR);
+		if ( info.version > VER_3_3_0_13 ) {
+			throw runtime_error(FIX_LINK_INDEX_ERROR);
+		} else {
+			return NULL;
+		}
 	}
 		
 	Ref<T> object = DynamicCast<T>(it->second);
@@ -336,6 +344,79 @@ std::list<NiObjectRef> AParticleModifier::InternalGetRefs() const {
 	return refs;
 }
 
+void NiPSysCollider::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiObject::Read( in, link_stack, info );
+	NifStream( bounce, in, info );
+	NifStream( spawnOnCollide, in, info );
+	NifStream( dieOnCollide, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiPSysCollider::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+	NifStream( bounce, out, info );
+	NifStream( spawnOnCollide, out, info );
+	NifStream( dieOnCollide, out, info );
+	if ( spawnModifier != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(spawnModifier) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( parent != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( nextCollider != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(nextCollider) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( colliderObject != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(colliderObject) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiPSysCollider::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiObject::asString();
+	out << "  Bounce:  " << bounce << endl;
+	out << "  Spawn on Collide:  " << spawnOnCollide << endl;
+	out << "  Die on Collide:  " << dieOnCollide << endl;
+	out << "  Spawn Modifier:  " << spawnModifier << endl;
+	out << "  Parent:  " << parent << endl;
+	out << "  Next Collider:  " << nextCollider << endl;
+	out << "  Collider Object:  " << colliderObject << endl;
+	return out.str();
+}
+
+void NiPSysCollider::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+	spawnModifier = FixLink<NiPSysSpawnModifier>( objects, link_stack, info );
+	parent = FixLink<NiObject>( objects, link_stack, info );
+	nextCollider = FixLink<NiObject>( objects, link_stack, info );
+	colliderObject = FixLink<NiNode>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiPSysCollider::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	if ( spawnModifier != NULL )
+		refs.push_back(StaticCast<NiObject>(spawnModifier));
+	if ( nextCollider != NULL )
+		refs.push_back(StaticCast<NiObject>(nextCollider));
+	if ( colliderObject != NULL )
+		refs.push_back(StaticCast<NiObject>(colliderObject));
+	return refs;
+}
+
 void bhkRefObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiObject::Read( in, link_stack, info );
 }
@@ -1126,13 +1207,13 @@ void NiDynamicEffect::InternalRead( istream& in, list<unsigned int> & link_stack
 		NifStream( switchState, in, info );
 	};
 	if ( info.version <= 0x04000002 ) {
-		NifStream( numAffectedNodes, in, info );
+		NifStream( numAffectedNodeListPointers, in, info );
 	};
 	if ( info.version >= 0x0A010000 ) {
 		NifStream( numAffectedNodes, in, info );
 	};
 	if ( info.version <= 0x04000002 ) {
-		affectedNodeListPointers.resize(numAffectedNodes);
+		affectedNodeListPointers.resize(numAffectedNodeListPointers);
 		for (unsigned int i2 = 0; i2 < affectedNodeListPointers.size(); i2++) {
 			NifStream( affectedNodeListPointers[i2], in, info );
 		};
@@ -1148,12 +1229,13 @@ void NiDynamicEffect::InternalRead( istream& in, list<unsigned int> & link_stack
 
 void NiDynamicEffect::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	NiAVObject::Write( out, link_map, info );
-	numAffectedNodes = (unsigned int)(affectedNodeListPointers.size());
+	numAffectedNodes = (unsigned int)(affectedNodes.size());
+	numAffectedNodeListPointers = (unsigned int)(affectedNodeListPointers.size());
 	if ( info.version >= 0x0A020000 ) {
 		NifStream( switchState, out, info );
 	};
 	if ( info.version <= 0x04000002 ) {
-		NifStream( numAffectedNodes, out, info );
+		NifStream( numAffectedNodeListPointers, out, info );
 	};
 	if ( info.version >= 0x0A010000 ) {
 		NifStream( numAffectedNodes, out, info );
@@ -1177,8 +1259,10 @@ std::string NiDynamicEffect::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << NiAVObject::asString();
-	numAffectedNodes = (unsigned int)(affectedNodeListPointers.size());
+	numAffectedNodes = (unsigned int)(affectedNodes.size());
+	numAffectedNodeListPointers = (unsigned int)(affectedNodeListPointers.size());
 	out << "  Switch State:  " << switchState << endl;
+	out << "  Num Affected Node List Pointers:  " << numAffectedNodeListPointers << endl;
 	out << "  Num Affected Nodes:  " << numAffectedNodes << endl;
 	array_output_count = 0;
 	for (unsigned int i1 = 0; i1 < affectedNodeListPointers.size(); i1++) {
@@ -3061,121 +3145,6 @@ std::list<NiObjectRef> bhkNiTriStripsShape::InternalGetRefs() const {
 	return refs;
 }
 
-void bhkMeshShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	bhkSphereRepShape::Read( in, link_stack, info );
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		NifStream( unknown[i1], in, info );
-	};
-	NifStream( unknownCount, in, info );
-	unknownFloats.resize(unknownCount);
-	for (unsigned int i1 = 0; i1 < unknownFloats.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < 3; i2++) {
-			NifStream( unknownFloats[i1][i2], in, info );
-		};
-	};
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknown[i1], in, info );
-	};
-	NifStream( numStripsData, in, info );
-	stripsData.resize(numStripsData);
-	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void bhkMeshShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkSphereRepShape::Write( out, link_map, info );
-	numStripsData = (unsigned int)(stripsData.size());
-	unknownCount = (int)(unknownFloats.size());
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		NifStream( unknown[i1], out, info );
-	};
-	NifStream( unknownCount, out, info );
-	for (unsigned int i1 = 0; i1 < unknownFloats.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < 3; i2++) {
-			NifStream( unknownFloats[i1][i2], out, info );
-		};
-	};
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknown[i1], out, info );
-	};
-	NifStream( numStripsData, out, info );
-	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
-		if ( stripsData[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(stripsData[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string bhkMeshShape::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << bhkSphereRepShape::asString();
-	numStripsData = (unsigned int)(stripsData.size());
-	unknownCount = (int)(unknownFloats.size());
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
-		};
-		out << "    unknown[" << i1 << "]:  " << unknown[i1] << endl;
-		array_output_count++;
-	};
-	out << "  unknown count:  " << unknownCount << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownFloats.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		for (unsigned int i2 = 0; i2 < 3; i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				break;
-			};
-			out << "      unknown floats[" << i2 << "]:  " << unknownFloats[i1][i2] << endl;
-			array_output_count++;
-		};
-	};
-	out << "  Num Strips Data:  " << numStripsData << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
-		};
-		out << "    Strips Data[" << i1 << "]:  " << stripsData[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void bhkMeshShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::FixLinks( objects, link_stack, info );
-	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
-		stripsData[i1] = FixLink<NiTriStripsData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> bhkMeshShape::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = bhkSphereRepShape::GetRefs();
-	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
-		if ( stripsData[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(stripsData[i1]));
-	};
-	return refs;
-}
-
 void bhkPackedNiTriStripsShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	AbhkShapeCollection::Read( in, link_stack, info );
@@ -4308,72 +4277,253 @@ std::list<NiObjectRef> NiBinaryExtraData::InternalGetRefs() const {
 	return refs;
 }
 
-void NiBlendBoolInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBlendInterpolator::Read( in, link_stack, info );
-	NifStream( boolValue, in, info );
+void NiBinaryVoxelExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiExtraData::Read( in, link_stack, info );
+	NifStream( unknownInt, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
 }
 
-void NiBlendBoolInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBlendInterpolator::Write( out, link_map, info );
-	NifStream( boolValue, out, info );
+void NiBinaryVoxelExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiExtraData::Write( out, link_map, info );
+	NifStream( unknownInt, out, info );
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
 }
 
-std::string NiBlendBoolInterpolator::InternalAsString( bool verbose ) const {
+std::string NiBinaryVoxelExtraData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiBlendInterpolator::asString();
-	out << "  Bool Value:  " << boolValue << endl;
+	out << NiExtraData::asString();
+	out << "  Unknown Int:  " << unknownInt << endl;
+	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
-void NiBlendBoolInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBlendInterpolator::FixLinks( objects, link_stack, info );
+void NiBinaryVoxelExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiExtraData::FixLinks( objects, link_stack, info );
+	data = FixLink<NiBinaryVoxelData>( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiBlendBoolInterpolator::InternalGetRefs() const {
+std::list<NiObjectRef> NiBinaryVoxelExtraData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiBlendInterpolator::GetRefs();
+	refs = NiExtraData::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
-void NiBlendFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBlendInterpolator::Read( in, link_stack, info );
-	NifStream( floatValue, in, info );
+void NiBinaryVoxelData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::Read( in, link_stack, info );
+	NifStream( unknownShort1, in, info );
+	NifStream( unknownShort2, in, info );
+	NifStream( unknownShort3, in, info );
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		NifStream( unknown7Floats[i1], in, info );
+	};
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		for (unsigned int i2 = 0; i2 < 12; i2++) {
+			NifStream( unknownBytes1[i1][i2], in, info );
+		};
+	};
+	NifStream( numUnknownVectors, in, info );
+	unknownVectors.resize(numUnknownVectors);
+	for (unsigned int i1 = 0; i1 < unknownVectors.size(); i1++) {
+		NifStream( unknownVectors[i1], in, info );
+	};
+	NifStream( numUnknownBytes2, in, info );
+	unknownBytes2.resize(numUnknownBytes2);
+	for (unsigned int i1 = 0; i1 < unknownBytes2.size(); i1++) {
+		NifStream( unknownBytes2[i1], in, info );
+	};
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		NifStream( unknown5Ints[i1], in, info );
+	};
 }
 
-void NiBlendFloatInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBlendInterpolator::Write( out, link_map, info );
-	NifStream( floatValue, out, info );
+void NiBinaryVoxelData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+	numUnknownBytes2 = (unsigned int)(unknownBytes2.size());
+	numUnknownVectors = (unsigned int)(unknownVectors.size());
+	NifStream( unknownShort1, out, info );
+	NifStream( unknownShort2, out, info );
+	NifStream( unknownShort3, out, info );
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		NifStream( unknown7Floats[i1], out, info );
+	};
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		for (unsigned int i2 = 0; i2 < 12; i2++) {
+			NifStream( unknownBytes1[i1][i2], out, info );
+		};
+	};
+	NifStream( numUnknownVectors, out, info );
+	for (unsigned int i1 = 0; i1 < unknownVectors.size(); i1++) {
+		NifStream( unknownVectors[i1], out, info );
+	};
+	NifStream( numUnknownBytes2, out, info );
+	for (unsigned int i1 = 0; i1 < unknownBytes2.size(); i1++) {
+		NifStream( unknownBytes2[i1], out, info );
+	};
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		NifStream( unknown5Ints[i1], out, info );
+	};
 }
 
-std::string NiBlendFloatInterpolator::InternalAsString( bool verbose ) const {
+std::string NiBinaryVoxelData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiBlendInterpolator::asString();
-	out << "  Float Value:  " << floatValue << endl;
-	return out.str();
-}
-
-void NiBlendFloatInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBlendInterpolator::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiBlendFloatInterpolator::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiBlendInterpolator::GetRefs();
-	return refs;
-}
-
-void NiBlendPoint3Interpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBlendInterpolator::Read( in, link_stack, info );
-	NifStream( pointValue, in, info );
-}
-
-void NiBlendPoint3Interpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBlendInterpolator::Write( out, link_map, info );
-	NifStream( pointValue, out, info );
-}
-
+	out << NiObject::asString();
+	numUnknownBytes2 = (unsigned int)(unknownBytes2.size());
+	numUnknownVectors = (unsigned int)(unknownVectors.size());
+	out << "  Unknown Short 1:  " << unknownShort1 << endl;
+	out << "  Unknown Short 2:  " << unknownShort2 << endl;
+	out << "  Unknown Short 3:  " << unknownShort3 << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Unknown 7 Floats[" << i1 << "]:  " << unknown7Floats[i1] << endl;
+		array_output_count++;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		for (unsigned int i2 = 0; i2 < 12; i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				break;
+			};
+			out << "      Unknown Bytes 1[" << i2 << "]:  " << unknownBytes1[i1][i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Num Unknown Vectors:  " << numUnknownVectors << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < unknownVectors.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Unknown Vectors[" << i1 << "]:  " << unknownVectors[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Num Unknown Bytes 2:  " << numUnknownBytes2 << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < unknownBytes2.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Unknown Bytes 2[" << i1 << "]:  " << unknownBytes2[i1] << endl;
+		array_output_count++;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Unknown 5 Ints[" << i1 << "]:  " << unknown5Ints[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void NiBinaryVoxelData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBinaryVoxelData::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	return refs;
+}
+
+void NiBlendBoolInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBlendInterpolator::Read( in, link_stack, info );
+	NifStream( boolValue, in, info );
+}
+
+void NiBlendBoolInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBlendInterpolator::Write( out, link_map, info );
+	NifStream( boolValue, out, info );
+}
+
+std::string NiBlendBoolInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiBlendInterpolator::asString();
+	out << "  Bool Value:  " << boolValue << endl;
+	return out.str();
+}
+
+void NiBlendBoolInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBlendInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBlendBoolInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiBlendInterpolator::GetRefs();
+	return refs;
+}
+
+void NiBlendFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBlendInterpolator::Read( in, link_stack, info );
+	NifStream( floatValue, in, info );
+}
+
+void NiBlendFloatInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBlendInterpolator::Write( out, link_map, info );
+	NifStream( floatValue, out, info );
+}
+
+std::string NiBlendFloatInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiBlendInterpolator::asString();
+	out << "  Float Value:  " << floatValue << endl;
+	return out.str();
+}
+
+void NiBlendFloatInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBlendInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBlendFloatInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiBlendInterpolator::GetRefs();
+	return refs;
+}
+
+void NiBlendPoint3Interpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBlendInterpolator::Read( in, link_stack, info );
+	NifStream( pointValue, in, info );
+}
+
+void NiBlendPoint3Interpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBlendInterpolator::Write( out, link_map, info );
+	NifStream( pointValue, out, info );
+}
+
 std::string NiBlendPoint3Interpolator::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
@@ -6033,21 +6183,21 @@ std::list<NiObjectRef> NiFloatExtraData::InternalGetRefs() const {
 void NiFloatExtraDataController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	NiTimeController::Read( in, link_stack, info );
-	if ( info.version >= 0x14000004 ) {
+	if ( info.version >= 0x0A020000 ) {
 		NifStream( block_num, in, info );
 		link_stack.push_back( block_num );
-		NifStream( unknownString, in, info );
+		NifStream( controllerData, in, info );
 	};
 }
 
 void NiFloatExtraDataController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	NiTimeController::Write( out, link_map, info );
-	if ( info.version >= 0x14000004 ) {
+	if ( info.version >= 0x0A020000 ) {
 		if ( unknownLink != NULL )
 			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
 		else
 			NifStream( 0xffffffff, out, info );
-		NifStream( unknownString, out, info );
+		NifStream( controllerData, out, info );
 	};
 }
 
@@ -6056,13 +6206,13 @@ std::string NiFloatExtraDataController::InternalAsString( bool verbose ) const {
 	unsigned int array_output_count = 0;
 	out << NiTimeController::asString();
 	out << "  Unknown Link:  " << unknownLink << endl;
-	out << "  Unknown String:  " << unknownString << endl;
+	out << "  Controller Data:  " << controllerData << endl;
 	return out.str();
 }
 
 void NiFloatExtraDataController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiTimeController::FixLinks( objects, link_stack, info );
-	if ( info.version >= 0x14000004 ) {
+	if ( info.version >= 0x0A020000 ) {
 		unknownLink = FixLink<NiObject>( objects, link_stack, info );
 	};
 }
@@ -7483,6 +7633,31 @@ std::list<NiObjectRef> NiNode::InternalGetRefs() const {
 	return refs;
 }
 
+void NiBone::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiNode::Read( in, link_stack, info );
+}
+
+void NiBone::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiNode::Write( out, link_map, info );
+}
+
+std::string NiBone::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiNode::asString();
+	return out.str();
+}
+
+void NiBone::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiNode::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBone::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiNode::GetRefs();
+	return refs;
+}
+
 void AvoidNode::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiNode::Read( in, link_stack, info );
 }
@@ -9866,27 +10041,44 @@ std::list<NiObjectRef> NiPSysEmitterCtlrData::InternalGetRefs() const {
 }
 
 void NiPSysEmitterDeclinationCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
 	APSysCtlr::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
 }
 
 void NiPSysEmitterDeclinationCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	APSysCtlr::Write( out, link_map, info );
+	if ( info.version <= 0x0A010000 ) {
+		if ( data != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
 }
 
 std::string NiPSysEmitterDeclinationCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << APSysCtlr::asString();
+	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
 void NiPSysEmitterDeclinationCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	APSysCtlr::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiFloatData>( objects, link_stack, info );
+	};
 }
 
 std::list<NiObjectRef> NiPSysEmitterDeclinationCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = APSysCtlr::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
@@ -9916,27 +10108,44 @@ std::list<NiObjectRef> NiPSysEmitterDeclinationVarCtlr::InternalGetRefs() const
 }
 
 void NiPSysEmitterInitialRadiusCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
 	APSysCtlr::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
 }
 
 void NiPSysEmitterInitialRadiusCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	APSysCtlr::Write( out, link_map, info );
+	if ( info.version <= 0x0A010000 ) {
+		if ( data != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
 }
 
 std::string NiPSysEmitterInitialRadiusCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << APSysCtlr::asString();
+	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
 void NiPSysEmitterInitialRadiusCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	APSysCtlr::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiFloatData>( objects, link_stack, info );
+	};
 }
 
 std::list<NiObjectRef> NiPSysEmitterInitialRadiusCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = APSysCtlr::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
@@ -10319,19 +10528,7 @@ std::list<NiObjectRef> NiPSysModifierActiveCtlr::InternalGetRefs() const {
 }
 
 void NiPSysPlanarCollider::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	NifStream( bounce, in, info );
-	NifStream( spawnOnCollide, in, info );
-	NifStream( dieOnCollide, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
+	NiPSysCollider::Read( in, link_stack, info );
 	NifStream( width, in, info );
 	NifStream( height, in, info );
 	NifStream( xAxis, in, info );
@@ -10339,26 +10536,7 @@ void NiPSysPlanarCollider::InternalRead( istream& in, list<unsigned int> & link_
 }
 
 void NiPSysPlanarCollider::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-	NifStream( bounce, out, info );
-	NifStream( spawnOnCollide, out, info );
-	NifStream( dieOnCollide, out, info );
-	if ( spawnModifier != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(spawnModifier) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( parent != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( unknownLink_ != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink_) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( colliderObject != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(colliderObject) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+	NiPSysCollider::Write( out, link_map, info );
 	NifStream( width, out, info );
 	NifStream( height, out, info );
 	NifStream( xAxis, out, info );
@@ -10368,14 +10546,7 @@ void NiPSysPlanarCollider::InternalWrite( ostream& out, const map<NiObjectRef,un
 std::string NiPSysPlanarCollider::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	out << "  Bounce:  " << bounce << endl;
-	out << "  Spawn on Collide:  " << spawnOnCollide << endl;
-	out << "  Die on Collide:  " << dieOnCollide << endl;
-	out << "  Spawn Modifier:  " << spawnModifier << endl;
-	out << "  Parent:  " << parent << endl;
-	out << "  Unknown Link?:  " << unknownLink_ << endl;
-	out << "  Collider Object:  " << colliderObject << endl;
+	out << NiPSysCollider::asString();
 	out << "  Width:  " << width << endl;
 	out << "  Height:  " << height << endl;
 	out << "  X Axis:  " << xAxis << endl;
@@ -10384,22 +10555,40 @@ std::string NiPSysPlanarCollider::InternalAsString( bool verbose ) const {
 }
 
 void NiPSysPlanarCollider::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	spawnModifier = FixLink<NiPSysSpawnModifier>( objects, link_stack, info );
-	parent = FixLink<NiObject>( objects, link_stack, info );
-	unknownLink_ = FixLink<NiObject>( objects, link_stack, info );
-	colliderObject = FixLink<NiNode>( objects, link_stack, info );
+	NiPSysCollider::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiPSysPlanarCollider::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	if ( spawnModifier != NULL )
-		refs.push_back(StaticCast<NiObject>(spawnModifier));
-	if ( unknownLink_ != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink_));
-	if ( colliderObject != NULL )
-		refs.push_back(StaticCast<NiObject>(colliderObject));
+	refs = NiPSysCollider::GetRefs();
+	return refs;
+}
+
+void NiPSysSphericalCollider::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysCollider::Read( in, link_stack, info );
+	NifStream( radius, in, info );
+}
+
+void NiPSysSphericalCollider::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysCollider::Write( out, link_map, info );
+	NifStream( radius, out, info );
+}
+
+std::string NiPSysSphericalCollider::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiPSysCollider::asString();
+	out << "  Radius:  " << radius << endl;
+	return out.str();
+}
+
+void NiPSysSphericalCollider::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysCollider::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiPSysSphericalCollider::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiPSysCollider::GetRefs();
 	return refs;
 }
 
@@ -10879,7 +11068,7 @@ void NiSkinData::InternalRead( istream& in, list<unsigned int> & link_stack, con
 		link_stack.push_back( block_num );
 	};
 	if ( info.version >= 0x04020100 ) {
-		NifStream( unknownByte, in, info );
+		NifStream( hasVertexWeights, in, info );
 	};
 	boneList.resize(numBones);
 	for (unsigned int i1 = 0; i1 < boneList.size(); i1++) {
@@ -10889,10 +11078,21 @@ void NiSkinData::InternalRead( istream& in, list<unsigned int> & link_stack, con
 		NifStream( boneList[i1].boundingSphereOffset, in, info );
 		NifStream( boneList[i1].boundingSphereRadius, in, info );
 		NifStream( boneList[i1].numVertices, in, info );
-		boneList[i1].vertexWeights.resize(boneList[i1].numVertices);
-		for (unsigned int i2 = 0; i2 < boneList[i1].vertexWeights.size(); i2++) {
-			NifStream( boneList[i1].vertexWeights[i2].index, in, info );
-			NifStream( boneList[i1].vertexWeights[i2].weight, in, info );
+		if ( info.version <= 0x04020100 ) {
+			boneList[i1].vertexWeights.resize(boneList[i1].numVertices);
+			for (unsigned int i3 = 0; i3 < boneList[i1].vertexWeights.size(); i3++) {
+				NifStream( boneList[i1].vertexWeights[i3].index, in, info );
+				NifStream( boneList[i1].vertexWeights[i3].weight, in, info );
+			};
+		};
+		if ( info.version >= 0x04020200 ) {
+			if ( (hasVertexWeights != 0) ) {
+				boneList[i1].vertexWeights.resize(boneList[i1].numVertices);
+				for (unsigned int i4 = 0; i4 < boneList[i1].vertexWeights.size(); i4++) {
+					NifStream( boneList[i1].vertexWeights[i4].index, in, info );
+					NifStream( boneList[i1].vertexWeights[i4].weight, in, info );
+				};
+			};
 		};
 	};
 }
@@ -10911,7 +11111,7 @@ void NiSkinData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int
 			NifStream( 0xffffffff, out, info );
 	};
 	if ( info.version >= 0x04020100 ) {
-		NifStream( unknownByte, out, info );
+		NifStream( hasVertexWeights, out, info );
 	};
 	for (unsigned int i1 = 0; i1 < boneList.size(); i1++) {
 		boneList[i1].numVertices = (unsigned short)(boneList[i1].vertexWeights.size());
@@ -10921,9 +11121,19 @@ void NiSkinData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int
 		NifStream( boneList[i1].boundingSphereOffset, out, info );
 		NifStream( boneList[i1].boundingSphereRadius, out, info );
 		NifStream( boneList[i1].numVertices, out, info );
-		for (unsigned int i2 = 0; i2 < boneList[i1].vertexWeights.size(); i2++) {
-			NifStream( boneList[i1].vertexWeights[i2].index, out, info );
-			NifStream( boneList[i1].vertexWeights[i2].weight, out, info );
+		if ( info.version <= 0x04020100 ) {
+			for (unsigned int i3 = 0; i3 < boneList[i1].vertexWeights.size(); i3++) {
+				NifStream( boneList[i1].vertexWeights[i3].index, out, info );
+				NifStream( boneList[i1].vertexWeights[i3].weight, out, info );
+			};
+		};
+		if ( info.version >= 0x04020200 ) {
+			if ( (hasVertexWeights != 0) ) {
+				for (unsigned int i4 = 0; i4 < boneList[i1].vertexWeights.size(); i4++) {
+					NifStream( boneList[i1].vertexWeights[i4].index, out, info );
+					NifStream( boneList[i1].vertexWeights[i4].weight, out, info );
+				};
+			};
 		};
 	};
 }
@@ -10938,7 +11148,7 @@ std::string NiSkinData::InternalAsString( bool verbose ) const {
 	out << "  Scale:  " << scale << endl;
 	out << "  Num Bones:  " << numBones << endl;
 	out << "  Skin Partition:  " << skinPartition << endl;
-	out << "  Unknown Byte:  " << unknownByte << endl;
+	out << "  Has Vertex Weights:  " << hasVertexWeights << endl;
 	array_output_count = 0;
 	for (unsigned int i1 = 0; i1 < boneList.size(); i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
@@ -11073,6 +11283,116 @@ std::list<NiObjectRef> NiSkinInstance::InternalGetRefs() const {
 	return refs;
 }
 
+void NiTriShapeSkinController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiTimeController::Read( in, link_stack, info );
+	NifStream( numBones, in, info );
+	vertexCounts.resize(numBones);
+	for (unsigned int i1 = 0; i1 < vertexCounts.size(); i1++) {
+		NifStream( vertexCounts[i1], in, info );
+	};
+	bones.resize(numBones);
+	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+	boneData.resize(numBones);
+	for (unsigned int i1 = 0; i1 < boneData.size(); i1++) {
+		boneData[i1].resize(vertexCounts[i1]);
+		for (unsigned int i2 = 0; i2 < vertexCounts[i1]; i2++) {
+			NifStream( boneData[i1][i2].vertexWeight, in, info );
+			NifStream( boneData[i1][i2].vertexIndex, in, info );
+			NifStream( boneData[i1][i2].unknownVector, in, info );
+		};
+	};
+}
+
+void NiTriShapeSkinController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiTimeController::Write( out, link_map, info );
+	for (unsigned int i1 = 0; i1 < boneData.size(); i1++)
+		vertexCounts[i1] = (unsigned int)(boneData[i1].size());
+	numBones = (unsigned int)(vertexCounts.size());
+	NifStream( numBones, out, info );
+	for (unsigned int i1 = 0; i1 < vertexCounts.size(); i1++) {
+		NifStream( vertexCounts[i1], out, info );
+	};
+	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
+		if ( bones[i1] != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(bones[i1]) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	for (unsigned int i1 = 0; i1 < boneData.size(); i1++) {
+		for (unsigned int i2 = 0; i2 < vertexCounts[i1]; i2++) {
+			NifStream( boneData[i1][i2].vertexWeight, out, info );
+			NifStream( boneData[i1][i2].vertexIndex, out, info );
+			NifStream( boneData[i1][i2].unknownVector, out, info );
+		};
+	};
+}
+
+std::string NiTriShapeSkinController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiTimeController::asString();
+	for (unsigned int i1 = 0; i1 < boneData.size(); i1++)
+		vertexCounts[i1] = (unsigned int)(boneData[i1].size());
+	numBones = (unsigned int)(vertexCounts.size());
+	out << "  Num Bones:  " << numBones << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < vertexCounts.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Vertex Counts[" << i1 << "]:  " << vertexCounts[i1] << endl;
+		array_output_count++;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
+		};
+		out << "    Bones[" << i1 << "]:  " << bones[i1] << endl;
+		array_output_count++;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < boneData.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		for (unsigned int i2 = 0; i2 < vertexCounts[i1]; i2++) {
+			out << "      Vertex Weight:  " << boneData[i1][i2].vertexWeight << endl;
+			out << "      Vertex Index:  " << boneData[i1][i2].vertexIndex << endl;
+			out << "      Unknown Vector:  " << boneData[i1][i2].unknownVector << endl;
+		};
+	};
+	return out.str();
+}
+
+void NiTriShapeSkinController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiTimeController::FixLinks( objects, link_stack, info );
+	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
+		bones[i1] = FixLink<NiBone>( objects, link_stack, info );
+	};
+}
+
+std::list<NiObjectRef> NiTriShapeSkinController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiTimeController::GetRefs();
+	for (unsigned int i1 = 0; i1 < bones.size(); i1++) {
+	};
+	return refs;
+}
+
 void NiClodSkinInstance::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiSkinInstance::Read( in, link_stack, info );
 }
@@ -12013,15 +12333,21 @@ std::list<NiObjectRef> NiTextureTransformController::InternalGetRefs() const {
 
 void NiTextureModeProperty::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiProperty::Read( in, link_stack, info );
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknown3Shorts[i1], in, info );
+	NifStream( unknownShort, in, info );
+	if ( info.version >= 0x03010000 ) {
+		for (unsigned int i2 = 0; i2 < 2; i2++) {
+			NifStream( unknown2Shorts[i2], in, info );
+		};
 	};
 }
 
 void NiTextureModeProperty::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	NiProperty::Write( out, link_map, info );
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknown3Shorts[i1], out, info );
+	NifStream( unknownShort, out, info );
+	if ( info.version >= 0x03010000 ) {
+		for (unsigned int i2 = 0; i2 < 2; i2++) {
+			NifStream( unknown2Shorts[i2], out, info );
+		};
 	};
 }
 
@@ -12029,8 +12355,9 @@ std::string NiTextureModeProperty::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << NiProperty::asString();
+	out << "  Unknown Short:  " << unknownShort << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
+	for (unsigned int i1 = 0; i1 < 2; i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 			break;
@@ -12038,7 +12365,7 @@ std::string NiTextureModeProperty::InternalAsString( bool verbose ) const {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			break;
 		};
-		out << "    Unknown 3 Shorts[" << i1 << "]:  " << unknown3Shorts[i1] << endl;
+		out << "    Unknown 2 Shorts[" << i1 << "]:  " << unknown2Shorts[i1] << endl;
 		array_output_count++;
 	};
 	return out.str();
@@ -12055,20 +12382,37 @@ std::list<NiObjectRef> NiTextureModeProperty::InternalGetRefs() const {
 }
 
 void NiImage::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
 	NiObject::Read( in, link_stack, info );
-	NifStream( external_, in, info );
-	NifStream( file, in, info );
-	for (unsigned int i1 = 0; i1 < 4; i1++) {
-		NifStream( unknown4Shorts[i1], in, info );
+	NifStream( external, in, info );
+	if ( (external != 0) ) {
+		NifStream( fileName, in, info );
+	};
+	if ( (external == 0) ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+	NifStream( unknownInt1, in, info );
+	if ( info.version >= 0x03010000 ) {
+		NifStream( unknownInt2, in, info );
 	};
 }
 
 void NiImage::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	NiObject::Write( out, link_map, info );
-	NifStream( external_, out, info );
-	NifStream( file, out, info );
-	for (unsigned int i1 = 0; i1 < 4; i1++) {
-		NifStream( unknown4Shorts[i1], out, info );
+	NifStream( external, out, info );
+	if ( (external != 0) ) {
+		NifStream( fileName, out, info );
+	};
+	if ( (external == 0) ) {
+		if ( imageData != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(imageData) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	NifStream( unknownInt1, out, info );
+	if ( info.version >= 0x03010000 ) {
+		NifStream( unknownInt2, out, info );
 	};
 }
 
@@ -12076,30 +12420,30 @@ std::string NiImage::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << NiObject::asString();
-	out << "  External ?:  " << external_ << endl;
-	out << "  File:  " << file << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 4; i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
-		};
-		out << "    Unknown 4 Shorts[" << i1 << "]:  " << unknown4Shorts[i1] << endl;
-		array_output_count++;
+	out << "  External:  " << external << endl;
+	if ( (external != 0) ) {
+		out << "    File Name:  " << fileName << endl;
 	};
+	if ( (external == 0) ) {
+		out << "    Image Data:  " << imageData << endl;
+	};
+	out << "  Unknown Int 1:  " << unknownInt1 << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
 	return out.str();
 }
 
 void NiImage::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiObject::FixLinks( objects, link_stack, info );
+	if ( (external == 0) ) {
+		imageData = FixLink<NiRawImageData>( objects, link_stack, info );
+	};
 }
 
 std::list<NiObjectRef> NiImage::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = NiObject::GetRefs();
+	if ( imageData != NULL )
+		refs.push_back(StaticCast<NiObject>(imageData));
 	return refs;
 }
 
@@ -12109,6 +12453,10 @@ void NiTextureProperty::InternalRead( istream& in, list<unsigned int> & link_sta
 	NifStream( flags, in, info );
 	NifStream( block_num, in, info );
 	link_stack.push_back( block_num );
+	if ( info.version <= 0x03000300 ) {
+		NifStream( unknownInt1, in, info );
+		NifStream( unknownInt2, in, info );
+	};
 }
 
 void NiTextureProperty::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
@@ -12118,6 +12466,10 @@ void NiTextureProperty::InternalWrite( ostream& out, const map<NiObjectRef,unsig
 		NifStream( link_map.find( StaticCast<NiObject>(image) )->second, out, info );
 	else
 		NifStream( 0xffffffff, out, info );
+	if ( info.version <= 0x03000300 ) {
+		NifStream( unknownInt1, out, info );
+		NifStream( unknownInt2, out, info );
+	};
 }
 
 std::string NiTextureProperty::InternalAsString( bool verbose ) const {
@@ -12126,6 +12478,8 @@ std::string NiTextureProperty::InternalAsString( bool verbose ) const {
 	out << NiProperty::asString();
 	out << "  Flags:  " << flags << endl;
 	out << "  Image:  " << image << endl;
+	out << "  Unknown Int 1:  " << unknownInt1 << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
 	return out.str();
 }
 
@@ -12146,19 +12500,18 @@ void NiMultiTextureProperty::InternalRead( istream& in, list<unsigned int> & lin
 	unsigned int block_num;
 	NiProperty::Read( in, link_stack, info );
 	NifStream( flags, in, info );
-	NifStream( unknownInt1, in, info );
-	NifStream( unknownInt2, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( unknownInt3, in, info );
-	NifStream( unknownInt4, in, info );
-	NifStream( unknownInt5, in, info );
-	for (unsigned int i1 = 0; i1 < 11; i1++) {
-		NifStream( unknownShorts[i1], in, info );
-	};
-	if ( (unknownInt5 == 0) ) {
-		for (unsigned int i2 = 0; i2 < 11; i2++) {
-			NifStream( unknownExtraShorts[i2], in, info );
+	NifStream( unknownInt, in, info );
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		NifStream( textureElements[i1].hasImage, in, info );
+		if ( textureElements[i1].hasImage ) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
+			NifStream( textureElements[i1].unknownInt1, in, info );
+			NifStream( textureElements[i1].unknownInt2, in, info );
+			NifStream( textureElements[i1].unknownInt3, in, info );
+			NifStream( textureElements[i1].unknownShort1, in, info );
+			NifStream( textureElements[i1].unknownShort2, in, info );
+			NifStream( textureElements[i1].unknownShort3, in, info );
 		};
 	};
 }
@@ -12166,21 +12519,20 @@ void NiMultiTextureProperty::InternalRead( istream& in, list<unsigned int> & lin
 void NiMultiTextureProperty::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	NiProperty::Write( out, link_map, info );
 	NifStream( flags, out, info );
-	NifStream( unknownInt1, out, info );
-	NifStream( unknownInt2, out, info );
-	if ( image != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(image) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( unknownInt3, out, info );
-	NifStream( unknownInt4, out, info );
-	NifStream( unknownInt5, out, info );
-	for (unsigned int i1 = 0; i1 < 11; i1++) {
-		NifStream( unknownShorts[i1], out, info );
-	};
-	if ( (unknownInt5 == 0) ) {
-		for (unsigned int i2 = 0; i2 < 11; i2++) {
-			NifStream( unknownExtraShorts[i2], out, info );
+	NifStream( unknownInt, out, info );
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		NifStream( textureElements[i1].hasImage, out, info );
+		if ( textureElements[i1].hasImage ) {
+			if ( textureElements[i1].image != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(textureElements[i1].image) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
+			NifStream( textureElements[i1].unknownInt1, out, info );
+			NifStream( textureElements[i1].unknownInt2, out, info );
+			NifStream( textureElements[i1].unknownInt3, out, info );
+			NifStream( textureElements[i1].unknownShort1, out, info );
+			NifStream( textureElements[i1].unknownShort2, out, info );
+			NifStream( textureElements[i1].unknownShort3, out, info );
 		};
 	};
 }
@@ -12190,36 +12542,22 @@ std::string NiMultiTextureProperty::InternalAsString( bool verbose ) const {
 	unsigned int array_output_count = 0;
 	out << NiProperty::asString();
 	out << "  Flags:  " << flags << endl;
-	out << "  Unknown Int 1:  " << unknownInt1 << endl;
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Image:  " << image << endl;
-	out << "  Unknown Int 3:  " << unknownInt3 << endl;
-	out << "  Unknown Int 4:  " << unknownInt4 << endl;
-	out << "  Unknown Int 5:  " << unknownInt5 << endl;
+	out << "  Unknown Int:  " << unknownInt << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 11; i1++) {
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 			break;
 		};
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
-		};
-		out << "    Unknown Shorts[" << i1 << "]:  " << unknownShorts[i1] << endl;
-		array_output_count++;
-	};
-	if ( (unknownInt5 == 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < 11; i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-				break;
-			};
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				break;
-			};
-			out << "      Unknown Extra Shorts[" << i2 << "]:  " << unknownExtraShorts[i2] << endl;
-			array_output_count++;
+		out << "    Has Image:  " << textureElements[i1].hasImage << endl;
+		if ( textureElements[i1].hasImage ) {
+			out << "      Image:  " << textureElements[i1].image << endl;
+			out << "      Unknown Int 1:  " << textureElements[i1].unknownInt1 << endl;
+			out << "      Unknown Int 2:  " << textureElements[i1].unknownInt2 << endl;
+			out << "      Unknown Int 3:  " << textureElements[i1].unknownInt3 << endl;
+			out << "      Unknown Short 1:  " << textureElements[i1].unknownShort1 << endl;
+			out << "      Unknown Short 2:  " << textureElements[i1].unknownShort2 << endl;
+			out << "      Unknown Short 3:  " << textureElements[i1].unknownShort3 << endl;
 		};
 	};
 	return out.str();
@@ -12227,14 +12565,20 @@ std::string NiMultiTextureProperty::InternalAsString( bool verbose ) const {
 
 void NiMultiTextureProperty::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiProperty::FixLinks( objects, link_stack, info );
-	image = FixLink<NiImage>( objects, link_stack, info );
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		if ( textureElements[i1].hasImage ) {
+			textureElements[i1].image = FixLink<NiImage>( objects, link_stack, info );
+		};
+	};
 }
 
 std::list<NiObjectRef> NiMultiTextureProperty::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = NiProperty::GetRefs();
-	if ( image != NULL )
-		refs.push_back(StaticCast<NiObject>(image));
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		if ( textureElements[i1].image != NULL )
+			refs.push_back(StaticCast<NiObject>(textureElements[i1].image));
+	};
 	return refs;
 }
 
@@ -13321,13 +13665,15 @@ void NiTriShapeData::InternalRead( istream& in, list<unsigned int> & link_stack,
 			};
 		};
 	};
-	NifStream( numMatchGroups, in, info );
-	matchGroups.resize(numMatchGroups);
-	for (unsigned int i1 = 0; i1 < matchGroups.size(); i1++) {
-		NifStream( matchGroups[i1].numVertices, in, info );
-		matchGroups[i1].vertexIndices.resize(matchGroups[i1].numVertices);
-		for (unsigned int i2 = 0; i2 < matchGroups[i1].vertexIndices.size(); i2++) {
-			NifStream( matchGroups[i1].vertexIndices[i2], in, info );
+	if ( info.version >= 0x03010000 ) {
+		NifStream( numMatchGroups, in, info );
+		matchGroups.resize(numMatchGroups);
+		for (unsigned int i2 = 0; i2 < matchGroups.size(); i2++) {
+			NifStream( matchGroups[i2].numVertices, in, info );
+			matchGroups[i2].vertexIndices.resize(matchGroups[i2].numVertices);
+			for (unsigned int i3 = 0; i3 < matchGroups[i2].vertexIndices.size(); i3++) {
+				NifStream( matchGroups[i2].vertexIndices[i3], in, info );
+			};
 		};
 	};
 }
@@ -13351,12 +13697,14 @@ void NiTriShapeData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned
 			};
 		};
 	};
-	NifStream( numMatchGroups, out, info );
-	for (unsigned int i1 = 0; i1 < matchGroups.size(); i1++) {
-		matchGroups[i1].numVertices = (unsigned short)(matchGroups[i1].vertexIndices.size());
-		NifStream( matchGroups[i1].numVertices, out, info );
-		for (unsigned int i2 = 0; i2 < matchGroups[i1].vertexIndices.size(); i2++) {
-			NifStream( matchGroups[i1].vertexIndices[i2], out, info );
+	if ( info.version >= 0x03010000 ) {
+		NifStream( numMatchGroups, out, info );
+		for (unsigned int i2 = 0; i2 < matchGroups.size(); i2++) {
+			matchGroups[i2].numVertices = (unsigned short)(matchGroups[i2].vertexIndices.size());
+			NifStream( matchGroups[i2].numVertices, out, info );
+			for (unsigned int i3 = 0; i3 < matchGroups[i2].vertexIndices.size(); i3++) {
+				NifStream( matchGroups[i2].vertexIndices[i3], out, info );
+			};
 		};
 	};
 }
@@ -14101,30 +14449,56 @@ void NiRawImageData::InternalRead( istream& in, list<unsigned int> & link_stack,
 	NiObject::Read( in, link_stack, info );
 	NifStream( width, in, info );
 	NifStream( height, in, info );
-	NifStream( unknownInt, in, info );
-	imageData.resize(width);
-	for (unsigned int i1 = 0; i1 < imageData.size(); i1++) {
-		imageData[i1].resize(height);
-		for (unsigned int i2 = 0; i2 < imageData[i1].size(); i2++) {
-			NifStream( imageData[i1][i2].r, in, info );
-			NifStream( imageData[i1][i2].g, in, info );
-			NifStream( imageData[i1][i2].b, in, info );
+	NifStream( imageType, in, info );
+	if ( (imageType == 1) ) {
+		rgbImageData.resize(width);
+		for (unsigned int i2 = 0; i2 < rgbImageData.size(); i2++) {
+			rgbImageData[i2].resize(height);
+			for (unsigned int i3 = 0; i3 < rgbImageData[i2].size(); i3++) {
+				NifStream( rgbImageData[i2][i3].r, in, info );
+				NifStream( rgbImageData[i2][i3].g, in, info );
+				NifStream( rgbImageData[i2][i3].b, in, info );
+			};
+		};
+	};
+	if ( (imageType == 2) ) {
+		rgbaImageData.resize(width);
+		for (unsigned int i2 = 0; i2 < rgbaImageData.size(); i2++) {
+			rgbaImageData[i2].resize(height);
+			for (unsigned int i3 = 0; i3 < rgbaImageData[i2].size(); i3++) {
+				NifStream( rgbaImageData[i2][i3].r, in, info );
+				NifStream( rgbaImageData[i2][i3].g, in, info );
+				NifStream( rgbaImageData[i2][i3].b, in, info );
+				NifStream( rgbaImageData[i2][i3].a, in, info );
+			};
 		};
 	};
 }
 
 void NiRawImageData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	NiObject::Write( out, link_map, info );
-	height = (unsigned int)((imageData.size() > 0) ? imageData[0].size() : 0);
-	width = (unsigned int)(imageData.size());
+	height = (unsigned int)((rgbImageData.size() > 0) ? rgbImageData[0].size() : 0);
+	width = (unsigned int)(rgbImageData.size());
 	NifStream( width, out, info );
 	NifStream( height, out, info );
-	NifStream( unknownInt, out, info );
-	for (unsigned int i1 = 0; i1 < imageData.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < imageData[i1].size(); i2++) {
-			NifStream( imageData[i1][i2].r, out, info );
-			NifStream( imageData[i1][i2].g, out, info );
-			NifStream( imageData[i1][i2].b, out, info );
+	NifStream( imageType, out, info );
+	if ( (imageType == 1) ) {
+		for (unsigned int i2 = 0; i2 < rgbImageData.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < rgbImageData[i2].size(); i3++) {
+				NifStream( rgbImageData[i2][i3].r, out, info );
+				NifStream( rgbImageData[i2][i3].g, out, info );
+				NifStream( rgbImageData[i2][i3].b, out, info );
+			};
+		};
+	};
+	if ( (imageType == 2) ) {
+		for (unsigned int i2 = 0; i2 < rgbaImageData.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < rgbaImageData[i2].size(); i3++) {
+				NifStream( rgbaImageData[i2][i3].r, out, info );
+				NifStream( rgbaImageData[i2][i3].g, out, info );
+				NifStream( rgbaImageData[i2][i3].b, out, info );
+				NifStream( rgbaImageData[i2][i3].a, out, info );
+			};
 		};
 	};
 }
@@ -14133,21 +14507,38 @@ std::string NiRawImageData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << NiObject::asString();
-	height = (unsigned int)((imageData.size() > 0) ? imageData[0].size() : 0);
-	width = (unsigned int)(imageData.size());
+	height = (unsigned int)((rgbImageData.size() > 0) ? rgbImageData[0].size() : 0);
+	width = (unsigned int)(rgbImageData.size());
 	out << "  Width:  " << width << endl;
 	out << "  Height:  " << height << endl;
-	out << "  Unknown Int:  " << unknownInt << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < imageData.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
+	out << "  Image Type:  " << imageType << endl;
+	if ( (imageType == 1) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < rgbImageData.size(); i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+				break;
+			};
+			for (unsigned int i3 = 0; i3 < rgbImageData[i2].size(); i3++) {
+				out << "        r:  " << rgbImageData[i2][i3].r << endl;
+				out << "        g:  " << rgbImageData[i2][i3].g << endl;
+				out << "        b:  " << rgbImageData[i2][i3].b << endl;
+			};
 		};
-		for (unsigned int i2 = 0; i2 < imageData[i1].size(); i2++) {
-			out << "      r:  " << imageData[i1][i2].r << endl;
-			out << "      g:  " << imageData[i1][i2].g << endl;
-			out << "      b:  " << imageData[i1][i2].b << endl;
+	};
+	if ( (imageType == 2) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < rgbaImageData.size(); i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+				break;
+			};
+			for (unsigned int i3 = 0; i3 < rgbaImageData[i2].size(); i3++) {
+				out << "        r:  " << rgbaImageData[i2][i3].r << endl;
+				out << "        g:  " << rgbaImageData[i2][i3].g << endl;
+				out << "        b:  " << rgbaImageData[i2][i3].b << endl;
+				out << "        a:  " << rgbaImageData[i2][i3].a << endl;
+			};
 		};
 	};
 	return out.str();
diff --git a/src/niflib.cpp b/src/niflib.cpp
index 74ed36d6aa2bb1870b156e2985a5dd7258a4feb2..bc17c2aae60564067e2d9a992fee5e17307a6c14 100644
--- a/src/niflib.cpp
+++ b/src/niflib.cpp
@@ -988,6 +988,8 @@ void MergeNifTrees( NiNode * target, NiSequenceStreamHelper * right, unsigned ve
 
 bool IsSupportedVersion( unsigned int version ) {
 	switch (version) {
+		case VER_3_0:
+		case VER_3_03:
 		case VER_3_1:
 		case VER_3_3_0_13:
 		case VER_4_0_0_0:
@@ -1017,9 +1019,16 @@ unsigned int ParseVersionString(string version) {
 		end = version.find_first_of( ".", start );
 		
 		if ( end == string::npos ) {
-			len = end;
+			if ( offset > 0 ) {
+				//This version has only one period in it.  Take the rest of the numbers one character at a time.
+				len = 1;
+			} else {
+				//We've already taken two characters one at a time, so take the rest all at once.
+				len = end;
+			}
 		} else {
 			len = end-start;
+			
 		}
 
 		int num = 0;
@@ -1032,7 +1041,12 @@ unsigned int ParseVersionString(string version) {
 		if ( len == string::npos ) {
 			break;
 		}
-		start = start + len + 1;
+
+		if ( end != string::npos ) {
+			//account for length of the period
+			start += 1;
+		}
+		start += len;
 	}
 
 	if ( outver == 0 ) {
@@ -1058,6 +1072,12 @@ string FormatVersionString(unsigned version) {
 	} else {
 		//Versions before 3.3.0.13 are in x.x format.
 		out << int_ver[0] << "." << int_ver[1];
+		if ( int_ver[2] ) {
+			out << int_ver[2];
+			if ( int_ver[3] ) {
+				out << int_ver[3];
+			}
+		}
 	}
 
 	return out.str();
diff --git a/src/obj/NiBinaryVoxelData.cpp b/src/obj/NiBinaryVoxelData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a9a073acb1f1fd66f0333587ed30432a2dd50b31
--- /dev/null
+++ b/src/obj/NiBinaryVoxelData.cpp
@@ -0,0 +1,61 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiBinaryVoxelData.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiBinaryVoxelData::TYPE("NiBinaryVoxelData", &NI_BINARY_VOXEL_DATA_PARENT::TYPE );
+
+NiBinaryVoxelData::NiBinaryVoxelData() NI_BINARY_VOXEL_DATA_CONSTRUCT {}
+
+NiBinaryVoxelData::~NiBinaryVoxelData() {}
+
+void NiBinaryVoxelData::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiBinaryVoxelData::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiBinaryVoxelData::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiBinaryVoxelData::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiBinaryVoxelData::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiBinaryVoxelData::GetType() const {
+	return TYPE;
+}
+
+namespace Niflib {
+	typedef NiObject*(*obj_factory_func)();
+	extern map<string, obj_factory_func> global_object_map;
+
+	//Initialization function
+	static bool Initialization();
+
+	//A static bool to force the initialization to happen pre-main
+	static bool obj_initialized = Initialization();
+
+	static bool Initialization() {
+		//Add the function to the global object map
+		global_object_map["NiBinaryVoxelData"] = NiBinaryVoxelData::Create;
+
+		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
+		obj_initialized = true;
+		return obj_initialized;
+	}
+}
+
+NiObject * NiBinaryVoxelData::Create() {
+	return new NiBinaryVoxelData;
+}
+
diff --git a/src/obj/NiBinaryVoxelExtraData.cpp b/src/obj/NiBinaryVoxelExtraData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ac687e36e4992ebf55abe2a2b8a9eae1e8691209
--- /dev/null
+++ b/src/obj/NiBinaryVoxelExtraData.cpp
@@ -0,0 +1,62 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiBinaryVoxelExtraData.h"
+#include "../../include/obj/NiBinaryVoxelData.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiBinaryVoxelExtraData::TYPE("NiBinaryVoxelExtraData", &NI_BINARY_VOXEL_EXTRA_DATA_PARENT::TYPE );
+
+NiBinaryVoxelExtraData::NiBinaryVoxelExtraData() NI_BINARY_VOXEL_EXTRA_DATA_CONSTRUCT {}
+
+NiBinaryVoxelExtraData::~NiBinaryVoxelExtraData() {}
+
+void NiBinaryVoxelExtraData::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiBinaryVoxelExtraData::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiBinaryVoxelExtraData::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiBinaryVoxelExtraData::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiBinaryVoxelExtraData::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiBinaryVoxelExtraData::GetType() const {
+	return TYPE;
+}
+
+namespace Niflib {
+	typedef NiObject*(*obj_factory_func)();
+	extern map<string, obj_factory_func> global_object_map;
+
+	//Initialization function
+	static bool Initialization();
+
+	//A static bool to force the initialization to happen pre-main
+	static bool obj_initialized = Initialization();
+
+	static bool Initialization() {
+		//Add the function to the global object map
+		global_object_map["NiBinaryVoxelExtraData"] = NiBinaryVoxelExtraData::Create;
+
+		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
+		obj_initialized = true;
+		return obj_initialized;
+	}
+}
+
+NiObject * NiBinaryVoxelExtraData::Create() {
+	return new NiBinaryVoxelExtraData;
+}
+
diff --git a/src/obj/bhkMeshShape.cpp b/src/obj/NiBone.cpp
similarity index 51%
rename from src/obj/bhkMeshShape.cpp
rename to src/obj/NiBone.cpp
index a2ef676e3d2f860640971602eec4fdb007862c68..af579c1893a299dbff65177ca57040527aad3a69 100644
--- a/src/obj/bhkMeshShape.cpp
+++ b/src/obj/NiBone.cpp
@@ -1,38 +1,37 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#include "../../include/obj/bhkMeshShape.h"
-#include "../../include/obj/NiTriStripsData.h"
+#include "../../include/obj/NiBone.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type bhkMeshShape::TYPE("bhkMeshShape", &BHK_MESH_SHAPE_PARENT::TYPE );
+const Type NiBone::TYPE("NiBone", &NI_BONE_PARENT::TYPE );
 
-bhkMeshShape::bhkMeshShape() BHK_MESH_SHAPE_CONSTRUCT {}
+NiBone::NiBone() NI_BONE_CONSTRUCT {}
 
-bhkMeshShape::~bhkMeshShape() {}
+NiBone::~NiBone() {}
 
-void bhkMeshShape::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiBone::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalRead( in, link_stack, info );
 }
 
-void bhkMeshShape::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void NiBone::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	InternalWrite( out, link_map, info );
 }
 
-string bhkMeshShape::asString( bool verbose ) const {
+string NiBone::asString( bool verbose ) const {
 	return InternalAsString( verbose );
 }
 
-void bhkMeshShape::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiBone::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalFixLinks( objects, link_stack, info );
 }
 
-list<NiObjectRef> bhkMeshShape::GetRefs() const {
+list<NiObjectRef> NiBone::GetRefs() const {
 	return InternalGetRefs();
 }
 
-const Type & bhkMeshShape::GetType() const {
+const Type & NiBone::GetType() const {
 	return TYPE;
 }
 
@@ -48,7 +47,7 @@ namespace Niflib {
 
 	static bool Initialization() {
 		//Add the function to the global object map
-		global_object_map["bhkMeshShape"] = bhkMeshShape::Create;
+		global_object_map["NiBone"] = NiBone::Create;
 
 		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
 		obj_initialized = true;
@@ -56,7 +55,7 @@ namespace Niflib {
 	}
 }
 
-NiObject * bhkMeshShape::Create() {
-	return new bhkMeshShape;
+NiObject * NiBone::Create() {
+	return new NiBone;
 }
 
diff --git a/src/obj/NiImage.cpp b/src/obj/NiImage.cpp
index 875ba02f98d75adc8d3a8419af39b2afaddfca5a..9554007531dbb7d843a673e342e9ba09a17fc3b1 100644
--- a/src/obj/NiImage.cpp
+++ b/src/obj/NiImage.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for license. */
 
 #include "../../include/obj/NiImage.h"
+#include "../../include/obj/NiRawImageData.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
@@ -60,9 +61,9 @@ NiObject * NiImage::Create() {
 }
 
 void NiImage::SetTextureFileName( string file_name ) {
-	file = file_name;
+	fileName = file_name;
 }
 
 string NiImage::GetTextureFileName() const {
-	return file;
+	return fileName;
 }
\ No newline at end of file
diff --git a/src/obj/NiPSysCollider.cpp b/src/obj/NiPSysCollider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..884d8958ca30c8b664d3f2de1c71ea491c4a87a8
--- /dev/null
+++ b/src/obj/NiPSysCollider.cpp
@@ -0,0 +1,64 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiPSysCollider.h"
+#include "../../include/obj/NiPSysSpawnModifier.h"
+#include "../../include/obj/NiObject.h"
+#include "../../include/obj/NiNode.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiPSysCollider::TYPE("NiPSysCollider", &NI_P_SYS_COLLIDER_PARENT::TYPE );
+
+NiPSysCollider::NiPSysCollider() NI_P_SYS_COLLIDER_CONSTRUCT {}
+
+NiPSysCollider::~NiPSysCollider() {}
+
+void NiPSysCollider::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiPSysCollider::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiPSysCollider::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiPSysCollider::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiPSysCollider::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiPSysCollider::GetType() const {
+	return TYPE;
+}
+
+namespace Niflib {
+	typedef NiObject*(*obj_factory_func)();
+	extern map<string, obj_factory_func> global_object_map;
+
+	//Initialization function
+	static bool Initialization();
+
+	//A static bool to force the initialization to happen pre-main
+	static bool obj_initialized = Initialization();
+
+	static bool Initialization() {
+		//Add the function to the global object map
+		global_object_map["NiPSysCollider"] = NiPSysCollider::Create;
+
+		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
+		obj_initialized = true;
+		return obj_initialized;
+	}
+}
+
+NiObject * NiPSysCollider::Create() {
+	return new NiPSysCollider;
+}
+
diff --git a/src/obj/NiPSysEmitterDeclinationCtlr.cpp b/src/obj/NiPSysEmitterDeclinationCtlr.cpp
index 59c0d2b7fa5005af424901c7a3bf911e7a386215..971045dfeac4e8a11aec050e46a0639f66c9fde4 100644
--- a/src/obj/NiPSysEmitterDeclinationCtlr.cpp
+++ b/src/obj/NiPSysEmitterDeclinationCtlr.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for license. */
 
 #include "../../include/obj/NiPSysEmitterDeclinationCtlr.h"
+#include "../../include/obj/NiFloatData.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
diff --git a/src/obj/NiPSysEmitterInitialRadiusCtlr.cpp b/src/obj/NiPSysEmitterInitialRadiusCtlr.cpp
index 5cdd6eca19b0851f551362ea57358011d8c5fdea..bf9d053194d94a9319d9fa207df0af86c41f96dc 100644
--- a/src/obj/NiPSysEmitterInitialRadiusCtlr.cpp
+++ b/src/obj/NiPSysEmitterInitialRadiusCtlr.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for license. */
 
 #include "../../include/obj/NiPSysEmitterInitialRadiusCtlr.h"
+#include "../../include/obj/NiFloatData.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
diff --git a/src/obj/NiPSysSphericalCollider.cpp b/src/obj/NiPSysSphericalCollider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65224f6739f71df2841d6f3f6b21ec081d3442fa
--- /dev/null
+++ b/src/obj/NiPSysSphericalCollider.cpp
@@ -0,0 +1,61 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiPSysSphericalCollider.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiPSysSphericalCollider::TYPE("NiPSysSphericalCollider", &NI_P_SYS_SPHERICAL_COLLIDER_PARENT::TYPE );
+
+NiPSysSphericalCollider::NiPSysSphericalCollider() NI_P_SYS_SPHERICAL_COLLIDER_CONSTRUCT {}
+
+NiPSysSphericalCollider::~NiPSysSphericalCollider() {}
+
+void NiPSysSphericalCollider::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiPSysSphericalCollider::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiPSysSphericalCollider::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiPSysSphericalCollider::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiPSysSphericalCollider::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiPSysSphericalCollider::GetType() const {
+	return TYPE;
+}
+
+namespace Niflib {
+	typedef NiObject*(*obj_factory_func)();
+	extern map<string, obj_factory_func> global_object_map;
+
+	//Initialization function
+	static bool Initialization();
+
+	//A static bool to force the initialization to happen pre-main
+	static bool obj_initialized = Initialization();
+
+	static bool Initialization() {
+		//Add the function to the global object map
+		global_object_map["NiPSysSphericalCollider"] = NiPSysSphericalCollider::Create;
+
+		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
+		obj_initialized = true;
+		return obj_initialized;
+	}
+}
+
+NiObject * NiPSysSphericalCollider::Create() {
+	return new NiPSysSphericalCollider;
+}
+
diff --git a/src/obj/NiTriShapeSkinController.cpp b/src/obj/NiTriShapeSkinController.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a1964a646ced026e0f37be75d7f7c9cd71b843a9
--- /dev/null
+++ b/src/obj/NiTriShapeSkinController.cpp
@@ -0,0 +1,63 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiTriShapeSkinController.h"
+#include "../../include/gen/OldSkinData.h"
+#include "../../include/obj/NiBone.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiTriShapeSkinController::TYPE("NiTriShapeSkinController", &NI_TRI_SHAPE_SKIN_CONTROLLER_PARENT::TYPE );
+
+NiTriShapeSkinController::NiTriShapeSkinController() NI_TRI_SHAPE_SKIN_CONTROLLER_CONSTRUCT {}
+
+NiTriShapeSkinController::~NiTriShapeSkinController() {}
+
+void NiTriShapeSkinController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiTriShapeSkinController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiTriShapeSkinController::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiTriShapeSkinController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiTriShapeSkinController::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiTriShapeSkinController::GetType() const {
+	return TYPE;
+}
+
+namespace Niflib {
+	typedef NiObject*(*obj_factory_func)();
+	extern map<string, obj_factory_func> global_object_map;
+
+	//Initialization function
+	static bool Initialization();
+
+	//A static bool to force the initialization to happen pre-main
+	static bool obj_initialized = Initialization();
+
+	static bool Initialization() {
+		//Add the function to the global object map
+		global_object_map["NiTriShapeSkinController"] = NiTriShapeSkinController::Create;
+
+		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
+		obj_initialized = true;
+		return obj_initialized;
+	}
+}
+
+NiObject * NiTriShapeSkinController::Create() {
+	return new NiTriShapeSkinController;
+}
+