From 25189fa97de1ea3b9e5bdd50be894cd28602adb5 Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Fri, 18 May 2007 23:02:55 +0000
Subject: [PATCH] Updated Niflib to the latest XML.  This significantly
 improves the hierarchy and adds support for BSWindModifier.

---
 include/gen/obj_defines.h                     | 1241 +--
 include/obj/ABoneLODController.h              |   94 -
 include/obj/{APSysData.h => BSWindModifier.h} |   22 +-
 include/obj/BSXFlags.h                        |   14 +-
 include/obj/NiAVObject.h                      |   16 +-
 .../obj/{AKeyedData.h => NiAVObjectPalette.h} |   20 +-
 include/obj/NiAlphaController.h               |    2 +-
 include/obj/NiAutoNormalParticlesData.h       |    2 +-
 include/obj/NiBSBoneLODController.h           |    2 +-
 include/obj/NiBSplineCompFloatInterpolator.h  |    2 +-
 include/obj/NiBSplineCompPoint3Interpolator.h |    2 +-
 .../obj/NiBSplineCompTransformInterpolator.h  |    2 +-
 include/obj/NiBSplineFloatInterpolator.h      |   42 +
 include/obj/NiBSplinePoint3Interpolator.h     |   42 +
 ...int.h => NiBSplineTransformInterpolator.h} |   25 +-
 include/obj/NiBoneLODController.h             |    3 +-
 include/obj/NiBoolData.h                      |    2 +-
 include/obj/NiBoolInterpController.h          |   43 +
 include/obj/NiBoolInterpolator.h              |    2 +-
 include/obj/NiBoolTimelineInterpolator.h      |    2 +-
 include/obj/NiCollisionData.h                 |    2 +-
 include/obj/NiCollisionObject.h               |    5 +-
 include/obj/NiColorData.h                     |    2 +-
 include/obj/NiControllerSequence.h            |    4 +-
 include/obj/NiDefaultAVObjectPalette.h        |    2 +-
 include/obj/NiExtraDataController.h           |   42 +
 include/obj/NiFlipController.h                |    2 +-
 include/obj/NiFloatData.h                     |    2 +-
 include/obj/NiFloatExtraDataController.h      |    2 +-
 include/obj/NiFloatInterpController.h         |   43 +
 include/obj/NiFloatInterpolator.h             |    2 +-
 include/obj/NiGeomMorpherController.h         |    2 +-
 include/obj/NiInterpController.h              |   42 +
 include/obj/NiKeyBasedInterpolator.h          |   42 +
 include/obj/NiKeyframeData.h                  |    2 +-
 include/obj/NiLODNode.h                       |    2 +-
 include/obj/NiLightColorController.h          |   26 +-
 include/obj/NiLightDimmerController.h         |    2 +-
 include/obj/NiMaterialColorController.h       |    2 +-
 include/obj/NiMeshPSysData.h                  |    2 +-
 .../obj/NiMultiTargetTransformController.h    |    2 +-
 include/obj/NiPSysData.h                      |    2 +-
 include/obj/NiPSysEmitterCtlr.h               |    2 +-
 include/obj/NiPSysEmitterDeclinationCtlr.h    |    2 +-
 include/obj/NiPSysEmitterDeclinationVarCtlr.h |    2 +-
 include/obj/NiPSysEmitterInitialRadiusCtlr.h  |    2 +-
 include/obj/NiPSysEmitterLifeSpanCtlr.h       |    2 +-
 include/obj/NiPSysEmitterSpeedCtlr.h          |    2 +-
 include/obj/NiPSysGravityStrengthCtlr.h       |    2 +-
 include/obj/NiPSysModifierActiveCtlr.h        |    3 +-
 include/obj/NiPSysModifierBoolCtlr.h          |   43 +
 include/obj/NiPSysModifierCtlr.h              |   42 +
 include/obj/NiPSysModifierFloatCtlr.h         |   48 +
 include/obj/NiParticleMeshesData.h            |    2 +-
 include/obj/NiParticlesData.h                 |    2 +-
 include/obj/NiPathInterpolator.h              |    2 +-
 ...APSysCtlr.h => NiPoint3InterpController.h} |   41 +-
 include/obj/NiPoint3Interpolator.h            |    2 +-
 include/obj/NiPosData.h                       |    2 +-
 include/obj/NiRollController.h                |    2 +-
 ...ontroller.h => NiSingleInterpController.h} |   25 +-
 include/obj/NiSourceTexture.h                 |    2 +-
 include/obj/NiSwitchNode.h                    |   43 +
 include/obj/NiTexture.h                       |   42 +
 include/obj/NiTextureTransformController.h    |    2 +-
 include/obj/NiTransformController.h           |    2 +-
 include/obj/NiTransformInterpolator.h         |    2 +-
 include/obj/NiVisController.h                 |    2 +-
 include/obj/NiVisData.h                       |    2 +-
 include/obj/bhkBlendCollisionObject.h         |    2 +-
 ...AbhkShapeCollection.h => bhkBvTreeShape.h} |   22 +-
 include/obj/bhkCollisionObject.h              |    2 +-
 .../obj/{AbhkConstraint.h => bhkConstraint.h} |   23 +-
 include/obj/bhkConvexVerticesShape.h          |    2 +-
 include/obj/bhkHingeConstraint.h              |    2 +-
 include/obj/bhkLimitedHingeConstraint.h       |    2 +-
 include/obj/bhkListShape.h                    |    2 +-
 include/obj/bhkMalleableConstraint.h          |    2 +-
 include/obj/bhkMoppBvTreeShape.h              |    2 +-
 include/obj/bhkNiCollisionObject.h            |   42 +
 include/obj/bhkNiTriStripsShape.h             |    2 +-
 include/obj/bhkPCollisionObject.h             |   42 +
 include/obj/bhkPackedNiTriStripsShape.h       |    2 +-
 include/obj/bhkPhantom.h                      |   45 +
 include/obj/bhkPrismaticConstraint.h          |    2 +-
 include/obj/bhkRagdollConstraint.h            |    3 +-
 include/obj/bhkRigidBody.h                    |    2 +-
 include/obj/bhkSPCollisionObject.h            |    2 +-
 include/obj/bhkShapeCollection.h              |   42 +
 include/obj/bhkShapePhantom.h                 |   43 +
 include/obj/bhkSimpleShapePhantom.h           |    2 +-
 include/obj/bhkStiffSpringConstraint.h        |    2 +-
 include/obj/hkPackedNiTriStripsData.h         |    2 +-
 niflib.vcproj                                 |  244 +-
 src/gen/obj_impl.cpp                          | 9280 +++++++++--------
 src/niflib.cpp                                |   10 +-
 src/obj/ABoneLODController.cpp                |  125 -
 src/obj/APSysCtlr.cpp                         |   68 -
 ...{AbhkConstraint.cpp => BSWindModifier.cpp} |   32 +-
 src/obj/BSXFlags.cpp                          |    8 -
 src/obj/NiAVObject.cpp                        |   19 +-
 src/obj/NiAVObjectPalette.cpp                 |   61 +
 src/obj/NiBSplineFloatInterpolator.cpp        |   61 +
 src/obj/NiBSplinePoint3Interpolator.cpp       |   61 +
 src/obj/NiBSplineTransformInterpolator.cpp    |   61 +
 src/obj/NiBoolInterpController.cpp            |   61 +
 src/obj/NiCollisionObject.cpp                 |    9 +-
 src/obj/NiControllerSequence.cpp              |    4 +-
 ...nstraint.cpp => NiExtraDataController.cpp} |   32 +-
 src/obj/NiFloatInterpController.cpp           |   61 +
 src/obj/NiInterpController.cpp                |   61 +
 src/obj/NiKeyBasedInterpolator.cpp            |   61 +
 src/obj/NiLightColorController.cpp            |   16 -
 src/obj/NiPSysModifierActiveCtlr.cpp          |    1 +
 src/obj/NiPSysModifierBoolCtlr.cpp            |   61 +
 src/obj/NiPSysModifierCtlr.cpp                |   61 +
 src/obj/NiPSysModifierFloatCtlr.cpp           |   62 +
 src/obj/NiPoint3InterpController.cpp          |   69 +
 src/obj/NiSingleInterpController.cpp          |   69 +
 src/obj/NiSingleInterpolatorController.cpp    |   69 -
 src/obj/NiSwitchNode.cpp                      |   61 +
 src/obj/{APSysData.cpp => NiTexture.cpp}      |   31 +-
 src/obj/bhkBvTreeShape.cpp                    |   61 +
 src/obj/bhkConstraint.cpp                     |   62 +
 src/obj/bhkNiCollisionObject.cpp              |   61 +
 ...Collection.cpp => bhkPCollisionObject.cpp} |   32 +-
 src/obj/{AKeyedData.cpp => bhkPhantom.cpp}    |   31 +-
 src/obj/bhkRigidBody.cpp                      |    2 +-
 src/obj/bhkShapeCollection.cpp                |   61 +
 src/obj/bhkShapePhantom.cpp                   |   61 +
 130 files changed, 7720 insertions(+), 5903 deletions(-)
 delete mode 100644 include/obj/ABoneLODController.h
 rename include/obj/{APSysData.h => BSWindModifier.h} (78%)
 rename include/obj/{AKeyedData.h => NiAVObjectPalette.h} (79%)
 create mode 100644 include/obj/NiBSplineFloatInterpolator.h
 create mode 100644 include/obj/NiBSplinePoint3Interpolator.h
 rename include/obj/{AbhkRagdollConstraint.h => NiBSplineTransformInterpolator.h} (71%)
 create mode 100644 include/obj/NiBoolInterpController.h
 create mode 100644 include/obj/NiExtraDataController.h
 create mode 100644 include/obj/NiFloatInterpController.h
 create mode 100644 include/obj/NiInterpController.h
 create mode 100644 include/obj/NiKeyBasedInterpolator.h
 create mode 100644 include/obj/NiPSysModifierBoolCtlr.h
 create mode 100644 include/obj/NiPSysModifierCtlr.h
 create mode 100644 include/obj/NiPSysModifierFloatCtlr.h
 rename include/obj/{APSysCtlr.h => NiPoint3InterpController.h} (60%)
 rename include/obj/{NiSingleInterpolatorController.h => NiSingleInterpController.h} (72%)
 create mode 100644 include/obj/NiSwitchNode.h
 create mode 100644 include/obj/NiTexture.h
 rename include/obj/{AbhkShapeCollection.h => bhkBvTreeShape.h} (74%)
 rename include/obj/{AbhkConstraint.h => bhkConstraint.h} (78%)
 create mode 100644 include/obj/bhkNiCollisionObject.h
 create mode 100644 include/obj/bhkPCollisionObject.h
 create mode 100644 include/obj/bhkPhantom.h
 create mode 100644 include/obj/bhkShapeCollection.h
 create mode 100644 include/obj/bhkShapePhantom.h
 delete mode 100644 src/obj/ABoneLODController.cpp
 delete mode 100644 src/obj/APSysCtlr.cpp
 rename src/obj/{AbhkConstraint.cpp => BSWindModifier.cpp} (58%)
 create mode 100644 src/obj/NiAVObjectPalette.cpp
 create mode 100644 src/obj/NiBSplineFloatInterpolator.cpp
 create mode 100644 src/obj/NiBSplinePoint3Interpolator.cpp
 create mode 100644 src/obj/NiBSplineTransformInterpolator.cpp
 create mode 100644 src/obj/NiBoolInterpController.cpp
 rename src/obj/{AbhkRagdollConstraint.cpp => NiExtraDataController.cpp} (56%)
 create mode 100644 src/obj/NiFloatInterpController.cpp
 create mode 100644 src/obj/NiInterpController.cpp
 create mode 100644 src/obj/NiKeyBasedInterpolator.cpp
 create mode 100644 src/obj/NiPSysModifierBoolCtlr.cpp
 create mode 100644 src/obj/NiPSysModifierCtlr.cpp
 create mode 100644 src/obj/NiPSysModifierFloatCtlr.cpp
 create mode 100644 src/obj/NiPoint3InterpController.cpp
 create mode 100644 src/obj/NiSingleInterpController.cpp
 delete mode 100644 src/obj/NiSingleInterpolatorController.cpp
 create mode 100644 src/obj/NiSwitchNode.cpp
 rename src/obj/{APSysData.cpp => NiTexture.cpp} (61%)
 create mode 100644 src/obj/bhkBvTreeShape.cpp
 create mode 100644 src/obj/bhkConstraint.cpp
 create mode 100644 src/obj/bhkNiCollisionObject.cpp
 rename src/obj/{AbhkShapeCollection.cpp => bhkPCollisionObject.cpp} (57%)
 rename src/obj/{AKeyedData.cpp => bhkPhantom.cpp} (61%)
 create mode 100644 src/obj/bhkShapeCollection.cpp
 create mode 100644 src/obj/bhkShapePhantom.cpp

diff --git a/include/gen/obj_defines.h b/include/gen/obj_defines.h
index 59af5ee1..02ba52e3 100644
--- a/include/gen/obj_defines.h
+++ b/include/gen/obj_defines.h
@@ -12,8 +12,6 @@ All rights reserved.  Please see niflib.h for license. */
 
 #define NI_OBJECT_MEMBERS \
 
-#define A_KEYED_DATA_MEMBERS \
-
 #define A_PARTICLE_MODIFIER_MEMBERS \
 Ref<AParticleModifier > nextModifier; \
 NiParticleSystemController * controller; \
@@ -31,35 +29,189 @@ Ref<NiNode > colliderObject; \
 
 #define BHK_SERIALIZABLE_MEMBERS \
 
-#define ABHK_CONSTRAINT_MEMBERS \
-mutable unsigned int numBodies; \
-vector<bhkShape * > bodies; \
+#define BHK_WORLD_OBJECT_MEMBERS \
+Ref<bhkShape > shape; \
+OblivionLayer layer; \
+byte colFilter; \
+unsigned short unknownShort; \
+
+#define BHK_PHANTOM_MEMBERS \
+
+#define BHK_SHAPE_PHANTOM_MEMBERS \
+
+#define BHK_SIMPLE_SHAPE_PHANTOM_MEMBERS \
+array<7,float > unkownFloats; \
+array< 3, array<5,float > > unknownFloats2; \
+float unknownFloat; \
+
+#define BHK_ENTITY_MEMBERS \
+
+#define BHK_RIGID_BODY_MEMBERS \
+array<5,float > unknown5Floats; \
+array<4,unsigned short > unknown4Shorts; \
+OblivionLayer layerCopy; \
+byte colFilterCopy; \
+array<7,unsigned short > unknown7Shorts; \
+Vector3 translation; \
+float unknownFloat00; \
+QuaternionXYZW rotation; \
+Vector3 linearVelocity; \
+float unknownFloat01; \
+Vector3 angularVelocity; \
+float unknownFloat02; \
+array<12,float > inertia; \
+Vector3 center; \
+float unknownFloat03; \
+float mass; \
+float linearDamping; \
+float angularDamping; \
+float friction; \
+float restitution; \
+float maxLinearVelocity; \
+float maxAngularVelocity; \
+float penetrationDepth; \
+MotionSystem motionSystem; \
+byte unknownByte1; \
+byte unknownByte2; \
+MotionQuality qualityType; \
+unsigned int unknownInt6; \
+unsigned int unknownInt7; \
+unsigned int unknownInt8; \
+mutable unsigned int numConstraints; \
+vector<Ref<bhkConstraint > > constraints; \
+
+#define BHK_RIGID_BODY_T_MEMBERS \
+
+#define BHK_CONSTRAINT_MEMBERS \
+mutable unsigned int numEntities; \
+vector<bhkEntity * > entities; \
 unsigned int priority; \
 
-#define ABHK_RAGDOLL_CONSTRAINT_MEMBERS \
+#define BHK_LIMITED_HINGE_CONSTRAINT_MEMBERS \
+LimitedHingeDescriptor limitedHinge; \
+
+#define BHK_MALLEABLE_CONSTRAINT_MEMBERS \
+unsigned int type; \
+unsigned int unknownInt2; \
+Ref<NiObject > unknownLink1; \
+Ref<NiObject > unknownLink2; \
+unsigned int unknownInt3; \
 RagdollDescriptor ragdoll; \
+LimitedHingeDescriptor limitedHinge; \
+float tau; \
+float damping; \
+
+#define BHK_STIFF_SPRING_CONSTRAINT_MEMBERS \
+Float4 pivotA; \
+Float4 pivotB; \
+float length; \
+
+#define BHK_RAGDOLL_CONSTRAINT_MEMBERS \
+RagdollDescriptor ragdoll; \
+
+#define BHK_PRISMATIC_CONSTRAINT_MEMBERS \
+array<8,Float4 > unknownVectors; \
+array<3,float > unknownFloats2; \
+
+#define BHK_HINGE_CONSTRAINT_MEMBERS \
+Float4 pivotA; \
+Float4 perp2axleina1; \
+Float4 perp2axleina2; \
+Float4 pivotB; \
+Float4 axleB; \
 
 #define BHK_SHAPE_MEMBERS \
 
-#define ABHK_SHAPE_COLLECTION_MEMBERS \
+#define BHK_TRANSFORM_SHAPE_MEMBERS \
+Ref<bhkShape > shape; \
+HavokMaterial material; \
+float unknownFloat1; \
+array<8,byte > unknown8Bytes; \
+Matrix44 transform; \
 
 #define BHK_SPHERE_REP_SHAPE_MEMBERS \
 HavokMaterial material; \
+float radius; \
 
 #define BHK_CONVEX_SHAPE_MEMBERS \
 
-#define BHK_WORLD_OBJECT_MEMBERS \
+#define BHK_SPHERE_SHAPE_MEMBERS \
 
-#define BHK_ENTITY_MEMBERS \
+#define BHK_CAPSULE_SHAPE_MEMBERS \
+unsigned short unknownShort1; \
+unsigned short unknownShort2; \
+unsigned short unknownShort3; \
+unsigned short unknownShort4; \
+Vector3 firstPoint; \
+float radius1; \
+Vector3 secondPoint; \
+float radius2; \
+
+#define BHK_BOX_SHAPE_MEMBERS \
+unsigned short unknownShort1; \
+unsigned short unknownShort2; \
+unsigned short unknownShort3; \
+unsigned short unknownShort4; \
+Vector3 dimensions; \
+float min_Size; \
+
+#define BHK_CONVEX_VERTICES_SHAPE_MEMBERS \
+array<6,float > unknown6Floats; \
+mutable unsigned int numVertices; \
+vector<Float4 > vertices; \
+mutable unsigned int numNormals; \
+vector<Float4 > normals; \
+
+#define BHK_CONVEX_TRANSFORM_SHAPE_MEMBERS \
+
+#define BHK_MULTI_SPHERE_SHAPE_MEMBERS \
+float unknownFloat1; \
+float unknownFloat2; \
+mutable unsigned int numSpheres; \
+vector<Sphere > spheres; \
+
+#define BHK_BV_TREE_SHAPE_MEMBERS \
+
+#define BHK_MOPP_BV_TREE_SHAPE_MEMBERS \
 Ref<bhkShape > shape; \
-OblivionLayer layer; \
-byte colFilter; \
-unsigned short unknownShort; \
+HavokMaterial material; \
+array<8,byte > unknown8Bytes; \
+float unknownFloat; \
+mutable unsigned int moppDataSize; \
+Vector3 objectCorner; \
+float scalingFactor; \
+vector<byte > moppData; \
 
-#define NI_COLLISION_OBJECT_MEMBERS \
-NiAVObject * parent; \
-unsigned short unknownShort; \
-Ref<NiObject > body; \
+#define BHK_SHAPE_COLLECTION_MEMBERS \
+
+#define BHK_LIST_SHAPE_MEMBERS \
+mutable unsigned int numSubShapes; \
+vector<Ref<bhkShape > > subShapes; \
+HavokMaterial material; \
+array<6,float > unknownFloats; \
+mutable unsigned int numUnknownInts; \
+vector<unsigned int > unknownInts; \
+
+#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_MEMBERS \
+mutable unsigned short numSubShapes; \
+vector<OblivionSubShape > subShapes; \
+array<9,float > unknownFloats; \
+float scale; \
+array<3,float > unknownFloats2; \
+Ref<hkPackedNiTriStripsData > data; \
+
+#define BHK_NI_TRI_STRIPS_SHAPE_MEMBERS \
+HavokMaterial material; \
+float unknownFloat1; \
+unsigned int unknownInt1; \
+array<4,unsigned int > unknownInts1; \
+unsigned int unknownInt2; \
+Vector3 scale; \
+unsigned int unknownInt3; \
+mutable unsigned int numStripsData; \
+vector<Ref<NiTriStripsData > > stripsData; \
+mutable unsigned int numDataLayers; \
+vector<OblivionColFilter > dataLayers; \
 
 #define NI_EXTRA_DATA_MEMBERS \
 string name; \
@@ -67,6 +219,38 @@ Ref<NiExtraData > nextExtraData; \
 
 #define NI_INTERPOLATOR_MEMBERS \
 
+#define NI_KEY_BASED_INTERPOLATOR_MEMBERS \
+
+#define NI_FLOAT_INTERPOLATOR_MEMBERS \
+float floatValue; \
+Ref<NiFloatData > data; \
+
+#define NI_TRANSFORM_INTERPOLATOR_MEMBERS \
+Vector3 translation; \
+Quaternion rotation; \
+float scale; \
+array<3,byte > unknownBytes; \
+Ref<NiTransformData > data; \
+
+#define NI_POINT3_INTERPOLATOR_MEMBERS \
+Vector3 point3Value; \
+Ref<NiPosData > data; \
+
+#define NI_PATH_INTERPOLATOR_MEMBERS \
+unsigned short unknownShort; \
+unsigned int unknownInt; \
+float unknownFloat1; \
+float unknownFloat2; \
+unsigned short unknownShort2; \
+Ref<NiPosData > posData; \
+Ref<NiFloatData > floatData; \
+
+#define NI_BOOL_INTERPOLATOR_MEMBERS \
+bool boolValue; \
+Ref<NiBoolData > data; \
+
+#define NI_BOOL_TIMELINE_INTERPOLATOR_MEMBERS \
+
 #define NI_BLEND_INTERPOLATOR_MEMBERS \
 unsigned short unknownShort; \
 unsigned int unknownInt; \
@@ -84,6 +268,32 @@ mutable unsigned int numExtraDataList; \
 vector<Ref<NiExtraData > > extraDataList; \
 Ref<NiTimeController > controller; \
 
+#define NI_COLLISION_OBJECT_MEMBERS \
+NiAVObject * target; \
+unsigned short unknownShort; \
+Ref<NiObject > body; \
+
+#define NI_COLLISION_DATA_MEMBERS \
+unsigned int unknownInt1; \
+unsigned int unknownInt2; \
+byte unknownByte; \
+unsigned int collisionType; \
+Vector3 unknownVector; \
+array<8,float > unknownFloat1; \
+array<15,float > unknownFloat2; \
+
+#define BHK_NI_COLLISION_OBJECT_MEMBERS \
+
+#define BHK_COLLISION_OBJECT_MEMBERS \
+
+#define BHK_BLEND_COLLISION_OBJECT_MEMBERS \
+float unknownFloat1; \
+float unknownFloat2; \
+
+#define BHK_P_COLLISION_OBJECT_MEMBERS \
+
+#define BHK_S_P_COLLISION_OBJECT_MEMBERS \
+
 #define NI_A_V_OBJECT_MEMBERS \
 unsigned short flags; \
 Vector3 translation; \
@@ -94,7 +304,6 @@ mutable unsigned int numProperties; \
 vector<Ref<NiProperty > > properties; \
 bool hasBoundingBox; \
 BoundingBox boundingBox; \
-Ref<NiCollisionData > collisionData; \
 Ref<NiCollisionObject > collisionObject; \
 
 #define NI_DYNAMIC_EFFECT_MEMBERS \
@@ -143,227 +352,141 @@ float startTime; \
 float stopTime; \
 NiObjectNET * target; \
 
-#define A_BONE_L_O_D_CONTROLLER_MEMBERS \
-unsigned int unknownInt1; \
-mutable unsigned int numNodeGroups; \
-unsigned int numNodeGroups2; \
-vector<NodeGroup > nodeGroups; \
+#define NI_INTERP_CONTROLLER_MEMBERS \
 
-#define NI_SINGLE_INTERPOLATOR_CONTROLLER_MEMBERS \
-Ref<NiInterpolator > interpolator; \
+#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_MEMBERS \
+mutable unsigned short numExtraTargets; \
+vector<NiNode * > extraTargets; \
 
-#define A_P_SYS_CTLR_MEMBERS \
-string modifierName; \
+#define NI_GEOM_MORPHER_CONTROLLER_MEMBERS \
+unsigned short unknown; \
+byte unknown2; \
+Ref<NiMorphData > data; \
+byte unknownByte; \
+mutable unsigned int numInterpolators; \
+vector<Ref<NiInterpolator > > interpolators; \
+mutable unsigned int numUnknownInts; \
+vector<unsigned int > unknownInts; \
 
-#define NI_GEOMETRY_MEMBERS \
-Ref<NiGeometryData > data; \
-Ref<NiSkinInstance > skinInstance; \
-bool hasShader; \
-string shaderName; \
-Ref<NiObject > unknownLink; \
+#define NI_SINGLE_INTERP_CONTROLLER_MEMBERS \
+Ref<NiInterpolator > interpolator; \
 
-#define NI_TRI_BASED_GEOM_MEMBERS \
+#define NI_TRANSFORM_CONTROLLER_MEMBERS \
 
-#define NI_GEOMETRY_DATA_MEMBERS \
-string name; \
-mutable unsigned short numVertices; \
-unsigned short unknownShort1; \
-bool hasVertices; \
-vector<Vector3 > vertices; \
-mutable byte numUvSets2; \
-byte unknownByte; \
-bool hasNormals; \
-vector<Vector3 > normals; \
-vector<Vector3 > unknownVectors1; \
-vector<Vector3 > unknownVectors2; \
-Vector3 center; \
-float radius; \
-bool hasVertexColors; \
-vector<Color4 > vertexColors; \
-mutable unsigned short numUvSets; \
-bool hasUv; \
-vector< vector<TexCoord > > uvSets; \
-unsigned short unknownShort2; \
-Ref<NiObject > unknownLink; \
+#define NI_P_SYS_MODIFIER_CTLR_MEMBERS \
+string modifierName; \
 
-#define NI_TRI_BASED_GEOM_DATA_MEMBERS \
-unsigned short numTriangles; \
+#define NI_P_SYS_EMITTER_CTLR_MEMBERS \
+Ref<NiPSysEmitterCtlrData > data; \
+Ref<NiInterpolator > visibilityInterpolator; \
 
-#define A_P_SYS_DATA_MEMBERS \
-bool hasUnknownFloats1; \
-vector<float > unknownFloats1; \
-unsigned short unknownShort3; \
-bool hasUnknownFloats2; \
-vector<float > unknownFloats2; \
-byte hasUnknownFloats3; \
-vector< array<4,float > > unknownFloats3; \
+#define NI_P_SYS_MODIFIER_BOOL_CTLR_MEMBERS \
 
-#define BHK_BLEND_COLLISION_OBJECT_MEMBERS \
-float unknownFloat1; \
-float unknownFloat2; \
+#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_MEMBERS \
+Ref<NiVisData > data; \
 
-#define BHK_BLEND_CONTROLLER_MEMBERS \
-unsigned int unknownInt; \
+#define NI_P_SYS_MODIFIER_FLOAT_CTLR_MEMBERS \
+Ref<NiFloatData > data; \
 
-#define BHK_BOX_SHAPE_MEMBERS \
-float unknownFloat1; \
-unsigned short unknownShort1; \
-unsigned short unknownShort2; \
-unsigned short unknownShort3; \
-unsigned short unknownShort4; \
-Vector3 dimensions; \
-float min_Size; \
+#define NI_P_SYS_EMITTER_DECLINATION_CTLR_MEMBERS \
 
-#define BHK_CAPSULE_SHAPE_MEMBERS \
-float radius; \
-unsigned short unknownShort1; \
-unsigned short unknownShort2; \
-unsigned short unknownShort3; \
-unsigned short unknownShort4; \
-Vector3 firstPoint; \
-float radius1; \
-Vector3 secondPoint; \
-float radius2; \
+#define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_MEMBERS \
 
-#define BHK_COLLISION_OBJECT_MEMBERS \
+#define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_MEMBERS \
 
-#define BHK_CONVEX_VERTICES_SHAPE_MEMBERS \
-array<7,float > unknownFloats1; \
-mutable unsigned int numVertices; \
-vector<Float4 > vertices; \
-mutable unsigned int numNormals; \
-vector<Float4 > normals; \
+#define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_MEMBERS \
 
-#define BHK_HINGE_CONSTRAINT_MEMBERS \
-Float4 pivotA; \
-Float4 perp2axleina1; \
-Float4 perp2axleina2; \
-Float4 pivotB; \
-Float4 axleB; \
+#define NI_P_SYS_EMITTER_SPEED_CTLR_MEMBERS \
 
-#define BHK_LIMITED_HINGE_CONSTRAINT_MEMBERS \
-LimitedHingeDescriptor limitedHinge; \
+#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_MEMBERS \
 
-#define BHK_LIST_SHAPE_MEMBERS \
-mutable unsigned int numSubShapes; \
-vector<Ref<bhkShape > > subShapes; \
-HavokMaterial material; \
-array<6,float > unknownFloats; \
-mutable unsigned int numUnknownInts; \
-vector<unsigned int > unknownInts; \
+#define NI_FLOAT_INTERP_CONTROLLER_MEMBERS \
 
-#define BHK_MALLEABLE_CONSTRAINT_MEMBERS \
-unsigned int type; \
+#define NI_FLIP_CONTROLLER_MEMBERS \
+unsigned int textureSlot; \
 unsigned int unknownInt2; \
-Ref<NiObject > unknownLink1; \
-Ref<NiObject > unknownLink2; \
-unsigned int unknownInt3; \
-RagdollDescriptor ragdoll; \
-LimitedHingeDescriptor limitedHinge; \
-float tau; \
-float damping; \
+float delta; \
+mutable unsigned int numSources; \
+vector<Ref<NiSourceTexture > > sources; \
+vector<Ref<NiImage > > image; \
 
-#define BHK_MOPP_BV_TREE_SHAPE_MEMBERS \
-Ref<bhkShape > shape; \
-HavokMaterial material; \
-array<8,byte > unknown8Bytes; \
-float unknownFloat; \
-mutable unsigned int moppDataSize; \
-Vector3 objectCorner; \
-float scalingFactor; \
-vector<byte > moppData; \
+#define NI_ALPHA_CONTROLLER_MEMBERS \
+Ref<NiFloatData > data; \
 
-#define BHK_MULTI_SPHERE_SHAPE_MEMBERS \
-float unknownFloat1; \
-float unknownFloat2; \
-float unknownFloat3; \
-mutable unsigned int numSpheres; \
-vector<Sphere > spheres; \
+#define NI_TEXTURE_TRANSFORM_CONTROLLER_MEMBERS \
+byte unknown2; \
+TexType textureSlot; \
+unsigned int operation; \
+Ref<NiFloatData > data; \
 
-#define BHK_NI_TRI_STRIPS_SHAPE_MEMBERS \
-float unknownFloat1; \
-unsigned int unknownInt1; \
-array<4,unsigned int > unknownInts1; \
-unsigned int unknownInt2; \
-Vector3 scale; \
-unsigned int unknownInt3; \
-mutable unsigned int numStripsData; \
-vector<Ref<NiTriStripsData > > stripsData; \
-mutable unsigned int numDataLayers; \
-vector<OblivionColFilter > dataLayers; \
+#define NI_LIGHT_DIMMER_CONTROLLER_MEMBERS \
 
-#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_MEMBERS \
-mutable unsigned short numSubShapes; \
-vector<OblivionSubShape > subShapes; \
-array<9,float > unknownFloats; \
-float scale; \
-array<3,float > unknownFloats2; \
-Ref<hkPackedNiTriStripsData > data; \
+#define NI_BOOL_INTERP_CONTROLLER_MEMBERS \
+
+#define NI_VIS_CONTROLLER_MEMBERS \
+Ref<NiVisData > data; \
 
-#define BHK_PRISMATIC_CONSTRAINT_MEMBERS \
-array<8,Float4 > unknownVectors; \
-array<3,float > unknownFloats2; \
+#define NI_POINT3_INTERP_CONTROLLER_MEMBERS \
+unsigned short targetColor; \
+Ref<NiPosData > data; \
 
-#define BHK_RAGDOLL_CONSTRAINT_MEMBERS \
+#define NI_MATERIAL_COLOR_CONTROLLER_MEMBERS \
 
-#define BHK_RIGID_BODY_MEMBERS \
-array<5,float > unknown5Floats; \
-array<4,unsigned short > unknown4Shorts; \
-OblivionLayer layerCopy; \
-byte colFilterCopy; \
-array<7,unsigned short > unknown7Shorts; \
-Vector3 translation; \
-float unknownFloat00; \
-QuaternionXYZW rotation; \
-Vector3 linearVelocity; \
-float unknownFloat01; \
-Vector3 angularVelocity; \
-float unknownFloat02; \
-array<12,float > inertia; \
-Vector3 center; \
-float unknownFloat03; \
-float mass; \
-float linearDamping; \
-float angularDamping; \
-float friction; \
-float restitution; \
-float maxLinearVelocity; \
-float maxAngularVelocity; \
-float penetrationDepth; \
-MotionSystem motionSystem; \
-byte unknownByte1; \
-byte unknownByte2; \
-MotionQuality qualityType; \
-unsigned int unknownInt6; \
-unsigned int unknownInt7; \
-unsigned int unknownInt8; \
-mutable unsigned int numConstraints; \
-vector<Ref<AbhkConstraint > > constraints; \
+#define NI_LIGHT_COLOR_CONTROLLER_MEMBERS \
 
-#define BHK_RIGID_BODY_T_MEMBERS \
+#define NI_EXTRA_DATA_CONTROLLER_MEMBERS \
 
-#define BHK_SIMPLE_SHAPE_PHANTOM_MEMBERS \
-array<7,float > unkownFloats; \
-array< 3, array<5,float > > unknownFloats2; \
-float unknownFloat; \
+#define NI_FLOAT_EXTRA_DATA_CONTROLLER_MEMBERS \
+string controllerData; \
 
-#define BHK_S_P_COLLISION_OBJECT_MEMBERS \
+#define NI_BONE_L_O_D_CONTROLLER_MEMBERS \
+unsigned int unknownInt1; \
+mutable unsigned int numNodeGroups; \
+unsigned int numNodeGroups2; \
+vector<NodeGroup > nodeGroups; \
+mutable unsigned int numShapeGroups; \
+vector<SkinShapeGroup > shapeGroups1; \
+mutable unsigned int numShapeGroups2; \
+vector<Ref<NiTriShape > > shapeGroups2; \
 
-#define BHK_SPHERE_SHAPE_MEMBERS \
-float radius; \
+#define NI_B_S_BONE_L_O_D_CONTROLLER_MEMBERS \
 
-#define BHK_STIFF_SPRING_CONSTRAINT_MEMBERS \
-Float4 pivotA; \
-Float4 pivotB; \
-float length; \
+#define NI_GEOMETRY_MEMBERS \
+Ref<NiGeometryData > data; \
+Ref<NiSkinInstance > skinInstance; \
+bool hasShader; \
+string shaderName; \
+Ref<NiObject > unknownLink; \
 
-#define BHK_TRANSFORM_SHAPE_MEMBERS \
-float unknownFloat1; \
-float unknownFloat2; \
-float unknownFloat3; \
-Matrix44 transform; \
+#define NI_TRI_BASED_GEOM_MEMBERS \
 
-#define BHK_CONVEX_TRANSFORM_SHAPE_MEMBERS \
+#define NI_GEOMETRY_DATA_MEMBERS \
+string name; \
+mutable unsigned short numVertices; \
+unsigned short unknownShort1; \
+bool hasVertices; \
+vector<Vector3 > vertices; \
+mutable byte numUvSets2; \
+byte unknownByte1; \
+bool hasNormals; \
+vector<Vector3 > normals; \
+vector<Vector3 > unknownVectors1; \
+vector<Vector3 > unknownVectors2; \
+Vector3 center; \
+float radius; \
+bool hasVertexColors; \
+vector<Color4 > vertexColors; \
+mutable unsigned short numUvSets; \
+bool hasUv; \
+vector< vector<TexCoord > > uvSets; \
+unsigned short unknownShort2; \
+Ref<NiObject > unknownLink1; \
+
+#define NI_TRI_BASED_GEOM_DATA_MEMBERS \
+unsigned short numTriangles; \
+
+#define BHK_BLEND_CONTROLLER_MEMBERS \
+unsigned int unknownInt; \
 
 #define B_S_BOUND_MEMBERS \
 Vector3 center; \
@@ -378,8 +501,8 @@ float unknownFloat; \
 
 #define B_S_P_SYS_ARRAY_EMITTER_MEMBERS \
 
-#define B_S_X_FLAGS_MEMBERS \
-unsigned int flags; \
+#define B_S_WIND_MODIFIER_MEMBERS \
+float unknownFloat; \
 
 #define HK_PACKED_NI_TRI_STRIPS_DATA_MEMBERS \
 mutable unsigned int numTriangles; \
@@ -387,22 +510,51 @@ vector<hkTriangle > triangles; \
 mutable unsigned int numVertices; \
 vector<Vector3 > vertices; \
 
-#define NI_ALPHA_CONTROLLER_MEMBERS \
-Ref<NiFloatData > data; \
-
 #define NI_ALPHA_PROPERTY_MEMBERS \
 unsigned short flags; \
 byte threshold; \
 
 #define NI_AMBIENT_LIGHT_MEMBERS \
 
-#define NI_AUTO_NORMAL_PARTICLES_DATA_MEMBERS \
+#define NI_PARTICLES_DATA_MEMBERS \
 unsigned short numParticles; \
 float size; \
 unsigned short numActive; \
 unsigned short unknownShort; \
 bool hasSizes; \
 vector<float > sizes; \
+bool hasUnknownFloats1; \
+vector<float > unknownFloats1; \
+bool hasRotations1; \
+vector<Quaternion > rotations1; \
+
+#define NI_ROTATING_PARTICLES_DATA_MEMBERS \
+bool hasRotations2; \
+vector<Quaternion > rotations2; \
+
+#define NI_AUTO_NORMAL_PARTICLES_DATA_MEMBERS \
+
+#define NI_P_SYS_DATA_MEMBERS \
+vector< array<10,float > > unknownFloats2; \
+bool hasUnknownFloats3; \
+vector<float > unknownFloats1; \
+bool hasUnknownFloats4; \
+vector< array<4,float > > unknownFloats4; \
+vector< array<7,float > > unknownFloats5; \
+bool hasUnknownFloats6; \
+vector<float > unknownFloats6; \
+unsigned int unknownInt1; \
+
+#define NI_MESH_P_SYS_DATA_MEMBERS \
+Ref<NiObject > modifier; \
+byte unknownByte2; \
+mutable unsigned int numUnknownLinks; \
+vector<Ref<NiObject > > unknownLinks; \
+unsigned int numVertices2; \
+byte unknownByte3; \
+unsigned int unknownInt2; \
+unsigned int numVertices3; \
+Ref<NiNode > unknownLink2; \
 
 #define NI_BINARY_EXTRA_DATA_MEMBERS \
 ByteArray binaryData; \
@@ -434,37 +586,28 @@ Vector3 pointValue; \
 
 #define NI_BLEND_TRANSFORM_INTERPOLATOR_MEMBERS \
 
-#define NI_BONE_L_O_D_CONTROLLER_MEMBERS \
-mutable unsigned int numShapeGroups; \
-vector<SkinShapeGroup > shapeGroups1; \
-mutable unsigned int numShapeGroups2; \
-vector<Ref<NiTriShape > > shapeGroups2; \
-
 #define NI_BOOL_DATA_MEMBERS \
 KeyGroup<byte > data; \
 
 #define NI_BOOLEAN_EXTRA_DATA_MEMBERS \
 byte booleanData; \
 
-#define NI_BOOL_INTERPOLATOR_MEMBERS \
-bool boolValue; \
-Ref<NiBoolData > data; \
-
-#define NI_BOOL_TIMELINE_INTERPOLATOR_MEMBERS \
-byte boolValue; \
-Ref<NiBoolData > data; \
-
-#define NI_B_S_BONE_L_O_D_CONTROLLER_MEMBERS \
-
 #define NI_B_SPLINE_BASIS_DATA_MEMBERS \
 unsigned int numControlPt; \
 
+#define NI_B_SPLINE_FLOAT_INTERPOLATOR_MEMBERS \
+
 #define NI_B_SPLINE_COMP_FLOAT_INTERPOLATOR_MEMBERS \
 array<4,float > unknownFloats; \
 
+#define NI_B_SPLINE_POINT3_INTERPOLATOR_MEMBERS \
+array<6,float > unknownFloats; \
+
 #define NI_B_SPLINE_COMP_POINT3_INTERPOLATOR_MEMBERS \
 array<6,float > unknownFloats; \
 
+#define NI_B_SPLINE_TRANSFORM_INTERPOLATOR_MEMBERS \
+
 #define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_MEMBERS \
 Vector3 translation; \
 Quaternion rotation; \
@@ -503,16 +646,6 @@ unsigned int unknownInt; \
 unsigned int unknownInt2; \
 unsigned int unknownInt3; \
 
-#define NI_COLLISION_DATA_MEMBERS \
-NiNode * targetNode; \
-unsigned int unknownInt1; \
-unsigned int unknownInt2; \
-byte unknownByte; \
-unsigned int collisionType; \
-Vector3 unknownVector; \
-array<8,float > unknownFloat1; \
-array<15,float > unknownFloat2; \
-
 #define NI_COLOR_DATA_MEMBERS \
 KeyGroup<Color4 > data; \
 
@@ -547,6 +680,8 @@ NiControllerManager * manager; \
 string targetName; \
 Ref<NiStringPalette > stringPalette; \
 
+#define NI_A_V_OBJECT_PALETTE_MEMBERS \
+
 #define NI_DEFAULT_A_V_OBJECT_PALETTE_MEMBERS \
 unsigned int unknownInt; \
 mutable unsigned int numObjs; \
@@ -557,14 +692,6 @@ vector<AVObject > objs; \
 #define NI_DITHER_PROPERTY_MEMBERS \
 unsigned short flags; \
 
-#define NI_FLIP_CONTROLLER_MEMBERS \
-unsigned int textureSlot; \
-unsigned int unknownInt2; \
-float delta; \
-mutable unsigned int numSources; \
-vector<Ref<NiSourceTexture > > sources; \
-vector<Ref<NiImage > > image; \
-
 #define NI_ROLL_CONTROLLER_MEMBERS \
 Ref<NiFloatData > data; \
 
@@ -574,14 +701,6 @@ KeyGroup<float > data; \
 #define NI_FLOAT_EXTRA_DATA_MEMBERS \
 float floatData; \
 
-#define NI_FLOAT_EXTRA_DATA_CONTROLLER_MEMBERS \
-Ref<NiObject > unknownLink; \
-string controllerData; \
-
-#define NI_FLOAT_INTERPOLATOR_MEMBERS \
-float floatValue; \
-Ref<NiFloatData > data; \
-
 #define NI_FLOATS_EXTRA_DATA_MEMBERS \
 mutable unsigned int numFloats; \
 vector<float > data; \
@@ -591,16 +710,6 @@ unsigned short flags; \
 float fogDepth; \
 Color3 fogColor; \
 
-#define NI_GEOM_MORPHER_CONTROLLER_MEMBERS \
-unsigned short unknown; \
-byte unknown2; \
-Ref<NiMorphData > data; \
-byte unknownByte; \
-mutable unsigned int numInterpolators; \
-vector<Ref<NiInterpolator > > interpolators; \
-mutable unsigned int numUnknownInts; \
-vector<unsigned int > unknownInts; \
-
 #define NI_GRAVITY_MEMBERS \
 float unknownFloat1; \
 float force; \
@@ -611,6 +720,8 @@ Vector3 direction; \
 #define NI_INTEGER_EXTRA_DATA_MEMBERS \
 unsigned int integerData; \
 
+#define B_S_X_FLAGS_MEMBERS \
+
 #define NI_INTEGERS_EXTRA_DATA_MEMBERS \
 mutable unsigned int numIntegers; \
 vector<unsigned int > data; \
@@ -630,14 +741,6 @@ array<3,KeyGroup<float > > xyzRotations; \
 KeyGroup<Vector3 > translations; \
 KeyGroup<float > scales; \
 
-#define NI_LIGHT_COLOR_CONTROLLER_MEMBERS \
-unsigned short unknownShort; \
-Ref<NiPosData > data; \
-Ref<NiPoint3Interpolator > interpolator; \
-
-#define NI_LIGHT_DIMMER_CONTROLLER_MEMBERS \
-Ref<NiInterpolator > unknownLink; \
-
 #define NI_LOOK_AT_CONTROLLER_MEMBERS \
 unsigned short unknown1; \
 Ref<NiNode > lookAtNode; \
@@ -653,10 +756,6 @@ Ref<NiPoint3Interpolator > unknownLink1; \
 Ref<NiFloatInterpolator > unknownLink2; \
 Ref<NiFloatInterpolator > unknownLink3; \
 
-#define NI_MATERIAL_COLOR_CONTROLLER_MEMBERS \
-unsigned short targetColor; \
-Ref<NiPosData > data; \
-
 #define NI_MATERIAL_PROPERTY_MEMBERS \
 unsigned short flags; \
 Color3 ambientColor; \
@@ -666,32 +765,12 @@ Color3 emissiveColor; \
 float glossiness; \
 float alpha; \
 
-#define NI_MESH_P_SYS_DATA_MEMBERS \
-byte unknownByte11; \
-vector< array<10,float > > unknownFloats4; \
-vector< array<12,float > > unknownFloats5; \
-unsigned int unknownInt1; \
-Ref<NiObject > modifier; \
-byte unknownByte2; \
-mutable unsigned int numUnknownLinks; \
-vector<Ref<NiObject > > unknownLinks; \
-unsigned short unknownShort4; \
-unsigned int unknownInt2; \
-byte unknownByte12; \
-unsigned int unknownInt3; \
-unsigned int unknownInt4; \
-Ref<NiNode > unknownLink2; \
-
 #define NI_MORPH_DATA_MEMBERS \
 mutable unsigned int numMorphs; \
 unsigned int numVertices; \
 byte unknownByte; \
 vector<Morph > morphs; \
 
-#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_MEMBERS \
-mutable unsigned short numExtraTargets; \
-vector<NiNode * > extraTargets; \
-
 #define NI_NODE_MEMBERS \
 mutable unsigned int numChildren; \
 vector<Ref<NiAVObject > > children; \
@@ -722,6 +801,8 @@ BillboardMode billboardMode; \
 
 #define NI_B_S_PARTICLE_NODE_MEMBERS \
 
+#define NI_SWITCH_NODE_MEMBERS \
+
 #define NI_L_O_D_NODE_MEMBERS \
 array<4,byte > unknown4Bytes; \
 Vector3 lodCenter; \
@@ -773,13 +854,6 @@ float unknownFloat4; \
 
 #define NI_PARTICLE_MESHES_MEMBERS \
 
-#define NI_PARTICLES_DATA_MEMBERS \
-unsigned short numActive; \
-bool hasUnknownFloats; \
-vector<float > unknownFloats; \
-bool hasRotations; \
-vector<Quaternion > rotations; \
-
 #define NI_PARTICLE_MESHES_DATA_MEMBERS \
 Ref<NiAVObject > unknownLink2; \
 
@@ -841,13 +915,6 @@ unsigned short unknownShort; \
 Ref<NiPosData > posData; \
 Ref<NiFloatData > floatData; \
 
-#define NI_PATH_INTERPOLATOR_MEMBERS \
-float unknownFloat1; \
-float unknownFloat2; \
-unsigned short unknownShort2; \
-Ref<NiPosData > posData; \
-Ref<NiFloatData > floatData; \
-
 #define NI_PIXEL_DATA_MEMBERS \
 PixelFormat pixelFormat; \
 unsigned int redMask; \
@@ -885,10 +952,6 @@ float unknownFloat14; \
 float unknownFloat15; \
 float unknownFloat16; \
 
-#define NI_POINT3_INTERPOLATOR_MEMBERS \
-Vector3 point3Value; \
-Ref<NiPosData > data; \
-
 #define NI_POINT_LIGHT_MEMBERS \
 float constantAttenuation; \
 float linearAttenuation; \
@@ -925,16 +988,6 @@ Ref<NiColorData > data; \
 float radius; \
 float height; \
 
-#define NI_P_SYS_DATA_MEMBERS \
-vector< array<10,float > > unknownFloats4; \
-bool unknownBool1; \
-vector< array<32,byte > > unknownBytes; \
-vector< array<28,byte > > unknownBytesAlt; \
-byte unknownByte3; \
-bool unknownBool2; \
-vector< array<4,byte > > unknownBytes2; \
-unsigned int unknownInt1; \
-
 #define NI_P_SYS_DRAG_MODIFIER_MEMBERS \
 NiObject * parent; \
 Vector3 dragAxis; \
@@ -942,29 +995,11 @@ float percentage; \
 float range; \
 float rangeFalloff; \
 
-#define NI_P_SYS_EMITTER_CTLR_MEMBERS \
-Ref<NiPSysEmitterCtlrData > data; \
-Ref<NiInterpolator > visibilityInterpolator; \
-
 #define NI_P_SYS_EMITTER_CTLR_DATA_MEMBERS \
 KeyGroup<float > floatKeys_; \
 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; \
-
-#define NI_P_SYS_EMITTER_SPEED_CTLR_MEMBERS \
-Ref<NiFloatData > unknownLink; \
-
 #define NI_P_SYS_GRAVITY_MODIFIER_MEMBERS \
 NiNode * gravityObject; \
 Vector3 gravityAxis; \
@@ -974,9 +1009,6 @@ ForceType forceType; \
 float turbulence; \
 float turbulenceScale; \
 
-#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_MEMBERS \
-Ref<NiFloatData > unknownLink; \
-
 #define NI_P_SYS_GROW_FADE_MODIFIER_MEMBERS \
 float growTime; \
 unsigned short growGeneration; \
@@ -994,9 +1026,6 @@ Vector3 emissionAxis; \
 mutable unsigned int numMeshes; \
 vector<Ref<NiNode > > meshes; \
 
-#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_MEMBERS \
-unsigned int unknownInt; \
-
 #define NI_P_SYS_PLANAR_COLLIDER_MEMBERS \
 float width; \
 float height; \
@@ -1049,9 +1078,7 @@ float worldRadius; \
 mutable unsigned int proportionCount; \
 vector<float > proportionLevels; \
 
-#define NI_ROTATING_PARTICLES_MEMBERS \
-
-#define NI_ROTATING_PARTICLES_DATA_MEMBERS \
+#define NI_ROTATING_PARTICLES_MEMBERS \
 
 #define NI_SEQUENCE_STREAM_HELPER_MEMBERS \
 
@@ -1086,6 +1113,8 @@ vector< vector<OldSkinData > > boneData; \
 mutable unsigned int numSkinPartitionBlocks; \
 vector<SkinPartition > skinPartitionBlocks; \
 
+#define NI_TEXTURE_MEMBERS \
+
 #define NI_SOURCE_TEXTURE_MEMBERS \
 byte useExternal; \
 string fileName; \
@@ -1156,12 +1185,6 @@ unsigned short ps2L; \
 unsigned short ps2K; \
 unsigned short unknownShort; \
 
-#define NI_TEXTURE_TRANSFORM_CONTROLLER_MEMBERS \
-byte unknown2; \
-TexType textureSlot; \
-unsigned int operation; \
-Ref<NiFloatData > data; \
-
 #define NI_TEXTURE_MODE_PROPERTY_MEMBERS \
 short unknownShort; \
 array<2,short > unknown2Shorts; \
@@ -1214,17 +1237,8 @@ TexDesc decal3Texture; \
 mutable unsigned int numShaderTextures; \
 vector<ShaderTexDesc > shaderTextures; \
 
-#define NI_TRANSFORM_CONTROLLER_MEMBERS \
-
 #define NI_TRANSFORM_DATA_MEMBERS \
 
-#define NI_TRANSFORM_INTERPOLATOR_MEMBERS \
-Vector3 translation; \
-Quaternion rotation; \
-float scale; \
-array<3,byte > unknownBytes; \
-Ref<NiTransformData > data; \
-
 #define NI_TRI_SHAPE_MEMBERS \
 
 #define NI_TRI_SHAPE_DATA_MEMBERS \
@@ -1276,9 +1290,6 @@ unsigned int numBytes; \
 mutable unsigned short numVertices; \
 vector<float > weight; \
 
-#define NI_VIS_CONTROLLER_MEMBERS \
-Ref<NiVisData > data; \
-
 #define NI_VIS_DATA_MEMBERS \
 mutable unsigned int numVisKeys; \
 vector<Key<byte > > visKeys; \
@@ -1303,9 +1314,6 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_OBJECT_PARENT
 
 #define NI_OBJECT_CONSTRUCT 
-#define A_KEYED_DATA_PARENT NiObject
-
-#define A_KEYED_DATA_CONSTRUCT 
 #define A_PARTICLE_MODIFIER_PARENT NiObject
 
 #define A_PARTICLE_MODIFIER_CONSTRUCT  : nextModifier(NULL), controller(NULL)
@@ -1320,35 +1328,111 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define BHK_SERIALIZABLE_PARENT bhkRefObject
 
 #define BHK_SERIALIZABLE_CONSTRUCT 
-#define ABHK_CONSTRAINT_PARENT bhkSerializable
+#define BHK_WORLD_OBJECT_PARENT bhkSerializable
+
+#define BHK_WORLD_OBJECT_CONSTRUCT  : shape(NULL), layer((OblivionLayer)1), colFilter((byte)0), unknownShort((unsigned short)0)
+
+#define BHK_PHANTOM_PARENT bhkWorldObject
+
+#define BHK_PHANTOM_CONSTRUCT 
+#define BHK_SHAPE_PHANTOM_PARENT bhkPhantom
+
+#define BHK_SHAPE_PHANTOM_CONSTRUCT 
+#define BHK_SIMPLE_SHAPE_PHANTOM_PARENT bhkShapePhantom
+
+#define BHK_SIMPLE_SHAPE_PHANTOM_CONSTRUCT  : unknownFloat(0.0f)
+
+#define BHK_ENTITY_PARENT bhkWorldObject
+
+#define BHK_ENTITY_CONSTRUCT 
+#define BHK_RIGID_BODY_PARENT bhkEntity
+
+#define BHK_RIGID_BODY_CONSTRUCT  : layerCopy((OblivionLayer)1), colFilterCopy((byte)0), unknownFloat00(0.0f), unknownFloat01(0.0f), unknownFloat02(0.0f), unknownFloat03(0.0f), mass(0.0f), linearDamping(0.1f), angularDamping(0.1f), friction(0.3f), restitution(0.3f), maxLinearVelocity(250.0f), maxAngularVelocity(31.415926535f), penetrationDepth(0.15f), motionSystem((MotionSystem)7), unknownByte1((byte)1), unknownByte2((byte)1), qualityType((MotionQuality)1), unknownInt6((unsigned int)0), unknownInt7((unsigned int)0), unknownInt8((unsigned int)0), numConstraints((unsigned int)0)
+
+#define BHK_RIGID_BODY_T_PARENT bhkRigidBody
+
+#define BHK_RIGID_BODY_T_CONSTRUCT 
+#define BHK_CONSTRAINT_PARENT bhkSerializable
+
+#define BHK_CONSTRAINT_CONSTRUCT  : numEntities((unsigned int)0), priority((unsigned int)1)
+
+#define BHK_LIMITED_HINGE_CONSTRAINT_PARENT bhkConstraint
+
+#define BHK_LIMITED_HINGE_CONSTRAINT_CONSTRUCT 
+#define BHK_MALLEABLE_CONSTRAINT_PARENT bhkConstraint
+
+#define BHK_MALLEABLE_CONSTRAINT_CONSTRUCT  : type((unsigned int)0), unknownInt2((unsigned int)0), unknownLink1(NULL), unknownLink2(NULL), unknownInt3((unsigned int)0), tau(0.0f), damping(0.0f)
+
+#define BHK_STIFF_SPRING_CONSTRAINT_PARENT bhkConstraint
 
-#define ABHK_CONSTRAINT_CONSTRUCT  : numBodies((unsigned int)0), priority((unsigned int)1)
+#define BHK_STIFF_SPRING_CONSTRAINT_CONSTRUCT  : length(0.0f)
+
+#define BHK_RAGDOLL_CONSTRAINT_PARENT bhkConstraint
+
+#define BHK_RAGDOLL_CONSTRAINT_CONSTRUCT 
+#define BHK_PRISMATIC_CONSTRAINT_PARENT bhkConstraint
 
-#define ABHK_RAGDOLL_CONSTRAINT_PARENT AbhkConstraint
+#define BHK_PRISMATIC_CONSTRAINT_CONSTRUCT 
+#define BHK_HINGE_CONSTRAINT_PARENT bhkConstraint
 
-#define ABHK_RAGDOLL_CONSTRAINT_CONSTRUCT 
+#define BHK_HINGE_CONSTRAINT_CONSTRUCT 
 #define BHK_SHAPE_PARENT bhkSerializable
 
 #define BHK_SHAPE_CONSTRUCT 
-#define ABHK_SHAPE_COLLECTION_PARENT bhkShape
+#define BHK_TRANSFORM_SHAPE_PARENT bhkShape
+
+#define BHK_TRANSFORM_SHAPE_CONSTRUCT  : shape(NULL), unknownFloat1(0.0f)
 
-#define ABHK_SHAPE_COLLECTION_CONSTRUCT 
 #define BHK_SPHERE_REP_SHAPE_PARENT bhkShape
 
-#define BHK_SPHERE_REP_SHAPE_CONSTRUCT 
+#define BHK_SPHERE_REP_SHAPE_CONSTRUCT  : radius(0.0f)
+
 #define BHK_CONVEX_SHAPE_PARENT bhkSphereRepShape
 
 #define BHK_CONVEX_SHAPE_CONSTRUCT 
-#define BHK_WORLD_OBJECT_PARENT bhkShape
+#define BHK_SPHERE_SHAPE_PARENT bhkConvexShape
 
-#define BHK_WORLD_OBJECT_CONSTRUCT 
-#define BHK_ENTITY_PARENT bhkWorldObject
+#define BHK_SPHERE_SHAPE_CONSTRUCT 
+#define BHK_CAPSULE_SHAPE_PARENT bhkConvexShape
 
-#define BHK_ENTITY_CONSTRUCT  : shape(NULL), layer((OblivionLayer)1), colFilter((byte)0), unknownShort((unsigned short)0)
+#define BHK_CAPSULE_SHAPE_CONSTRUCT  : unknownShort1((unsigned short)0), unknownShort2((unsigned short)0), unknownShort3((unsigned short)0), unknownShort4((unsigned short)0), radius1(0.0f), radius2(0.0f)
 
-#define NI_COLLISION_OBJECT_PARENT NiObject
+#define BHK_BOX_SHAPE_PARENT bhkConvexShape
+
+#define BHK_BOX_SHAPE_CONSTRUCT  : unknownShort1((unsigned short)0), unknownShort2((unsigned short)0), unknownShort3((unsigned short)0), unknownShort4((unsigned short)0), min_Size(0.0f)
+
+#define BHK_CONVEX_VERTICES_SHAPE_PARENT bhkConvexShape
+
+#define BHK_CONVEX_VERTICES_SHAPE_CONSTRUCT  : numVertices((unsigned int)0), numNormals((unsigned int)0)
+
+#define BHK_CONVEX_TRANSFORM_SHAPE_PARENT bhkTransformShape
+
+#define BHK_CONVEX_TRANSFORM_SHAPE_CONSTRUCT 
+#define BHK_MULTI_SPHERE_SHAPE_PARENT bhkSphereRepShape
+
+#define BHK_MULTI_SPHERE_SHAPE_CONSTRUCT  : unknownFloat1(0.0f), unknownFloat2(0.0f), numSpheres((unsigned int)0)
+
+#define BHK_BV_TREE_SHAPE_PARENT bhkShape
+
+#define BHK_BV_TREE_SHAPE_CONSTRUCT 
+#define BHK_MOPP_BV_TREE_SHAPE_PARENT bhkBvTreeShape
+
+#define BHK_MOPP_BV_TREE_SHAPE_CONSTRUCT  : shape(NULL), unknownFloat(0.0f), moppDataSize((unsigned int)0), scalingFactor(0.0f)
+
+#define BHK_SHAPE_COLLECTION_PARENT bhkShape
 
-#define NI_COLLISION_OBJECT_CONSTRUCT  : parent(NULL), unknownShort((unsigned short)1), body(NULL)
+#define BHK_SHAPE_COLLECTION_CONSTRUCT 
+#define BHK_LIST_SHAPE_PARENT bhkShapeCollection
+
+#define BHK_LIST_SHAPE_CONSTRUCT  : numSubShapes((unsigned int)0), numUnknownInts((unsigned int)0)
+
+#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_PARENT bhkShapeCollection
+
+#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_CONSTRUCT  : numSubShapes((unsigned short)0), scale(1.0f), data(NULL)
+
+#define BHK_NI_TRI_STRIPS_SHAPE_PARENT bhkShapeCollection
+
+#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 NI_EXTRA_DATA_PARENT NiObject
 
@@ -1357,6 +1441,32 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_INTERPOLATOR_PARENT NiObject
 
 #define NI_INTERPOLATOR_CONSTRUCT 
+#define NI_KEY_BASED_INTERPOLATOR_PARENT NiInterpolator
+
+#define NI_KEY_BASED_INTERPOLATOR_CONSTRUCT 
+#define NI_FLOAT_INTERPOLATOR_PARENT NiKeyBasedInterpolator
+
+#define NI_FLOAT_INTERPOLATOR_CONSTRUCT  : floatValue(0.0f), data(NULL)
+
+#define NI_TRANSFORM_INTERPOLATOR_PARENT NiKeyBasedInterpolator
+
+#define NI_TRANSFORM_INTERPOLATOR_CONSTRUCT  : scale(0.0f), data(NULL)
+
+#define NI_POINT3_INTERPOLATOR_PARENT NiKeyBasedInterpolator
+
+#define NI_POINT3_INTERPOLATOR_CONSTRUCT  : data(NULL)
+
+#define NI_PATH_INTERPOLATOR_PARENT NiKeyBasedInterpolator
+
+#define NI_PATH_INTERPOLATOR_CONSTRUCT  : unknownShort((unsigned short)0), unknownInt((unsigned int)0), unknownFloat1(0.0f), unknownFloat2(0.0f), unknownShort2((unsigned short)0), posData(NULL), floatData(NULL)
+
+#define NI_BOOL_INTERPOLATOR_PARENT NiKeyBasedInterpolator
+
+#define NI_BOOL_INTERPOLATOR_CONSTRUCT  : boolValue(false), data(NULL)
+
+#define NI_BOOL_TIMELINE_INTERPOLATOR_PARENT NiBoolInterpolator
+
+#define NI_BOOL_TIMELINE_INTERPOLATOR_CONSTRUCT 
 #define NI_BLEND_INTERPOLATOR_PARENT NiInterpolator
 
 #define NI_BLEND_INTERPOLATOR_CONSTRUCT  : unknownShort((unsigned short)0), unknownInt((unsigned int)0)
@@ -1369,9 +1479,33 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_OBJECT_N_E_T_CONSTRUCT  : extraData(NULL), numExtraDataList((unsigned int)0), controller(NULL)
 
+#define NI_COLLISION_OBJECT_PARENT NiObject
+
+#define NI_COLLISION_OBJECT_CONSTRUCT  : target(NULL), unknownShort((unsigned short)1), body(NULL)
+
+#define NI_COLLISION_DATA_PARENT NiCollisionObject
+
+#define NI_COLLISION_DATA_CONSTRUCT  : unknownInt1((unsigned int)0), unknownInt2((unsigned int)0), unknownByte((byte)0), collisionType((unsigned int)0)
+
+#define BHK_NI_COLLISION_OBJECT_PARENT NiCollisionObject
+
+#define BHK_NI_COLLISION_OBJECT_CONSTRUCT 
+#define BHK_COLLISION_OBJECT_PARENT bhkNiCollisionObject
+
+#define BHK_COLLISION_OBJECT_CONSTRUCT 
+#define BHK_BLEND_COLLISION_OBJECT_PARENT bhkCollisionObject
+
+#define BHK_BLEND_COLLISION_OBJECT_CONSTRUCT  : unknownFloat1(0.0f), unknownFloat2(0.0f)
+
+#define BHK_P_COLLISION_OBJECT_PARENT bhkNiCollisionObject
+
+#define BHK_P_COLLISION_OBJECT_CONSTRUCT 
+#define BHK_S_P_COLLISION_OBJECT_PARENT bhkPCollisionObject
+
+#define BHK_S_P_COLLISION_OBJECT_CONSTRUCT 
 #define NI_A_V_OBJECT_PARENT NiObjectNET
 
-#define NI_A_V_OBJECT_CONSTRUCT  : flags((unsigned short)0), scale(1.0f), numProperties((unsigned int)0), hasBoundingBox(false), collisionData(NULL), collisionObject(NULL)
+#define NI_A_V_OBJECT_CONSTRUCT  : flags((unsigned short)0), scale(1.0f), numProperties((unsigned int)0), hasBoundingBox(false), collisionObject(NULL)
 
 #define NI_DYNAMIC_EFFECT_PARENT NiAVObject
 
@@ -1400,124 +1534,127 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_TIME_CONTROLLER_CONSTRUCT  : nextController(NULL), flags((unsigned short)0), frequency(0.0f), phase(0.0f), startTime(0.0f), stopTime(0.0f), target(NULL)
 
-#define A_BONE_L_O_D_CONTROLLER_PARENT NiTimeController
-
-#define A_BONE_L_O_D_CONTROLLER_CONSTRUCT  : unknownInt1((unsigned int)0), numNodeGroups((unsigned int)0), numNodeGroups2((unsigned int)0)
-
-#define NI_SINGLE_INTERPOLATOR_CONTROLLER_PARENT NiTimeController
+#define NI_INTERP_CONTROLLER_PARENT NiTimeController
 
-#define NI_SINGLE_INTERPOLATOR_CONTROLLER_CONSTRUCT  : interpolator(NULL)
+#define NI_INTERP_CONTROLLER_CONSTRUCT 
+#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_PARENT NiInterpController
 
-#define A_P_SYS_CTLR_PARENT NiSingleInterpolatorController
-
-#define A_P_SYS_CTLR_CONSTRUCT 
-#define NI_GEOMETRY_PARENT NiAVObject
+#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_CONSTRUCT  : numExtraTargets((unsigned short)0)
 
-#define NI_GEOMETRY_CONSTRUCT  : data(NULL), skinInstance(NULL), hasShader(false), unknownLink(NULL)
+#define NI_GEOM_MORPHER_CONTROLLER_PARENT NiInterpController
 
-#define NI_TRI_BASED_GEOM_PARENT NiGeometry
+#define NI_GEOM_MORPHER_CONTROLLER_CONSTRUCT  : unknown((unsigned short)0), unknown2((byte)0), data(NULL), unknownByte((byte)0), numInterpolators((unsigned int)0), numUnknownInts((unsigned int)0)
 
-#define NI_TRI_BASED_GEOM_CONSTRUCT 
-#define NI_GEOMETRY_DATA_PARENT NiObject
+#define NI_SINGLE_INTERP_CONTROLLER_PARENT NiInterpController
 
-#define NI_GEOMETRY_DATA_CONSTRUCT  : numVertices((unsigned short)0), unknownShort1((unsigned short)0), hasVertices(false), numUvSets2((byte)0), unknownByte((byte)0), hasNormals(false), radius(0.0f), hasVertexColors(false), numUvSets((unsigned short)0), hasUv(false), unknownShort2((unsigned short)0), unknownLink(NULL)
+#define NI_SINGLE_INTERP_CONTROLLER_CONSTRUCT  : interpolator(NULL)
 
-#define NI_TRI_BASED_GEOM_DATA_PARENT NiGeometryData
+#define NI_TRANSFORM_CONTROLLER_PARENT NiSingleInterpController
 
-#define NI_TRI_BASED_GEOM_DATA_CONSTRUCT  : numTriangles((unsigned short)0)
+#define NI_TRANSFORM_CONTROLLER_CONSTRUCT 
+#define NI_P_SYS_MODIFIER_CTLR_PARENT NiSingleInterpController
 
-#define A_P_SYS_DATA_PARENT NiGeometryData
+#define NI_P_SYS_MODIFIER_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_CTLR_PARENT NiPSysModifierCtlr
 
-#define A_P_SYS_DATA_CONSTRUCT  : hasUnknownFloats1(false), unknownShort3((unsigned short)0), hasUnknownFloats2(false), hasUnknownFloats3((byte)0)
+#define NI_P_SYS_EMITTER_CTLR_CONSTRUCT  : data(NULL), visibilityInterpolator(NULL)
 
-#define BHK_BLEND_COLLISION_OBJECT_PARENT NiCollisionObject
+#define NI_P_SYS_MODIFIER_BOOL_CTLR_PARENT NiPSysModifierCtlr
 
-#define BHK_BLEND_COLLISION_OBJECT_CONSTRUCT  : unknownFloat1(0.0f), unknownFloat2(0.0f)
+#define NI_P_SYS_MODIFIER_BOOL_CTLR_CONSTRUCT 
+#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_PARENT NiPSysModifierBoolCtlr
 
-#define BHK_BLEND_CONTROLLER_PARENT NiTimeController
+#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_CONSTRUCT  : data(NULL)
 
-#define BHK_BLEND_CONTROLLER_CONSTRUCT  : unknownInt((unsigned int)0)
+#define NI_P_SYS_MODIFIER_FLOAT_CTLR_PARENT NiPSysModifierCtlr
 
-#define BHK_BOX_SHAPE_PARENT bhkConvexShape
+#define NI_P_SYS_MODIFIER_FLOAT_CTLR_CONSTRUCT  : data(NULL)
 
-#define BHK_BOX_SHAPE_CONSTRUCT  : unknownFloat1(0.0f), unknownShort1((unsigned short)0), unknownShort2((unsigned short)0), unknownShort3((unsigned short)0), unknownShort4((unsigned short)0), min_Size(0.0f)
+#define NI_P_SYS_EMITTER_DECLINATION_CTLR_PARENT NiPSysModifierFloatCtlr
 
-#define BHK_CAPSULE_SHAPE_PARENT bhkConvexShape
+#define NI_P_SYS_EMITTER_DECLINATION_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_PARENT NiPSysModifierFloatCtlr
 
-#define BHK_CAPSULE_SHAPE_CONSTRUCT  : radius(0.0f), unknownShort1((unsigned short)0), unknownShort2((unsigned short)0), unknownShort3((unsigned short)0), unknownShort4((unsigned short)0), radius1(0.0f), radius2(0.0f)
+#define NI_P_SYS_EMITTER_DECLINATION_VAR_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_PARENT NiPSysModifierFloatCtlr
 
-#define BHK_COLLISION_OBJECT_PARENT NiCollisionObject
+#define NI_P_SYS_EMITTER_INITIAL_RADIUS_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_PARENT NiPSysModifierFloatCtlr
 
-#define BHK_COLLISION_OBJECT_CONSTRUCT 
-#define BHK_CONVEX_VERTICES_SHAPE_PARENT bhkSphereRepShape
+#define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_CONSTRUCT 
+#define NI_P_SYS_EMITTER_SPEED_CTLR_PARENT NiPSysModifierFloatCtlr
 
-#define BHK_CONVEX_VERTICES_SHAPE_CONSTRUCT  : numVertices((unsigned int)0), numNormals((unsigned int)0)
+#define NI_P_SYS_EMITTER_SPEED_CTLR_CONSTRUCT 
+#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_PARENT NiPSysModifierFloatCtlr
 
-#define BHK_HINGE_CONSTRAINT_PARENT AbhkConstraint
+#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_CONSTRUCT 
+#define NI_FLOAT_INTERP_CONTROLLER_PARENT NiSingleInterpController
 
-#define BHK_HINGE_CONSTRAINT_CONSTRUCT 
-#define BHK_LIMITED_HINGE_CONSTRAINT_PARENT AbhkConstraint
+#define NI_FLOAT_INTERP_CONTROLLER_CONSTRUCT 
+#define NI_FLIP_CONTROLLER_PARENT NiFloatInterpController
 
-#define BHK_LIMITED_HINGE_CONSTRAINT_CONSTRUCT 
-#define BHK_LIST_SHAPE_PARENT AbhkShapeCollection
+#define NI_FLIP_CONTROLLER_CONSTRUCT  : textureSlot((unsigned int)0), unknownInt2((unsigned int)0), delta(0.0f), numSources((unsigned int)0)
 
-#define BHK_LIST_SHAPE_CONSTRUCT  : numSubShapes((unsigned int)0), numUnknownInts((unsigned int)0)
+#define NI_ALPHA_CONTROLLER_PARENT NiFloatInterpController
 
-#define BHK_MALLEABLE_CONSTRAINT_PARENT AbhkConstraint
+#define NI_ALPHA_CONTROLLER_CONSTRUCT  : data(NULL)
 
-#define BHK_MALLEABLE_CONSTRAINT_CONSTRUCT  : type((unsigned int)0), unknownInt2((unsigned int)0), unknownLink1(NULL), unknownLink2(NULL), unknownInt3((unsigned int)0), tau(0.0f), damping(0.0f)
+#define NI_TEXTURE_TRANSFORM_CONTROLLER_PARENT NiFloatInterpController
 
-#define BHK_MOPP_BV_TREE_SHAPE_PARENT bhkShape
+#define NI_TEXTURE_TRANSFORM_CONTROLLER_CONSTRUCT  : unknown2((byte)0), operation((unsigned int)0), data(NULL)
 
-#define BHK_MOPP_BV_TREE_SHAPE_CONSTRUCT  : shape(NULL), unknownFloat(0.0f), moppDataSize((unsigned int)0), scalingFactor(0.0f)
+#define NI_LIGHT_DIMMER_CONTROLLER_PARENT NiFloatInterpController
 
-#define BHK_MULTI_SPHERE_SHAPE_PARENT bhkSphereRepShape
+#define NI_LIGHT_DIMMER_CONTROLLER_CONSTRUCT 
+#define NI_BOOL_INTERP_CONTROLLER_PARENT NiSingleInterpController
 
-#define BHK_MULTI_SPHERE_SHAPE_CONSTRUCT  : unknownFloat1(0.0f), unknownFloat2(0.0f), unknownFloat3(0.0f), numSpheres((unsigned int)0)
+#define NI_BOOL_INTERP_CONTROLLER_CONSTRUCT 
+#define NI_VIS_CONTROLLER_PARENT NiBoolInterpController
 
-#define BHK_NI_TRI_STRIPS_SHAPE_PARENT bhkSphereRepShape
+#define NI_VIS_CONTROLLER_CONSTRUCT  : data(NULL)
 
-#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 NI_POINT3_INTERP_CONTROLLER_PARENT NiSingleInterpController
 
-#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_PARENT AbhkShapeCollection
+#define NI_POINT3_INTERP_CONTROLLER_CONSTRUCT  : targetColor((unsigned short)0), data(NULL)
 
-#define BHK_PACKED_NI_TRI_STRIPS_SHAPE_CONSTRUCT  : numSubShapes((unsigned short)0), scale(1.0f), data(NULL)
+#define NI_MATERIAL_COLOR_CONTROLLER_PARENT NiPoint3InterpController
 
-#define BHK_PRISMATIC_CONSTRAINT_PARENT AbhkConstraint
+#define NI_MATERIAL_COLOR_CONTROLLER_CONSTRUCT 
+#define NI_LIGHT_COLOR_CONTROLLER_PARENT NiPoint3InterpController
 
-#define BHK_PRISMATIC_CONSTRAINT_CONSTRUCT 
-#define BHK_RAGDOLL_CONSTRAINT_PARENT AbhkRagdollConstraint
+#define NI_LIGHT_COLOR_CONTROLLER_CONSTRUCT 
+#define NI_EXTRA_DATA_CONTROLLER_PARENT NiSingleInterpController
 
-#define BHK_RAGDOLL_CONSTRAINT_CONSTRUCT 
-#define BHK_RIGID_BODY_PARENT bhkEntity
+#define NI_EXTRA_DATA_CONTROLLER_CONSTRUCT 
+#define NI_FLOAT_EXTRA_DATA_CONTROLLER_PARENT NiExtraDataController
 
-#define BHK_RIGID_BODY_CONSTRUCT  : layerCopy((OblivionLayer)1), colFilterCopy((byte)0), unknownFloat00(0.0f), unknownFloat01(0.0f), unknownFloat02(0.0f), unknownFloat03(0.0f), mass(0.0f), linearDamping(0.1f), angularDamping(0.1f), friction(0.3f), restitution(0.3f), maxLinearVelocity(250.0f), maxAngularVelocity(31.415926535f), penetrationDepth(0.15f), motionSystem((MotionSystem)7), unknownByte1((byte)1), unknownByte2((byte)1), qualityType((MotionQuality)1), unknownInt6((unsigned int)0), unknownInt7((unsigned int)0), unknownInt8((unsigned int)0), numConstraints((unsigned int)0)
+#define NI_FLOAT_EXTRA_DATA_CONTROLLER_CONSTRUCT 
+#define NI_BONE_L_O_D_CONTROLLER_PARENT NiTimeController
 
-#define BHK_RIGID_BODY_T_PARENT bhkRigidBody
+#define NI_BONE_L_O_D_CONTROLLER_CONSTRUCT  : unknownInt1((unsigned int)0), numNodeGroups((unsigned int)0), numNodeGroups2((unsigned int)0), numShapeGroups((unsigned int)0), numShapeGroups2((unsigned int)0)
 
-#define BHK_RIGID_BODY_T_CONSTRUCT 
-#define BHK_SIMPLE_SHAPE_PHANTOM_PARENT bhkEntity
+#define NI_B_S_BONE_L_O_D_CONTROLLER_PARENT NiBoneLODController
 
-#define BHK_SIMPLE_SHAPE_PHANTOM_CONSTRUCT  : unknownFloat(0.0f)
+#define NI_B_S_BONE_L_O_D_CONTROLLER_CONSTRUCT 
+#define NI_GEOMETRY_PARENT NiAVObject
 
-#define BHK_S_P_COLLISION_OBJECT_PARENT NiCollisionObject
+#define NI_GEOMETRY_CONSTRUCT  : data(NULL), skinInstance(NULL), hasShader(false), unknownLink(NULL)
 
-#define BHK_S_P_COLLISION_OBJECT_CONSTRUCT 
-#define BHK_SPHERE_SHAPE_PARENT bhkConvexShape
+#define NI_TRI_BASED_GEOM_PARENT NiGeometry
 
-#define BHK_SPHERE_SHAPE_CONSTRUCT  : radius(0.0f)
+#define NI_TRI_BASED_GEOM_CONSTRUCT 
+#define NI_GEOMETRY_DATA_PARENT NiObject
 
-#define BHK_STIFF_SPRING_CONSTRAINT_PARENT AbhkConstraint
+#define NI_GEOMETRY_DATA_CONSTRUCT  : numVertices((unsigned short)0), unknownShort1((unsigned short)0), hasVertices(false), numUvSets2((byte)0), unknownByte1((byte)0), hasNormals(false), radius(0.0f), hasVertexColors(false), numUvSets((unsigned short)0), hasUv(false), unknownShort2((unsigned short)0), unknownLink1(NULL)
 
-#define BHK_STIFF_SPRING_CONSTRAINT_CONSTRUCT  : length(0.0f)
+#define NI_TRI_BASED_GEOM_DATA_PARENT NiGeometryData
 
-#define BHK_TRANSFORM_SHAPE_PARENT bhkEntity
+#define NI_TRI_BASED_GEOM_DATA_CONSTRUCT  : numTriangles((unsigned short)0)
 
-#define BHK_TRANSFORM_SHAPE_CONSTRUCT  : unknownFloat1(0.0f), unknownFloat2(0.0f), unknownFloat3(0.0f)
+#define BHK_BLEND_CONTROLLER_PARENT NiTimeController
 
-#define BHK_CONVEX_TRANSFORM_SHAPE_PARENT bhkTransformShape
+#define BHK_BLEND_CONTROLLER_CONSTRUCT  : unknownInt((unsigned int)0)
 
-#define BHK_CONVEX_TRANSFORM_SHAPE_CONSTRUCT 
 #define B_S_BOUND_PARENT NiExtraData
 
 #define B_S_BOUND_CONSTRUCT 
@@ -1532,18 +1669,14 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define B_S_P_SYS_ARRAY_EMITTER_PARENT NiPSysVolumeEmitter
 
 #define B_S_P_SYS_ARRAY_EMITTER_CONSTRUCT 
-#define B_S_X_FLAGS_PARENT NiExtraData
+#define B_S_WIND_MODIFIER_PARENT NiPSysModifier
 
-#define B_S_X_FLAGS_CONSTRUCT  : flags((unsigned int)0)
+#define B_S_WIND_MODIFIER_CONSTRUCT  : unknownFloat(0.0f)
 
-#define HK_PACKED_NI_TRI_STRIPS_DATA_PARENT AbhkShapeCollection
+#define HK_PACKED_NI_TRI_STRIPS_DATA_PARENT bhkShapeCollection
 
 #define HK_PACKED_NI_TRI_STRIPS_DATA_CONSTRUCT  : numTriangles((unsigned int)0), numVertices((unsigned int)0)
 
-#define NI_ALPHA_CONTROLLER_PARENT NiSingleInterpolatorController
-
-#define NI_ALPHA_CONTROLLER_CONSTRUCT  : data(NULL)
-
 #define NI_ALPHA_PROPERTY_PARENT NiProperty
 
 #define NI_ALPHA_PROPERTY_CONSTRUCT  : flags((unsigned short)237), threshold((byte)0)
@@ -1551,9 +1684,24 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_AMBIENT_LIGHT_PARENT NiLight
 
 #define NI_AMBIENT_LIGHT_CONSTRUCT 
-#define NI_AUTO_NORMAL_PARTICLES_DATA_PARENT NiGeometryData
+#define NI_PARTICLES_DATA_PARENT NiGeometryData
+
+#define NI_PARTICLES_DATA_CONSTRUCT  : numParticles((unsigned short)0), size(0.0f), numActive((unsigned short)0), unknownShort((unsigned short)0), hasSizes(false), hasUnknownFloats1(false), hasRotations1(false)
+
+#define NI_ROTATING_PARTICLES_DATA_PARENT NiParticlesData
+
+#define NI_ROTATING_PARTICLES_DATA_CONSTRUCT  : hasRotations2(false)
+
+#define NI_AUTO_NORMAL_PARTICLES_DATA_PARENT NiParticlesData
+
+#define NI_AUTO_NORMAL_PARTICLES_DATA_CONSTRUCT 
+#define NI_P_SYS_DATA_PARENT NiRotatingParticlesData
+
+#define NI_P_SYS_DATA_CONSTRUCT  : hasUnknownFloats3(false), hasUnknownFloats4(false), hasUnknownFloats6(false), unknownInt1((unsigned int)0)
 
-#define NI_AUTO_NORMAL_PARTICLES_DATA_CONSTRUCT  : numParticles((unsigned short)0), size(0.0f), numActive((unsigned short)0), unknownShort((unsigned short)0), hasSizes(false)
+#define NI_MESH_P_SYS_DATA_PARENT NiPSysData
+
+#define NI_MESH_P_SYS_DATA_CONSTRUCT  : modifier(NULL), unknownByte2((byte)0), numUnknownLinks((unsigned int)0), numVertices2((unsigned int)0), unknownByte3((byte)0), unknownInt2((unsigned int)1), numVertices3((unsigned int)0), unknownLink2(NULL)
 
 #define NI_BINARY_EXTRA_DATA_PARENT NiExtraData
 
@@ -1580,39 +1728,33 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_BLEND_TRANSFORM_INTERPOLATOR_PARENT NiBlendInterpolator
 
 #define NI_BLEND_TRANSFORM_INTERPOLATOR_CONSTRUCT 
-#define NI_BONE_L_O_D_CONTROLLER_PARENT ABoneLODController
-
-#define NI_BONE_L_O_D_CONTROLLER_CONSTRUCT  : numShapeGroups((unsigned int)0), numShapeGroups2((unsigned int)0)
-
-#define NI_BOOL_DATA_PARENT AKeyedData
+#define NI_BOOL_DATA_PARENT NiObject
 
 #define NI_BOOL_DATA_CONSTRUCT 
 #define NI_BOOLEAN_EXTRA_DATA_PARENT NiExtraData
 
 #define NI_BOOLEAN_EXTRA_DATA_CONSTRUCT  : booleanData((byte)0)
 
-#define NI_BOOL_INTERPOLATOR_PARENT NiInterpolator
-
-#define NI_BOOL_INTERPOLATOR_CONSTRUCT  : boolValue(false), data(NULL)
-
-#define NI_BOOL_TIMELINE_INTERPOLATOR_PARENT NiInterpolator
-
-#define NI_BOOL_TIMELINE_INTERPOLATOR_CONSTRUCT  : boolValue((byte)0), data(NULL)
-
-#define NI_B_S_BONE_L_O_D_CONTROLLER_PARENT ABoneLODController
-
-#define NI_B_S_BONE_L_O_D_CONTROLLER_CONSTRUCT 
 #define NI_B_SPLINE_BASIS_DATA_PARENT NiObject
 
 #define NI_B_SPLINE_BASIS_DATA_CONSTRUCT  : numControlPt((unsigned int)0)
 
-#define NI_B_SPLINE_COMP_FLOAT_INTERPOLATOR_PARENT NiBSplineInterpolator
+#define NI_B_SPLINE_FLOAT_INTERPOLATOR_PARENT NiBSplineInterpolator
+
+#define NI_B_SPLINE_FLOAT_INTERPOLATOR_CONSTRUCT 
+#define NI_B_SPLINE_COMP_FLOAT_INTERPOLATOR_PARENT NiBSplineFloatInterpolator
 
 #define NI_B_SPLINE_COMP_FLOAT_INTERPOLATOR_CONSTRUCT 
-#define NI_B_SPLINE_COMP_POINT3_INTERPOLATOR_PARENT NiBSplineInterpolator
+#define NI_B_SPLINE_POINT3_INTERPOLATOR_PARENT NiBSplineInterpolator
+
+#define NI_B_SPLINE_POINT3_INTERPOLATOR_CONSTRUCT 
+#define NI_B_SPLINE_COMP_POINT3_INTERPOLATOR_PARENT NiBSplinePoint3Interpolator
 
 #define NI_B_SPLINE_COMP_POINT3_INTERPOLATOR_CONSTRUCT 
-#define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_PARENT NiBSplineInterpolator
+#define NI_B_SPLINE_TRANSFORM_INTERPOLATOR_PARENT NiBSplineInterpolator
+
+#define NI_B_SPLINE_TRANSFORM_INTERPOLATOR_CONSTRUCT 
+#define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_PARENT NiBSplineTransformInterpolator
 
 #define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_CONSTRUCT  : scale(0.0f), translateOffset((unsigned int)0), rotateOffset((unsigned int)0), scaleOffset((unsigned int)0), translateBias(0.0f), translateMultiplier(0.0f), rotationBias(0.0f), rotationMultiplier(0.0f), scaleBias(0.0f), scaleMultiplier(0.0f)
 
@@ -1624,11 +1766,7 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_CAMERA_CONSTRUCT  : unknownShort((unsigned short)0), frustumLeft(0.0f), frustumRight(0.0f), frustumTop(0.0f), frustumBottom(0.0f), frustumNear(0.0f), frustumFar(0.0f), useOrthographicProjection(false), viewportLeft(0.0f), viewportRight(0.0f), viewportTop(0.0f), viewportBottom(0.0f), lodAdjust(0.0f), unknownLink_(NULL), unknownInt((unsigned int)0), unknownInt2((unsigned int)0), unknownInt3((unsigned int)0)
 
-#define NI_COLLISION_DATA_PARENT NiObject
-
-#define NI_COLLISION_DATA_CONSTRUCT  : targetNode(NULL), unknownInt1((unsigned int)0), unknownInt2((unsigned int)0), unknownByte((byte)0), collisionType((unsigned int)0)
-
-#define NI_COLOR_DATA_PARENT AKeyedData
+#define NI_COLOR_DATA_PARENT NiObject
 
 #define NI_COLOR_DATA_CONSTRUCT 
 #define NI_COLOR_EXTRA_DATA_PARENT NiExtraData
@@ -1646,7 +1784,10 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_CONTROLLER_SEQUENCE_CONSTRUCT  : weight(1.0f), textKeys(NULL), unknownInt0((unsigned int)0), frequency(0.0f), startTime(0.0f), stopTime(0.0f), unknownFloat2(0.0f), unknownByte((byte)0), manager(NULL), stringPalette(NULL)
 
-#define NI_DEFAULT_A_V_OBJECT_PALETTE_PARENT NiObject
+#define NI_A_V_OBJECT_PALETTE_PARENT NiObject
+
+#define NI_A_V_OBJECT_PALETTE_CONSTRUCT 
+#define NI_DEFAULT_A_V_OBJECT_PALETTE_PARENT NiAVObjectPalette
 
 #define NI_DEFAULT_A_V_OBJECT_PALETTE_CONSTRUCT  : unknownInt((unsigned int)0), numObjs((unsigned int)0)
 
@@ -1657,29 +1798,17 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_DITHER_PROPERTY_CONSTRUCT  : flags((unsigned short)0)
 
-#define NI_FLIP_CONTROLLER_PARENT NiSingleInterpolatorController
-
-#define NI_FLIP_CONTROLLER_CONSTRUCT  : textureSlot((unsigned int)0), unknownInt2((unsigned int)0), delta(0.0f), numSources((unsigned int)0)
-
-#define NI_ROLL_CONTROLLER_PARENT NiSingleInterpolatorController
+#define NI_ROLL_CONTROLLER_PARENT NiSingleInterpController
 
 #define NI_ROLL_CONTROLLER_CONSTRUCT  : data(NULL)
 
-#define NI_FLOAT_DATA_PARENT AKeyedData
+#define NI_FLOAT_DATA_PARENT NiObject
 
 #define NI_FLOAT_DATA_CONSTRUCT 
 #define NI_FLOAT_EXTRA_DATA_PARENT NiExtraData
 
 #define NI_FLOAT_EXTRA_DATA_CONSTRUCT  : floatData(0.0f)
 
-#define NI_FLOAT_EXTRA_DATA_CONTROLLER_PARENT NiTimeController
-
-#define NI_FLOAT_EXTRA_DATA_CONTROLLER_CONSTRUCT  : unknownLink(NULL)
-
-#define NI_FLOAT_INTERPOLATOR_PARENT NiInterpolator
-
-#define NI_FLOAT_INTERPOLATOR_CONSTRUCT  : floatValue(0.0f), data(NULL)
-
 #define NI_FLOATS_EXTRA_DATA_PARENT NiExtraData
 
 #define NI_FLOATS_EXTRA_DATA_CONSTRUCT  : numFloats((unsigned int)0)
@@ -1688,10 +1817,6 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_FOG_PROPERTY_CONSTRUCT  : flags((unsigned short)0), fogDepth(0.0f)
 
-#define NI_GEOM_MORPHER_CONTROLLER_PARENT NiTimeController
-
-#define NI_GEOM_MORPHER_CONTROLLER_CONSTRUCT  : unknown((unsigned short)0), unknown2((byte)0), data(NULL), unknownByte((byte)0), numInterpolators((unsigned int)0), numUnknownInts((unsigned int)0)
-
 #define NI_GRAVITY_PARENT AParticleModifier
 
 #define NI_GRAVITY_CONSTRUCT  : unknownFloat1(0.0f), force(0.0f)
@@ -1700,6 +1825,9 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_INTEGER_EXTRA_DATA_CONSTRUCT  : integerData((unsigned int)0)
 
+#define B_S_X_FLAGS_PARENT NiIntegerExtraData
+
+#define B_S_X_FLAGS_CONSTRUCT 
 #define NI_INTEGERS_EXTRA_DATA_PARENT NiExtraData
 
 #define NI_INTEGERS_EXTRA_DATA_CONSTRUCT  : numIntegers((unsigned int)0)
@@ -1712,18 +1840,10 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define B_S_KEYFRAME_CONTROLLER_CONSTRUCT  : data2(NULL)
 
-#define NI_KEYFRAME_DATA_PARENT AKeyedData
+#define NI_KEYFRAME_DATA_PARENT NiObject
 
 #define NI_KEYFRAME_DATA_CONSTRUCT  : numRotationKeys((unsigned int)0), rotationType((KeyType)0), unknownFloat(0.0f)
 
-#define NI_LIGHT_COLOR_CONTROLLER_PARENT NiTimeController
-
-#define NI_LIGHT_COLOR_CONTROLLER_CONSTRUCT  : unknownShort((unsigned short)0), data(NULL), interpolator(NULL)
-
-#define NI_LIGHT_DIMMER_CONTROLLER_PARENT NiTimeController
-
-#define NI_LIGHT_DIMMER_CONTROLLER_CONSTRUCT  : unknownLink(NULL)
-
 #define NI_LOOK_AT_CONTROLLER_PARENT NiTimeController
 
 #define NI_LOOK_AT_CONTROLLER_CONSTRUCT  : unknown1((unsigned short)0), lookAtNode(NULL)
@@ -1732,26 +1852,14 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_LOOK_AT_INTERPOLATOR_CONSTRUCT  : unknownShort((unsigned short)0), lookAt(NULL), unknownFloat(0.0f), scale(0.0f), unknownLink1(NULL), unknownLink2(NULL), unknownLink3(NULL)
 
-#define NI_MATERIAL_COLOR_CONTROLLER_PARENT NiSingleInterpolatorController
-
-#define NI_MATERIAL_COLOR_CONTROLLER_CONSTRUCT  : targetColor((unsigned short)0), data(NULL)
-
 #define NI_MATERIAL_PROPERTY_PARENT NiProperty
 
 #define NI_MATERIAL_PROPERTY_CONSTRUCT  : flags((unsigned short)0), glossiness(0.0f), alpha(0.0f)
 
-#define NI_MESH_P_SYS_DATA_PARENT APSysData
-
-#define NI_MESH_P_SYS_DATA_CONSTRUCT  : unknownByte11((byte)0), unknownInt1((unsigned int)0), modifier(NULL), unknownByte2((byte)0), numUnknownLinks((unsigned int)0), unknownShort4((unsigned short)0), unknownInt2((unsigned int)0), unknownByte12((byte)0), unknownInt3((unsigned int)0), unknownInt4((unsigned int)0), unknownLink2(NULL)
-
 #define NI_MORPH_DATA_PARENT NiObject
 
 #define NI_MORPH_DATA_CONSTRUCT  : numMorphs((unsigned int)0), numVertices((unsigned int)0), unknownByte((byte)0)
 
-#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_PARENT NiTimeController
-
-#define NI_MULTI_TARGET_TRANSFORM_CONTROLLER_CONSTRUCT  : numExtraTargets((unsigned short)0)
-
 #define NI_NODE_PARENT NiAVObject
 
 #define NI_NODE_CONSTRUCT  : numChildren((unsigned int)0), numEffects((unsigned int)0)
@@ -1782,7 +1890,10 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_B_S_PARTICLE_NODE_PARENT NiNode
 
 #define NI_B_S_PARTICLE_NODE_CONSTRUCT 
-#define NI_L_O_D_NODE_PARENT NiNode
+#define NI_SWITCH_NODE_PARENT NiNode
+
+#define NI_SWITCH_NODE_CONSTRUCT 
+#define NI_L_O_D_NODE_PARENT NiSwitchNode
 
 #define NI_L_O_D_NODE_CONSTRUCT  : numLodLevels((unsigned int)0), unknownShort((unsigned short)0), lodLevelData(NULL)
 
@@ -1819,11 +1930,7 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_PARTICLE_MESHES_PARENT NiParticles
 
 #define NI_PARTICLE_MESHES_CONSTRUCT 
-#define NI_PARTICLES_DATA_PARENT NiAutoNormalParticlesData
-
-#define NI_PARTICLES_DATA_CONSTRUCT  : numActive((unsigned short)0), hasUnknownFloats(false), hasRotations(false)
-
-#define NI_PARTICLE_MESHES_DATA_PARENT NiParticlesData
+#define NI_PARTICLE_MESHES_DATA_PARENT NiRotatingParticlesData
 
 #define NI_PARTICLE_MESHES_DATA_CONSTRUCT  : unknownLink2(NULL)
 
@@ -1845,10 +1952,6 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_PATH_CONTROLLER_CONSTRUCT  : unknownShort2((unsigned short)0), unknownInt1((unsigned int)0), unknownInt2((unsigned int)0), unknownInt3((unsigned int)0), unknownShort((unsigned short)0), posData(NULL), floatData(NULL)
 
-#define NI_PATH_INTERPOLATOR_PARENT NiBlendInterpolator
-
-#define NI_PATH_INTERPOLATOR_CONSTRUCT  : unknownFloat1(0.0f), unknownFloat2(0.0f), unknownShort2((unsigned short)0), posData(NULL), floatData(NULL)
-
 #define NI_PIXEL_DATA_PARENT NiObject
 
 #define NI_PIXEL_DATA_CONSTRUCT  : redMask((unsigned int)0), greenMask((unsigned int)0), blueMask((unsigned int)0), alphaMask((unsigned int)0), bitsPerPixel((unsigned int)0), unknownInt((unsigned int)0), palette(NULL), numMipmaps((unsigned int)0), bytesPerPixel((unsigned int)0), unknownInt2((unsigned int)0)
@@ -1857,15 +1960,11 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_PLANAR_COLLIDER_CONSTRUCT  : unknownShort((unsigned short)0), unknownFloat1(0.0f), unknownFloat2(0.0f), unknownShort2((unsigned short)0), unknownFloat3(0.0f), unknownFloat4(0.0f), unknownFloat5(0.0f), unknownFloat6(0.0f), unknownFloat7(0.0f), unknownFloat8(0.0f), unknownFloat9(0.0f), unknownFloat10(0.0f), unknownFloat11(0.0f), unknownFloat12(0.0f), unknownFloat13(0.0f), unknownFloat14(0.0f), unknownFloat15(0.0f), unknownFloat16(0.0f)
 
-#define NI_POINT3_INTERPOLATOR_PARENT NiInterpolator
-
-#define NI_POINT3_INTERPOLATOR_CONSTRUCT  : data(NULL)
-
 #define NI_POINT_LIGHT_PARENT NiLight
 
 #define NI_POINT_LIGHT_CONSTRUCT  : constantAttenuation(0.0f), linearAttenuation(0.0f), quadraticAttenuation(0.0f)
 
-#define NI_POS_DATA_PARENT AKeyedData
+#define NI_POS_DATA_PARENT NiObject
 
 #define NI_POS_DATA_CONSTRUCT 
 #define NI_P_SYS_AGE_DEATH_MODIFIER_PARENT NiPSysModifier
@@ -1896,49 +1995,18 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_P_SYS_CYLINDER_EMITTER_CONSTRUCT  : radius(0.0f), height(0.0f)
 
-#define NI_P_SYS_DATA_PARENT APSysData
-
-#define NI_P_SYS_DATA_CONSTRUCT  : unknownBool1(false), unknownByte3((byte)0), unknownBool2(false), unknownInt1((unsigned int)0)
-
 #define NI_P_SYS_DRAG_MODIFIER_PARENT NiPSysModifier
 
 #define NI_P_SYS_DRAG_MODIFIER_CONSTRUCT  : parent(NULL), percentage(0.0f), range(0.0f), rangeFalloff(0.0f)
 
-#define NI_P_SYS_EMITTER_CTLR_PARENT APSysCtlr
-
-#define NI_P_SYS_EMITTER_CTLR_CONSTRUCT  : data(NULL), visibilityInterpolator(NULL)
-
 #define NI_P_SYS_EMITTER_CTLR_DATA_PARENT NiObject
 
 #define NI_P_SYS_EMITTER_CTLR_DATA_CONSTRUCT  : numVisibilityKeys_((unsigned int)0)
 
-#define NI_P_SYS_EMITTER_DECLINATION_CTLR_PARENT APSysCtlr
-
-#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  : data(NULL)
-
-#define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_PARENT APSysCtlr
-
-#define NI_P_SYS_EMITTER_LIFE_SPAN_CTLR_CONSTRUCT  : unknownLink(NULL)
-
-#define NI_P_SYS_EMITTER_SPEED_CTLR_PARENT APSysCtlr
-
-#define NI_P_SYS_EMITTER_SPEED_CTLR_CONSTRUCT  : unknownLink(NULL)
-
 #define NI_P_SYS_GRAVITY_MODIFIER_PARENT NiPSysModifier
 
 #define NI_P_SYS_GRAVITY_MODIFIER_CONSTRUCT  : gravityObject(NULL), decay(0.0f), strength(0.0f), turbulence(0.0f), turbulenceScale(1.0f)
 
-#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_PARENT APSysCtlr
-
-#define NI_P_SYS_GRAVITY_STRENGTH_CTLR_CONSTRUCT  : unknownLink(NULL)
-
 #define NI_P_SYS_GROW_FADE_MODIFIER_PARENT NiPSysModifier
 
 #define NI_P_SYS_GROW_FADE_MODIFIER_CONSTRUCT  : growTime(0.0f), growGeneration((unsigned short)0), fadeTime(0.0f), fadeGeneration((unsigned short)0)
@@ -1951,10 +2019,6 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_P_SYS_MESH_UPDATE_MODIFIER_CONSTRUCT  : numMeshes((unsigned int)0)
 
-#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_PARENT APSysCtlr
-
-#define NI_P_SYS_MODIFIER_ACTIVE_CTLR_CONSTRUCT  : unknownInt((unsigned int)0)
-
 #define NI_P_SYS_PLANAR_COLLIDER_PARENT NiPSysCollider
 
 #define NI_P_SYS_PLANAR_COLLIDER_CONSTRUCT  : width(0.0f), height(0.0f)
@@ -1998,9 +2062,6 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 #define NI_ROTATING_PARTICLES_PARENT NiParticles
 
 #define NI_ROTATING_PARTICLES_CONSTRUCT 
-#define NI_ROTATING_PARTICLES_DATA_PARENT NiParticlesData
-
-#define NI_ROTATING_PARTICLES_DATA_CONSTRUCT 
 #define NI_SEQUENCE_STREAM_HELPER_PARENT NiObjectNET
 
 #define NI_SEQUENCE_STREAM_HELPER_CONSTRUCT 
@@ -2027,7 +2088,10 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_SKIN_PARTITION_CONSTRUCT  : numSkinPartitionBlocks((unsigned int)0)
 
-#define NI_SOURCE_TEXTURE_PARENT NiObjectNET
+#define NI_TEXTURE_PARENT NiObjectNET
+
+#define NI_TEXTURE_CONSTRUCT 
+#define NI_SOURCE_TEXTURE_PARENT NiTexture
 
 #define NI_SOURCE_TEXTURE_CONSTRUCT  : useExternal((byte)1), unknownLink(NULL), unknownByte((byte)0), pixelData(NULL), pixelLayout((PixelLayout)5), useMipmaps((MipMapFormat)2), alphaFormat((AlphaFormat)3), unknownByte2((byte)1)
 
@@ -2066,10 +2130,6 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_TEXTURE_EFFECT_CONSTRUCT  : textureType((unsigned int)0), coordinateGenerationType((unsigned int)0), sourceTexture(NULL), clippingPlane((byte)0), unknownFloat(0.0f), ps2L((unsigned short)0), ps2K((unsigned short)0), unknownShort((unsigned short)0)
 
-#define NI_TEXTURE_TRANSFORM_CONTROLLER_PARENT NiSingleInterpolatorController
-
-#define NI_TEXTURE_TRANSFORM_CONTROLLER_CONSTRUCT  : unknown2((byte)0), operation((unsigned int)0), data(NULL)
-
 #define NI_TEXTURE_MODE_PROPERTY_PARENT NiProperty
 
 #define NI_TEXTURE_MODE_PROPERTY_CONSTRUCT  : unknownShort((short)0)
@@ -2090,16 +2150,9 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_TEXTURING_PROPERTY_CONSTRUCT  : flags((unsigned short)0), applyMode((ApplyMode)2), textureCount((unsigned int)7), hasBaseTexture(false), hasDarkTexture(false), hasDetailTexture(false), hasGlossTexture(false), hasGlowTexture(false), hasBumpMapTexture(false), bumpMapLumaScale(0.0f), bumpMapLumaOffset(0.0f), hasDecal0Texture(false), hasDecal1Texture(false), hasDecal2Texture(false), hasDecal3Texture(false), numShaderTextures((unsigned int)0)
 
-#define NI_TRANSFORM_CONTROLLER_PARENT NiSingleInterpolatorController
-
-#define NI_TRANSFORM_CONTROLLER_CONSTRUCT 
 #define NI_TRANSFORM_DATA_PARENT NiKeyframeData
 
 #define NI_TRANSFORM_DATA_CONSTRUCT 
-#define NI_TRANSFORM_INTERPOLATOR_PARENT NiInterpolator
-
-#define NI_TRANSFORM_INTERPOLATOR_CONSTRUCT  : scale(0.0f), data(NULL)
-
 #define NI_TRI_SHAPE_PARENT NiTriBasedGeom
 
 #define NI_TRI_SHAPE_CONSTRUCT 
@@ -2140,11 +2193,7 @@ vector< vector<ByteColor4 > > rgbaImageData; \
 
 #define NI_VERT_WEIGHTS_EXTRA_DATA_CONSTRUCT  : numBytes((unsigned int)0), numVertices((unsigned short)0)
 
-#define NI_VIS_CONTROLLER_PARENT NiSingleInterpolatorController
-
-#define NI_VIS_CONTROLLER_CONSTRUCT  : data(NULL)
-
-#define NI_VIS_DATA_PARENT AKeyedData
+#define NI_VIS_DATA_PARENT NiObject
 
 #define NI_VIS_DATA_CONSTRUCT  : numVisKeys((unsigned int)0)
 
diff --git a/include/obj/ABoneLODController.h b/include/obj/ABoneLODController.h
deleted file mode 100644
index 271b2c4e..00000000
--- a/include/obj/ABoneLODController.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright (c) 2006, NIF File Format Library and Tools
-All rights reserved.  Please see niflib.h for license. */
-
-#ifndef _ABONELODCONTROLLER_H_
-#define _ABONELODCONTROLLER_H_
-
-#include "NiTimeController.h"
-
-// Include structures
-#include "../gen/NodeGroup.h"
-namespace Niflib {
-
-
-//#include "../gen/obj_defines.h"
-
-class ABoneLODController;
-typedef Ref<ABoneLODController> ABoneLODControllerRef;
-
-/*!
- * ABoneLODController - Level of detail controller for bones?
- */
-
-class ABoneLODController : public A_BONE_L_O_D_CONTROLLER_PARENT {
-public:
-	NIFLIB_API ABoneLODController();
-	NIFLIB_API ~ABoneLODController();
-	//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;
-
-	/*!
-	 * Returns the number of node groups (each group a sequence of bones).
-	 * \return The number of node groups.
-	 */
-	NIFLIB_API int GetNodeGroupCount() const;
-
-	/*!
-	 * Returns a specific node group (each group a sequence of bones).
-	 * \param[in] index The index of the node group to return the data for.  This must be >= 0 and < the result of ABoneLODController::GetNodeGroupCount.
-	 * \return The specified node group.
-	 */
-	NIFLIB_API vector<Ref<NiNode> > GetNodeGroup( int index ) const;
-
-	/*!
-	 * Adds a single node to the specified group. The group list will expand if necessary.
-	 * \param[in] index The index of the node group to add a node to.  This must be >= 0 and < the result of ABoneLODController::GetNodeGroupCount.
-	 * \param[in] node The node to add to the group.
-	 */
-	NIFLIB_API void AddNodeToGroup( int index, NiNode * node );
-
-	/*!
-	 * Remove a single node from the specified node group. 
-	 * \param[in] index The index of the node group to remove a node from.  This must be >= 0 and < the result of ABoneLODController::GetNodeGroupCount.
-	 * \param[in] node The node remove from the group.
-	 */
-	NIFLIB_API void RemoveNodeFromGroup( int index, NiNode * node );
-
-	/*!
-	 * Assigns an entire node group, replacing any nodes that were in the group before.
-	 * \param[in] index The index of the node group to assign a list of nodes to.  This must be >= 0 and < the result of ABoneLODController::GetNodeGroupCount.
-	 * \param[in] group The list of nodes to assign to the specified node group.
-	 */
-	NIFLIB_API void SetNodeGroup( int index, const vector<Ref<NiNode> > & group );
-
-
-	/*!
-	 * Removes an entire node group.  This will cause the indices of any subsequent node groups to shift.
-	 * \param[in] index The index of the node group to remove.  This must be >= 0 and < the result of ABoneLODController::GetNodeGroupCount.
-	 */
-	NIFLIB_API void RemoveNodeGroup( int index );
-
-	/*!
-	 * Clears all node groups.
-	 */
-	NIFLIB_API void ClearNodeGroups();
-
-protected:
-	A_BONE_L_O_D_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/include/obj/APSysData.h b/include/obj/BSWindModifier.h
similarity index 78%
rename from include/obj/APSysData.h
rename to include/obj/BSWindModifier.h
index 4e1ebe37..bec530c9 100644
--- a/include/obj/APSysData.h
+++ b/include/obj/BSWindModifier.h
@@ -1,25 +1,23 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _APSYSDATA_H_
-#define _APSYSDATA_H_
+#ifndef _BSWINDMODIFIER_H_
+#define _BSWINDMODIFIER_H_
 
-#include "NiTriBasedGeomData.h"
+#include "NiPSysModifier.h"
 namespace Niflib {
 
-//#include "../gen/obj_defines.h"
-
-class APSysData;
-typedef Ref<APSysData> APSysDataRef;
+class BSWindModifier;
+typedef Ref<BSWindModifier> BSWindModifierRef;
 
 /*!
- * APSysData - Particle system data.  Probably really NiPSysData.
+ * BSWindModifier - Unknown.
  */
 
-class APSysData : public A_P_SYS_DATA_PARENT {
+class BSWindModifier : public B_S_WIND_MODIFIER_PARENT {
 public:
-	NIFLIB_API APSysData();
-	NIFLIB_API ~APSysData();
+	NIFLIB_API BSWindModifier();
+	NIFLIB_API ~BSWindModifier();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -31,7 +29,7 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 protected:
-	A_P_SYS_DATA_MEMBERS
+	B_S_WIND_MODIFIER_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/BSXFlags.h b/include/obj/BSXFlags.h
index 1c41015c..dc3d7659 100644
--- a/include/obj/BSXFlags.h
+++ b/include/obj/BSXFlags.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BSXFLAGS_H_
 #define _BSXFLAGS_H_
 
-#include "NiExtraData.h"
+#include "NiIntegerExtraData.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
@@ -30,18 +30,6 @@ public:
 	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;
 
-	/*!
-	 * Gets the BSX Flag data.
-	 * \return The flag data.
-	 */
-	NIFLIB_API unsigned int GetFlags() const;
-
-	/*!
-	 * Sets the BSX Flag data.
-	 * \param[in] value The new flag data.
-	 */
-	NIFLIB_API void SetFlags( unsigned int value );
-
 protected:
 	B_S_X_FLAGS_MEMBERS
 private:
diff --git a/include/obj/NiAVObject.h b/include/obj/NiAVObject.h
index 57beaef6..c6926d7d 100644
--- a/include/obj/NiAVObject.h
+++ b/include/obj/NiAVObject.h
@@ -194,29 +194,17 @@ public:
 	NIFLIB_API void SetVisibility( bool n );
 
 	/*!
-	 * Gets the current collision object for this object.  Used in later NIF versions.  In Oblivion this links to the Havok objects.
+	 * Gets the current collision object for this object.  Usually a bounding box.  In Oblivion this links to the Havok objects.
 	 * \return The current collision object for this object.
 	 */
 	NIFLIB_API Ref<NiCollisionObject > GetCollisionObject() const;
 
 	/*!
-	 * Sets the collision object for this object.  Used in later NIF versions.  In Oblivion this links to the Havok objects.
+	 * Sets the collision object for this object.  Usually a bounding box.  In Oblivion this links to the Havok objects.
 	 * \param[in] value The new collision object to use.
 	 */
 	NIFLIB_API void SetCollisionObject( NiCollisionObject * value );
 
-	/*!
-	 * Gets the current collision data for this object.  Usually a bounding box.  Used in some NIF versions.
-	 * \return The current collision data for this object.
-	 */
-	NIFLIB_API Ref<NiCollisionData > GetCollisionData() const;
-
-	/*!
-	 * Sets the collision data for this object.  Usually a bounding box.  Used in some NIF versions.
-	 * \param[in] value The new collision data for this object.
-	 */
-	NIFLIB_API void SetCollisionData( NiCollisionData * value );
-
 	/*!
 	 * Used to get and set the collision type of a NiAVObject.
 	 */
diff --git a/include/obj/AKeyedData.h b/include/obj/NiAVObjectPalette.h
similarity index 79%
rename from include/obj/AKeyedData.h
rename to include/obj/NiAVObjectPalette.h
index ba564fd9..bf9c08d0 100644
--- a/include/obj/AKeyedData.h
+++ b/include/obj/NiAVObjectPalette.h
@@ -1,25 +1,23 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _AKEYEDDATA_H_
-#define _AKEYEDDATA_H_
+#ifndef _NIAVOBJECTPALETTE_H_
+#define _NIAVOBJECTPALETTE_H_
 
 #include "NiObject.h"
 namespace Niflib {
 
-//#include "../gen/obj_defines.h"
-
-class AKeyedData;
-typedef Ref<AKeyedData> AKeyedDataRef;
+class NiAVObjectPalette;
+typedef Ref<NiAVObjectPalette> NiAVObjectPaletteRef;
 
 /*!
- * AKeyedData - Single items of data linked to particular key times.
+ * NiAVObjectPalette - Unknown.
  */
 
-class AKeyedData : public A_KEYED_DATA_PARENT {
+class NiAVObjectPalette : public NI_A_V_OBJECT_PALETTE_PARENT {
 public:
-	NIFLIB_API AKeyedData();
-	NIFLIB_API ~AKeyedData();
+	NIFLIB_API NiAVObjectPalette();
+	NIFLIB_API ~NiAVObjectPalette();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -31,7 +29,7 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 protected:
-	A_KEYED_DATA_MEMBERS
+	NI_A_V_OBJECT_PALETTE_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/NiAlphaController.h b/include/obj/NiAlphaController.h
index f7c9f4e0..8cba2a71 100644
--- a/include/obj/NiAlphaController.h
+++ b/include/obj/NiAlphaController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIALPHACONTROLLER_H_
 #define _NIALPHACONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiFloatInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiAutoNormalParticlesData.h b/include/obj/NiAutoNormalParticlesData.h
index f9797131..b63f805b 100644
--- a/include/obj/NiAutoNormalParticlesData.h
+++ b/include/obj/NiAutoNormalParticlesData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIAUTONORMALPARTICLESDATA_H_
 #define _NIAUTONORMALPARTICLESDATA_H_
 
-#include "NiTriBasedGeomData.h"
+#include "NiParticlesData.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiBSBoneLODController.h b/include/obj/NiBSBoneLODController.h
index 546532f6..a22a06dd 100644
--- a/include/obj/NiBSBoneLODController.h
+++ b/include/obj/NiBSBoneLODController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBSBONELODCONTROLLER_H_
 #define _NIBSBONELODCONTROLLER_H_
 
-#include "ABoneLODController.h"
+#include "NiBoneLODController.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/NiBSplineCompFloatInterpolator.h b/include/obj/NiBSplineCompFloatInterpolator.h
index 4e7113d7..cf536af8 100644
--- a/include/obj/NiBSplineCompFloatInterpolator.h
+++ b/include/obj/NiBSplineCompFloatInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBSPLINECOMPFLOATINTERPOLATOR_H_
 #define _NIBSPLINECOMPFLOATINTERPOLATOR_H_
 
-#include "NiBSplineInterpolator.h"
+#include "NiBSplineFloatInterpolator.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiBSplineCompPoint3Interpolator.h b/include/obj/NiBSplineCompPoint3Interpolator.h
index 24d85962..81260138 100644
--- a/include/obj/NiBSplineCompPoint3Interpolator.h
+++ b/include/obj/NiBSplineCompPoint3Interpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBSPLINECOMPPOINT3INTERPOLATOR_H_
 #define _NIBSPLINECOMPPOINT3INTERPOLATOR_H_
 
-#include "NiBSplineInterpolator.h"
+#include "NiBSplinePoint3Interpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiBSplineCompTransformInterpolator.h b/include/obj/NiBSplineCompTransformInterpolator.h
index cd2ce752..6096388b 100644
--- a/include/obj/NiBSplineCompTransformInterpolator.h
+++ b/include/obj/NiBSplineCompTransformInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBSPLINECOMPTRANSFORMINTERPOLATOR_H_
 #define _NIBSPLINECOMPTRANSFORMINTERPOLATOR_H_
 
-#include "NiBSplineInterpolator.h"
+#include "NiBSplineTransformInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiBSplineFloatInterpolator.h b/include/obj/NiBSplineFloatInterpolator.h
new file mode 100644
index 00000000..784bbd3e
--- /dev/null
+++ b/include/obj/NiBSplineFloatInterpolator.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIBSPLINEFLOATINTERPOLATOR_H_
+#define _NIBSPLINEFLOATINTERPOLATOR_H_
+
+#include "NiBSplineInterpolator.h"
+namespace Niflib {
+
+class NiBSplineFloatInterpolator;
+typedef Ref<NiBSplineFloatInterpolator> NiBSplineFloatInterpolatorRef;
+
+/*!
+ * NiBSplineFloatInterpolator - Unknown.
+ */
+
+class NiBSplineFloatInterpolator : public NI_B_SPLINE_FLOAT_INTERPOLATOR_PARENT {
+public:
+	NIFLIB_API NiBSplineFloatInterpolator();
+	NIFLIB_API ~NiBSplineFloatInterpolator();
+	//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_B_SPLINE_FLOAT_INTERPOLATOR_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/NiBSplinePoint3Interpolator.h b/include/obj/NiBSplinePoint3Interpolator.h
new file mode 100644
index 00000000..7cb0c3d6
--- /dev/null
+++ b/include/obj/NiBSplinePoint3Interpolator.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIBSPLINEPOINT3INTERPOLATOR_H_
+#define _NIBSPLINEPOINT3INTERPOLATOR_H_
+
+#include "NiBSplineInterpolator.h"
+namespace Niflib {
+
+class NiBSplinePoint3Interpolator;
+typedef Ref<NiBSplinePoint3Interpolator> NiBSplinePoint3InterpolatorRef;
+
+/*!
+ * NiBSplinePoint3Interpolator - Unknown.
+ */
+
+class NiBSplinePoint3Interpolator : public NI_B_SPLINE_POINT3_INTERPOLATOR_PARENT {
+public:
+	NIFLIB_API NiBSplinePoint3Interpolator();
+	NIFLIB_API ~NiBSplinePoint3Interpolator();
+	//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_B_SPLINE_POINT3_INTERPOLATOR_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/AbhkRagdollConstraint.h b/include/obj/NiBSplineTransformInterpolator.h
similarity index 71%
rename from include/obj/AbhkRagdollConstraint.h
rename to include/obj/NiBSplineTransformInterpolator.h
index 7d36747d..06a1aa56 100644
--- a/include/obj/AbhkRagdollConstraint.h
+++ b/include/obj/NiBSplineTransformInterpolator.h
@@ -1,28 +1,23 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _ABHKRAGDOLLCONSTRAINT_H_
-#define _ABHKRAGDOLLCONSTRAINT_H_
+#ifndef _NIBSPLINETRANSFORMINTERPOLATOR_H_
+#define _NIBSPLINETRANSFORMINTERPOLATOR_H_
 
-#include "AbhkConstraint.h"
-// Include structures
-#include "../gen/RagdollDescriptor.h"
+#include "NiBSplineInterpolator.h"
 namespace Niflib {
 
-
-//#include "../gen/obj_defines.h"
-
-class AbhkRagdollConstraint;
-typedef Ref<AbhkRagdollConstraint> AbhkRagdollConstraintRef;
+class NiBSplineTransformInterpolator;
+typedef Ref<NiBSplineTransformInterpolator> NiBSplineTransformInterpolatorRef;
 
 /*!
- * AbhkRagdollConstraint - Ragdoll constraint.
+ * NiBSplineTransformInterpolator - Unknown.
  */
 
-class AbhkRagdollConstraint : public ABHK_RAGDOLL_CONSTRAINT_PARENT {
+class NiBSplineTransformInterpolator : public NI_B_SPLINE_TRANSFORM_INTERPOLATOR_PARENT {
 public:
-	NIFLIB_API AbhkRagdollConstraint();
-	NIFLIB_API ~AbhkRagdollConstraint();
+	NIFLIB_API NiBSplineTransformInterpolator();
+	NIFLIB_API ~NiBSplineTransformInterpolator();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -34,7 +29,7 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 protected:
-	ABHK_RAGDOLL_CONSTRAINT_MEMBERS
+	NI_B_SPLINE_TRANSFORM_INTERPOLATOR_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/NiBoneLODController.h b/include/obj/NiBoneLODController.h
index 36d00fd1..b76fc4cc 100644
--- a/include/obj/NiBoneLODController.h
+++ b/include/obj/NiBoneLODController.h
@@ -4,10 +4,11 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBONELODCONTROLLER_H_
 #define _NIBONELODCONTROLLER_H_
 
-#include "ABoneLODController.h"
+#include "NiTimeController.h"
 
 // Include structures
 #include "../gen/SkinShapeGroup.h"
+#include "../gen/NodeGroup.h"
 #include "../Ref.h"
 namespace Niflib {
 
diff --git a/include/obj/NiBoolData.h b/include/obj/NiBoolData.h
index 9deba0ed..efc385f8 100644
--- a/include/obj/NiBoolData.h
+++ b/include/obj/NiBoolData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBOOLDATA_H_
 #define _NIBOOLDATA_H_
 
-#include "AKeyedData.h"
+#include "NiObject.h"
 // Include structures
 #include "../gen/KeyGroup.h"
 namespace Niflib {
diff --git a/include/obj/NiBoolInterpController.h b/include/obj/NiBoolInterpController.h
new file mode 100644
index 00000000..98d20e25
--- /dev/null
+++ b/include/obj/NiBoolInterpController.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIBOOLINTERPCONTROLLER_H_
+#define _NIBOOLINTERPCONTROLLER_H_
+
+#include "NiSingleInterpController.h"
+namespace Niflib {
+
+class NiBoolInterpController;
+typedef Ref<NiBoolInterpController> NiBoolInterpControllerRef;
+
+/*!
+ * NiBoolInterpController - A controller that interpolates floating point
+ * numbers?
+ */
+
+class NiBoolInterpController : public NI_BOOL_INTERP_CONTROLLER_PARENT {
+public:
+	NIFLIB_API NiBoolInterpController();
+	NIFLIB_API ~NiBoolInterpController();
+	//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_BOOL_INTERP_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/include/obj/NiBoolInterpolator.h b/include/obj/NiBoolInterpolator.h
index 34ac2f79..fd5e00fa 100644
--- a/include/obj/NiBoolInterpolator.h
+++ b/include/obj/NiBoolInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBOOLINTERPOLATOR_H_
 #define _NIBOOLINTERPOLATOR_H_
 
-#include "NiInterpolator.h"
+#include "NiKeyBasedInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiBoolTimelineInterpolator.h b/include/obj/NiBoolTimelineInterpolator.h
index abe4bdf7..20969e1b 100644
--- a/include/obj/NiBoolTimelineInterpolator.h
+++ b/include/obj/NiBoolTimelineInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIBOOLTIMELINEINTERPOLATOR_H_
 #define _NIBOOLTIMELINEINTERPOLATOR_H_
 
-#include "NiInterpolator.h"
+#include "NiBoolInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiCollisionData.h b/include/obj/NiCollisionData.h
index 2f4a447f..f57b7362 100644
--- a/include/obj/NiCollisionData.h
+++ b/include/obj/NiCollisionData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NICOLLISIONDATA_H_
 #define _NICOLLISIONDATA_H_
 
-#include "NiObject.h"
+#include "NiCollisionObject.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
diff --git a/include/obj/NiCollisionObject.h b/include/obj/NiCollisionObject.h
index af0ed69f..4305c6d7 100644
--- a/include/obj/NiCollisionObject.h
+++ b/include/obj/NiCollisionObject.h
@@ -13,6 +13,7 @@ namespace Niflib {
 // Forward define of referenced NIF objects
 class NiAVObject;
 class NiObject;
+class NiNode;
 
 //#include "../gen/obj_defines.h"
 
@@ -41,7 +42,7 @@ public:
 	 * Returns the NiNode that this collision object is connected to, if any.
 	 * \return The NiNode that this collision object is connected to, or NULL if it is not connected to any nodes.
 	 */
-	NIFLIB_API Ref<NiAVObject> GetParent() const;
+	NIFLIB_API Ref<NiAVObject> GetTarget() const;
 
 	/*!
 	 * Gets the rigid body that this collision object uses, if any.
@@ -56,7 +57,7 @@ public:
 	NIFLIB_API void SetBody( NiObject * value );
 
 	/*! NIFLIB_HIDDEN function.  For internal use only */
-	NIFLIB_HIDDEN void SetParent( NiAVObject * value );
+	NIFLIB_HIDDEN void SetTarget( NiAVObject * value );
 
 protected:
 	NI_COLLISION_OBJECT_MEMBERS
diff --git a/include/obj/NiColorData.h b/include/obj/NiColorData.h
index 1487ad30..055ddff4 100644
--- a/include/obj/NiColorData.h
+++ b/include/obj/NiColorData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NICOLORDATA_H_
 #define _NICOLORDATA_H_
 
-#include "AKeyedData.h"
+#include "NiObject.h"
 // Include structures
 #include "../gen/KeyGroup.h"
 namespace Niflib {
diff --git a/include/obj/NiControllerSequence.h b/include/obj/NiControllerSequence.h
index e78cadff..4a32ce6b 100644
--- a/include/obj/NiControllerSequence.h
+++ b/include/obj/NiControllerSequence.h
@@ -15,7 +15,7 @@ class NiTextKeyExtraData;
 class NiControllerManager;
 class NiStringPalette;
 class NiTimeController;
-class NiSingleInterpolatorController;
+class NiSingleInterpController;
 
 //#include "../gen/obj_defines.h"
 
@@ -80,7 +80,7 @@ public:
 	 * \param[in] priority Used only in Oblivion to set the priority of one controller over another when the two are merged.
 	 * \sa NiControllerSequence::ClearChildren, NiControllerSequence::AddController
 	 */
-	NIFLIB_API void AddInterpolator( NiSingleInterpolatorController * obj, byte priority = 0 );
+	NIFLIB_API void AddInterpolator( NiSingleInterpController * obj, byte priority = 0 );
 
 	/*! 
 	 * Removes all controllers and interpolators from this Kf file root object.
diff --git a/include/obj/NiDefaultAVObjectPalette.h b/include/obj/NiDefaultAVObjectPalette.h
index 87fc3abf..6a05a888 100644
--- a/include/obj/NiDefaultAVObjectPalette.h
+++ b/include/obj/NiDefaultAVObjectPalette.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIDEFAULTAVOBJECTPALETTE_H_
 #define _NIDEFAULTAVOBJECTPALETTE_H_
 
-#include "NiObject.h"
+#include "NiAVObjectPalette.h"
 
 // Include structures
 #include "../gen/AVObject.h"
diff --git a/include/obj/NiExtraDataController.h b/include/obj/NiExtraDataController.h
new file mode 100644
index 00000000..79749062
--- /dev/null
+++ b/include/obj/NiExtraDataController.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIEXTRADATACONTROLLER_H_
+#define _NIEXTRADATACONTROLLER_H_
+
+#include "NiSingleInterpController.h"
+namespace Niflib {
+
+class NiExtraDataController;
+typedef Ref<NiExtraDataController> NiExtraDataControllerRef;
+
+/*!
+ * NiExtraDataController - An controller for extra data.
+ */
+
+class NiExtraDataController : public NI_EXTRA_DATA_CONTROLLER_PARENT {
+public:
+	NIFLIB_API NiExtraDataController();
+	NIFLIB_API ~NiExtraDataController();
+	//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_EXTRA_DATA_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/include/obj/NiFlipController.h b/include/obj/NiFlipController.h
index 07dabff1..d372a4ba 100644
--- a/include/obj/NiFlipController.h
+++ b/include/obj/NiFlipController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIFLIPCONTROLLER_H_
 #define _NIFLIPCONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiFloatInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiFloatData.h b/include/obj/NiFloatData.h
index d1e5df2f..4b6917e8 100644
--- a/include/obj/NiFloatData.h
+++ b/include/obj/NiFloatData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIFLOATDATA_H_
 #define _NIFLOATDATA_H_
 
-#include "AKeyedData.h"
+#include "NiObject.h"
 // Include structures
 #include "../gen/KeyGroup.h"
 namespace Niflib {
diff --git a/include/obj/NiFloatExtraDataController.h b/include/obj/NiFloatExtraDataController.h
index b89269c0..1d81fbd5 100644
--- a/include/obj/NiFloatExtraDataController.h
+++ b/include/obj/NiFloatExtraDataController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIFLOATEXTRADATACONTROLLER_H_
 #define _NIFLOATEXTRADATACONTROLLER_H_
 
-#include "NiTimeController.h"
+#include "NiExtraDataController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiFloatInterpController.h b/include/obj/NiFloatInterpController.h
new file mode 100644
index 00000000..1b74c39a
--- /dev/null
+++ b/include/obj/NiFloatInterpController.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIFLOATINTERPCONTROLLER_H_
+#define _NIFLOATINTERPCONTROLLER_H_
+
+#include "NiSingleInterpController.h"
+namespace Niflib {
+
+class NiFloatInterpController;
+typedef Ref<NiFloatInterpController> NiFloatInterpControllerRef;
+
+/*!
+ * NiFloatInterpController - A controller that interpolates floating
+ * point numbers?
+ */
+
+class NiFloatInterpController : public NI_FLOAT_INTERP_CONTROLLER_PARENT {
+public:
+	NIFLIB_API NiFloatInterpController();
+	NIFLIB_API ~NiFloatInterpController();
+	//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_FLOAT_INTERP_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/include/obj/NiFloatInterpolator.h b/include/obj/NiFloatInterpolator.h
index d8e43c49..719f25ec 100644
--- a/include/obj/NiFloatInterpolator.h
+++ b/include/obj/NiFloatInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIFLOATINTERPOLATOR_H_
 #define _NIFLOATINTERPOLATOR_H_
 
-#include "NiInterpolator.h"
+#include "NiKeyBasedInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiGeomMorpherController.h b/include/obj/NiGeomMorpherController.h
index 6dcea15f..2537acfb 100644
--- a/include/obj/NiGeomMorpherController.h
+++ b/include/obj/NiGeomMorpherController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIGEOMMORPHERCONTROLLER_H_
 #define _NIGEOMMORPHERCONTROLLER_H_
 
-#include "NiTimeController.h"
+#include "NiInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiInterpController.h b/include/obj/NiInterpController.h
new file mode 100644
index 00000000..e3b566c0
--- /dev/null
+++ b/include/obj/NiInterpController.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIINTERPCONTROLLER_H_
+#define _NIINTERPCONTROLLER_H_
+
+#include "NiTimeController.h"
+namespace Niflib {
+
+class NiInterpController;
+typedef Ref<NiInterpController> NiInterpControllerRef;
+
+/*!
+ * NiInterpController - A controller capable of interpolation?
+ */
+
+class NiInterpController : public NI_INTERP_CONTROLLER_PARENT {
+public:
+	NIFLIB_API NiInterpController();
+	NIFLIB_API ~NiInterpController();
+	//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_INTERP_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/include/obj/NiKeyBasedInterpolator.h b/include/obj/NiKeyBasedInterpolator.h
new file mode 100644
index 00000000..3de9b5fe
--- /dev/null
+++ b/include/obj/NiKeyBasedInterpolator.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIKEYBASEDINTERPOLATOR_H_
+#define _NIKEYBASEDINTERPOLATOR_H_
+
+#include "NiInterpolator.h"
+namespace Niflib {
+
+class NiKeyBasedInterpolator;
+typedef Ref<NiKeyBasedInterpolator> NiKeyBasedInterpolatorRef;
+
+/*!
+ * NiKeyBasedInterpolator - Interpolator objects that use keys?
+ */
+
+class NiKeyBasedInterpolator : public NI_KEY_BASED_INTERPOLATOR_PARENT {
+public:
+	NIFLIB_API NiKeyBasedInterpolator();
+	NIFLIB_API ~NiKeyBasedInterpolator();
+	//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_KEY_BASED_INTERPOLATOR_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/NiKeyframeData.h b/include/obj/NiKeyframeData.h
index 7ac866f8..0fdfbc14 100644
--- a/include/obj/NiKeyframeData.h
+++ b/include/obj/NiKeyframeData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIKEYFRAMEDATA_H_
 #define _NIKEYFRAMEDATA_H_
 
-#include "AKeyedData.h"
+#include "NiObject.h"
 // Include structures
 #include "../gen/KeyGroup.h"
 namespace Niflib {
diff --git a/include/obj/NiLODNode.h b/include/obj/NiLODNode.h
index fc331c63..2870520b 100644
--- a/include/obj/NiLODNode.h
+++ b/include/obj/NiLODNode.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NILODNODE_H_
 #define _NILODNODE_H_
 
-#include "NiNode.h"
+#include "NiSwitchNode.h"
 
 // Include structures
 #include "../gen/LODRange.h"
diff --git a/include/obj/NiLightColorController.h b/include/obj/NiLightColorController.h
index b9eb4bde..a8135e7d 100644
--- a/include/obj/NiLightColorController.h
+++ b/include/obj/NiLightColorController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NILIGHTCOLORCONTROLLER_H_
 #define _NILIGHTCOLORCONTROLLER_H_
 
-#include "NiTimeController.h"
+#include "NiPoint3InterpController.h"
 
 // Include structures
 #include "../Ref.h"
@@ -37,30 +37,6 @@ public:
 	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;
 
-	/*!
-	 * Retrives the pos data used by this controller.
-	 * \return The pos data.
-	 */
-	NIFLIB_API Ref<NiPosData> GetData() const;
-
-	/*!
-	 * Sets the pos data used by this controller.
-	 * \param[in] value The new pos data.
-	 */
-	NIFLIB_API void SetData( NiPosData * value );
-
-	/*!
-	 * Retrives the interpolator used by this controller.
-	 * \return The interpolator.
-	 */
-	NIFLIB_API Ref<NiPoint3Interpolator> GetInterpolator() const;
-
-	/*!
-	 * Sets the interpolator used by this controller.
-	 * \param[in] value The new interpolator.
-	 */
-	NIFLIB_API void SetInterpolator( NiPoint3Interpolator * value );
-
 protected:
 	NI_LIGHT_COLOR_CONTROLLER_MEMBERS
 private:
diff --git a/include/obj/NiLightDimmerController.h b/include/obj/NiLightDimmerController.h
index 28898103..786795e9 100644
--- a/include/obj/NiLightDimmerController.h
+++ b/include/obj/NiLightDimmerController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NILIGHTDIMMERCONTROLLER_H_
 #define _NILIGHTDIMMERCONTROLLER_H_
 
-#include "NiTimeController.h"
+#include "NiFloatInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiMaterialColorController.h b/include/obj/NiMaterialColorController.h
index 7ae0cc25..94b615f7 100644
--- a/include/obj/NiMaterialColorController.h
+++ b/include/obj/NiMaterialColorController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIMATERIALCOLORCONTROLLER_H_
 #define _NIMATERIALCOLORCONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiPoint3InterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiMeshPSysData.h b/include/obj/NiMeshPSysData.h
index d27492a4..f169ad24 100644
--- a/include/obj/NiMeshPSysData.h
+++ b/include/obj/NiMeshPSysData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIMESHPSYSDATA_H_
 #define _NIMESHPSYSDATA_H_
 
-#include "APSysData.h"
+#include "NiPSysData.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiMultiTargetTransformController.h b/include/obj/NiMultiTargetTransformController.h
index 808d635f..6a17486f 100644
--- a/include/obj/NiMultiTargetTransformController.h
+++ b/include/obj/NiMultiTargetTransformController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIMULTITARGETTRANSFORMCONTROLLER_H_
 #define _NIMULTITARGETTRANSFORMCONTROLLER_H_
 
-#include "NiTimeController.h"
+#include "NiInterpController.h"
 
 namespace Niflib {
 
diff --git a/include/obj/NiPSysData.h b/include/obj/NiPSysData.h
index 4c6ce6ed..670a4103 100644
--- a/include/obj/NiPSysData.h
+++ b/include/obj/NiPSysData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSDATA_H_
 #define _NIPSYSDATA_H_
 
-#include "APSysData.h"
+#include "NiRotatingParticlesData.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/NiPSysEmitterCtlr.h b/include/obj/NiPSysEmitterCtlr.h
index 0e714a4f..d4c98fbd 100644
--- a/include/obj/NiPSysEmitterCtlr.h
+++ b/include/obj/NiPSysEmitterCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSEMITTERCTLR_H_
 #define _NIPSYSEMITTERCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierCtlr.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiPSysEmitterDeclinationCtlr.h b/include/obj/NiPSysEmitterDeclinationCtlr.h
index 108ddd45..f71a89ff 100644
--- a/include/obj/NiPSysEmitterDeclinationCtlr.h
+++ b/include/obj/NiPSysEmitterDeclinationCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSEMITTERDECLINATIONCTLR_H_
 #define _NIPSYSEMITTERDECLINATIONCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierFloatCtlr.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiPSysEmitterDeclinationVarCtlr.h b/include/obj/NiPSysEmitterDeclinationVarCtlr.h
index 04eb553d..0bd169f2 100644
--- a/include/obj/NiPSysEmitterDeclinationVarCtlr.h
+++ b/include/obj/NiPSysEmitterDeclinationVarCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSEMITTERDECLINATIONVARCTLR_H_
 #define _NIPSYSEMITTERDECLINATIONVARCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierFloatCtlr.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiPSysEmitterInitialRadiusCtlr.h b/include/obj/NiPSysEmitterInitialRadiusCtlr.h
index d731f0a6..c1306d19 100644
--- a/include/obj/NiPSysEmitterInitialRadiusCtlr.h
+++ b/include/obj/NiPSysEmitterInitialRadiusCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSEMITTERINITIALRADIUSCTLR_H_
 #define _NIPSYSEMITTERINITIALRADIUSCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierFloatCtlr.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiPSysEmitterLifeSpanCtlr.h b/include/obj/NiPSysEmitterLifeSpanCtlr.h
index 9f356b0f..b0987f8a 100644
--- a/include/obj/NiPSysEmitterLifeSpanCtlr.h
+++ b/include/obj/NiPSysEmitterLifeSpanCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSEMITTERLIFESPANCTLR_H_
 #define _NIPSYSEMITTERLIFESPANCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierFloatCtlr.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiPSysEmitterSpeedCtlr.h b/include/obj/NiPSysEmitterSpeedCtlr.h
index 445f4464..ddea4366 100644
--- a/include/obj/NiPSysEmitterSpeedCtlr.h
+++ b/include/obj/NiPSysEmitterSpeedCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSEMITTERSPEEDCTLR_H_
 #define _NIPSYSEMITTERSPEEDCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierFloatCtlr.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
diff --git a/include/obj/NiPSysGravityStrengthCtlr.h b/include/obj/NiPSysGravityStrengthCtlr.h
index 4306b1a9..38bfe345 100644
--- a/include/obj/NiPSysGravityStrengthCtlr.h
+++ b/include/obj/NiPSysGravityStrengthCtlr.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSGRAVITYSTRENGTHCTLR_H_
 #define _NIPSYSGRAVITYSTRENGTHCTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierFloatCtlr.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
diff --git a/include/obj/NiPSysModifierActiveCtlr.h b/include/obj/NiPSysModifierActiveCtlr.h
index 15ad0c2e..71146df6 100644
--- a/include/obj/NiPSysModifierActiveCtlr.h
+++ b/include/obj/NiPSysModifierActiveCtlr.h
@@ -4,13 +4,14 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPSYSMODIFIERACTIVECTLR_H_
 #define _NIPSYSMODIFIERACTIVECTLR_H_
 
-#include "APSysCtlr.h"
+#include "NiPSysModifierBoolCtlr.h"
 namespace Niflib {
 
 
 //#include "../gen/obj_defines.h"
 
 class NiPSysModifierActiveCtlr;
+class NiVisData;
 typedef Ref<NiPSysModifierActiveCtlr> NiPSysModifierActiveCtlrRef;
 
 /*!
diff --git a/include/obj/NiPSysModifierBoolCtlr.h b/include/obj/NiPSysModifierBoolCtlr.h
new file mode 100644
index 00000000..3965a472
--- /dev/null
+++ b/include/obj/NiPSysModifierBoolCtlr.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIPSYSMODIFIERBOOLCTLR_H_
+#define _NIPSYSMODIFIERBOOLCTLR_H_
+
+#include "NiPSysModifierCtlr.h"
+namespace Niflib {
+
+class NiPSysModifierBoolCtlr;
+typedef Ref<NiPSysModifierBoolCtlr> NiPSysModifierBoolCtlrRef;
+
+/*!
+ * NiPSysModifierBoolCtlr - A particle system modifier controller that
+ * deals with boolean data?
+ */
+
+class NiPSysModifierBoolCtlr : public NI_P_SYS_MODIFIER_BOOL_CTLR_PARENT {
+public:
+	NIFLIB_API NiPSysModifierBoolCtlr();
+	NIFLIB_API ~NiPSysModifierBoolCtlr();
+	//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_MODIFIER_BOOL_CTLR_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/NiPSysModifierCtlr.h b/include/obj/NiPSysModifierCtlr.h
new file mode 100644
index 00000000..71797b73
--- /dev/null
+++ b/include/obj/NiPSysModifierCtlr.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIPSYSMODIFIERCTLR_H_
+#define _NIPSYSMODIFIERCTLR_H_
+
+#include "NiSingleInterpController.h"
+namespace Niflib {
+
+class NiPSysModifierCtlr;
+typedef Ref<NiPSysModifierCtlr> NiPSysModifierCtlrRef;
+
+/*!
+ * NiPSysModifierCtlr - A particle system modifier controller.
+ */
+
+class NiPSysModifierCtlr : public NI_P_SYS_MODIFIER_CTLR_PARENT {
+public:
+	NIFLIB_API NiPSysModifierCtlr();
+	NIFLIB_API ~NiPSysModifierCtlr();
+	//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_MODIFIER_CTLR_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/NiPSysModifierFloatCtlr.h b/include/obj/NiPSysModifierFloatCtlr.h
new file mode 100644
index 00000000..5e1d0de6
--- /dev/null
+++ b/include/obj/NiPSysModifierFloatCtlr.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NIPSYSMODIFIERFLOATCTLR_H_
+#define _NIPSYSMODIFIERFLOATCTLR_H_
+
+#include "NiPSysModifierCtlr.h"
+
+// Include structures
+#include "../Ref.h"
+namespace Niflib {
+
+// Forward define of referenced NIF objects
+class NiFloatData;
+class NiPSysModifierFloatCtlr;
+typedef Ref<NiPSysModifierFloatCtlr> NiPSysModifierFloatCtlrRef;
+
+/*!
+ * NiPSysModifierFloatCtlr - A particle system modifier controller that
+ * deals with floating point data?
+ */
+
+class NiPSysModifierFloatCtlr : public NI_P_SYS_MODIFIER_FLOAT_CTLR_PARENT {
+public:
+	NIFLIB_API NiPSysModifierFloatCtlr();
+	NIFLIB_API ~NiPSysModifierFloatCtlr();
+	//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_MODIFIER_FLOAT_CTLR_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/NiParticleMeshesData.h b/include/obj/NiParticleMeshesData.h
index 7f832f84..83967982 100644
--- a/include/obj/NiParticleMeshesData.h
+++ b/include/obj/NiParticleMeshesData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPARTICLEMESHESDATA_H_
 #define _NIPARTICLEMESHESDATA_H_
 
-#include "NiParticlesData.h"
+#include "NiRotatingParticlesData.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiParticlesData.h b/include/obj/NiParticlesData.h
index 43ed4462..39932ea3 100644
--- a/include/obj/NiParticlesData.h
+++ b/include/obj/NiParticlesData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPARTICLESDATA_H_
 #define _NIPARTICLESDATA_H_
 
-#include "NiAutoNormalParticlesData.h"
+#include "NiGeometryData.h"
 namespace Niflib {
 
 
diff --git a/include/obj/NiPathInterpolator.h b/include/obj/NiPathInterpolator.h
index 924029f0..7c114ed5 100644
--- a/include/obj/NiPathInterpolator.h
+++ b/include/obj/NiPathInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPATHINTERPOLATOR_H_
 #define _NIPATHINTERPOLATOR_H_
 
-#include "NiBlendInterpolator.h"
+#include "NiKeyBasedInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/APSysCtlr.h b/include/obj/NiPoint3InterpController.h
similarity index 60%
rename from include/obj/APSysCtlr.h
rename to include/obj/NiPoint3InterpController.h
index e45c86ab..9f0f1b15 100644
--- a/include/obj/APSysCtlr.h
+++ b/include/obj/NiPoint3InterpController.h
@@ -1,26 +1,29 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _APSYSCTLR_H_
-#define _APSYSCTLR_H_
-
-#include "NiSingleInterpolatorController.h"
-namespace Niflib {
+#ifndef _NIPOINT3INTERPCONTROLLER_H_
+#define _NIPOINT3INTERPCONTROLLER_H_
 
+#include "NiSingleInterpController.h"
 
-//#include "../gen/obj_defines.h"
+// Include structures
+#include "../Ref.h"
+namespace Niflib {
 
-class APSysCtlr;
-typedef Ref<APSysCtlr> APSysCtlrRef;
+// Forward define of referenced NIF objects
+class NiPosData;
+class NiPoint3InterpController;
+typedef Ref<NiPoint3InterpController> NiPoint3InterpControllerRef;
 
 /*!
- * APSysCtlr - Unknown.
+ * NiPoint3InterpController - A controller that interpolates point 3
+ * data?
  */
 
-class APSysCtlr : public A_P_SYS_CTLR_PARENT {
+class NiPoint3InterpController : public NI_POINT3_INTERP_CONTROLLER_PARENT {
 public:
-	NIFLIB_API APSysCtlr();
-	NIFLIB_API ~APSysCtlr();
+	NIFLIB_API NiPoint3InterpController();
+	NIFLIB_API ~NiPoint3InterpController();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -32,19 +35,19 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 	/*!
-	 * Retrives the modifier name. This seems to refer to the modifier object by its name.
-	 * \return The modifier name.
+	 * Retrives the pos data used by this controller.
+	 * \return The pos data.
 	 */
-	NIFLIB_API string GetModifierName() const;
+	NIFLIB_API Ref<NiPosData> GetData() const;
 
 	/*!
-	 * Sets the modifier name. This seems to refer to the modifier object by its name.
-	 * \param[in] value The new modifier name.
+	 * Sets the pos data used by this controller.
+	 * \param[in] value The new pos data.
 	 */
-	NIFLIB_API void SetModifierName( string value );
+	NIFLIB_API void SetData( NiPosData * value );
 
 protected:
-	A_P_SYS_CTLR_MEMBERS
+	NI_POINT3_INTERP_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;
diff --git a/include/obj/NiPoint3Interpolator.h b/include/obj/NiPoint3Interpolator.h
index 37534b73..9b07adc8 100644
--- a/include/obj/NiPoint3Interpolator.h
+++ b/include/obj/NiPoint3Interpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPOINT3INTERPOLATOR_H_
 #define _NIPOINT3INTERPOLATOR_H_
 
-#include "NiInterpolator.h"
+#include "NiKeyBasedInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiPosData.h b/include/obj/NiPosData.h
index 2e48433e..7b5191a1 100644
--- a/include/obj/NiPosData.h
+++ b/include/obj/NiPosData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIPOSDATA_H_
 #define _NIPOSDATA_H_
 
-#include "AKeyedData.h"
+#include "NiObject.h"
 // Include structures
 #include "../gen/KeyGroup.h"
 namespace Niflib {
diff --git a/include/obj/NiRollController.h b/include/obj/NiRollController.h
index a6530620..9debc6bf 100644
--- a/include/obj/NiRollController.h
+++ b/include/obj/NiRollController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIROLLCONTROLLER_H_
 #define _NIROLLCONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiSingleInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiSingleInterpolatorController.h b/include/obj/NiSingleInterpController.h
similarity index 72%
rename from include/obj/NiSingleInterpolatorController.h
rename to include/obj/NiSingleInterpController.h
index 809abae8..b5959728 100644
--- a/include/obj/NiSingleInterpolatorController.h
+++ b/include/obj/NiSingleInterpController.h
@@ -1,10 +1,10 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _NISINGLEINTERPOLATORCONTROLLER_H_
-#define _NISINGLEINTERPOLATORCONTROLLER_H_
+#ifndef _NISINGLEINTERPCONTROLLER_H_
+#define _NISINGLEINTERPCONTROLLER_H_
 
-#include "NiTimeController.h"
+#include "NiInterpController.h"
 
 // Include structures
 #include "../Ref.h"
@@ -12,21 +12,18 @@ namespace Niflib {
 
 // Forward define of referenced NIF objects
 class NiInterpolator;
-
-//#include "../gen/obj_defines.h"
-
-class NiSingleInterpolatorController;
-typedef Ref<NiSingleInterpolatorController> NiSingleInterpolatorControllerRef;
+class NiSingleInterpController;
+typedef Ref<NiSingleInterpController> NiSingleInterpControllerRef;
 
 /*!
- * NiSingleInterpolatorController - A controller referring to an
+ * NiSingleInterpController - A controller referring to a single
  * interpolator.
  */
 
-class NiSingleInterpolatorController : public NI_SINGLE_INTERPOLATOR_CONTROLLER_PARENT {
+class NiSingleInterpController : public NI_SINGLE_INTERP_CONTROLLER_PARENT {
 public:
-	NIFLIB_API NiSingleInterpolatorController();
-	NIFLIB_API ~NiSingleInterpolatorController();
+	NIFLIB_API NiSingleInterpController();
+	NIFLIB_API ~NiSingleInterpController();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -41,7 +38,7 @@ public:
 	 * Retrives the interpolator used by this controller.
 	 * \return The interpolator.
 	 */
-	NIFLIB_API Ref<NiInterpolator > GetInterpolator() const;
+	NIFLIB_API Ref<NiInterpolator> GetInterpolator() const;
 
 	/*!
 	 * Sets the interpolator used by this controller.
@@ -50,7 +47,7 @@ public:
 	NIFLIB_API void SetInterpolator( NiInterpolator * value );
 
 protected:
-	NI_SINGLE_INTERPOLATOR_CONTROLLER_MEMBERS
+	NI_SINGLE_INTERP_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;
diff --git a/include/obj/NiSourceTexture.h b/include/obj/NiSourceTexture.h
index 411c080e..79d77276 100644
--- a/include/obj/NiSourceTexture.h
+++ b/include/obj/NiSourceTexture.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NISOURCETEXTURE_H_
 #define _NISOURCETEXTURE_H_
 
-#include "NiObjectNET.h"
+#include "NiTexture.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiSwitchNode.h b/include/obj/NiSwitchNode.h
new file mode 100644
index 00000000..8517b7a6
--- /dev/null
+++ b/include/obj/NiSwitchNode.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NISWITCHNODE_H_
+#define _NISWITCHNODE_H_
+
+#include "NiNode.h"
+namespace Niflib {
+
+class NiSwitchNode;
+typedef Ref<NiSwitchNode> NiSwitchNodeRef;
+
+/*!
+ * NiSwitchNode - A node used to switch between branches, such as for LOD
+ * levels?
+ */
+
+class NiSwitchNode : public NI_SWITCH_NODE_PARENT {
+public:
+	NIFLIB_API NiSwitchNode();
+	NIFLIB_API ~NiSwitchNode();
+	//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_SWITCH_NODE_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/NiTexture.h b/include/obj/NiTexture.h
new file mode 100644
index 00000000..86e6c9ad
--- /dev/null
+++ b/include/obj/NiTexture.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _NITEXTURE_H_
+#define _NITEXTURE_H_
+
+#include "NiObjectNET.h"
+namespace Niflib {
+
+class NiTexture;
+typedef Ref<NiTexture> NiTextureRef;
+
+/*!
+ * NiTexture - A texture.
+ */
+
+class NiTexture : public NI_TEXTURE_PARENT {
+public:
+	NIFLIB_API NiTexture();
+	NIFLIB_API ~NiTexture();
+	//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_TEXTURE_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/NiTextureTransformController.h b/include/obj/NiTextureTransformController.h
index 36564dea..9cdc1e65 100644
--- a/include/obj/NiTextureTransformController.h
+++ b/include/obj/NiTextureTransformController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NITEXTURETRANSFORMCONTROLLER_H_
 #define _NITEXTURETRANSFORMCONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiFloatInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiTransformController.h b/include/obj/NiTransformController.h
index d6c80901..ccb934dd 100644
--- a/include/obj/NiTransformController.h
+++ b/include/obj/NiTransformController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NITRANSFORMCONTROLLER_H_
 #define _NITRANSFORMCONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiSingleInterpController.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/NiTransformInterpolator.h b/include/obj/NiTransformInterpolator.h
index 5933b5c9..b313d670 100644
--- a/include/obj/NiTransformInterpolator.h
+++ b/include/obj/NiTransformInterpolator.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NITRANSFORMINTERPOLATOR_H_
 #define _NITRANSFORMINTERPOLATOR_H_
 
-#include "NiInterpolator.h"
+#include "NiKeyBasedInterpolator.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiVisController.h b/include/obj/NiVisController.h
index fd63eede..27f69771 100644
--- a/include/obj/NiVisController.h
+++ b/include/obj/NiVisController.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIVISCONTROLLER_H_
 #define _NIVISCONTROLLER_H_
 
-#include "NiSingleInterpolatorController.h"
+#include "NiBoolInterpController.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/NiVisData.h b/include/obj/NiVisData.h
index c6cba34e..b8a41964 100644
--- a/include/obj/NiVisData.h
+++ b/include/obj/NiVisData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _NIVISDATA_H_
 #define _NIVISDATA_H_
 
-#include "AKeyedData.h"
+#include "NiObject.h"
 namespace Niflib {
 
 
diff --git a/include/obj/bhkBlendCollisionObject.h b/include/obj/bhkBlendCollisionObject.h
index ae792751..b54b6ac9 100644
--- a/include/obj/bhkBlendCollisionObject.h
+++ b/include/obj/bhkBlendCollisionObject.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKBLENDCOLLISIONOBJECT_H_
 #define _BHKBLENDCOLLISIONOBJECT_H_
 
-#include "NiCollisionObject.h"
+#include "bhkCollisionObject.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/AbhkShapeCollection.h b/include/obj/bhkBvTreeShape.h
similarity index 74%
rename from include/obj/AbhkShapeCollection.h
rename to include/obj/bhkBvTreeShape.h
index d74bd9c3..54f21ab8 100644
--- a/include/obj/AbhkShapeCollection.h
+++ b/include/obj/bhkBvTreeShape.h
@@ -1,26 +1,24 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _ABHKSHAPECOLLECTION_H_
-#define _ABHKSHAPECOLLECTION_H_
+#ifndef _BHKBVTREESHAPE_H_
+#define _BHKBVTREESHAPE_H_
 
 #include "bhkShape.h"
 namespace Niflib {
 
-//#include "../gen/obj_defines.h"
-
-class AbhkShapeCollection;
-typedef Ref<AbhkShapeCollection> AbhkShapeCollectionRef;
+class bhkBvTreeShape;
+typedef Ref<bhkBvTreeShape> bhkBvTreeShapeRef;
 
 /*!
- * AbhkShapeCollection - Havok data, not sure where to put in the
- * hierarchy.
+ * bhkBvTreeShape - A tree-like Havok data structure stored in an
+ * assembly-like binary code?
  */
 
-class AbhkShapeCollection : public ABHK_SHAPE_COLLECTION_PARENT {
+class bhkBvTreeShape : public BHK_BV_TREE_SHAPE_PARENT {
 public:
-	NIFLIB_API AbhkShapeCollection();
-	NIFLIB_API ~AbhkShapeCollection();
+	NIFLIB_API bhkBvTreeShape();
+	NIFLIB_API ~bhkBvTreeShape();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -32,7 +30,7 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 protected:
-	ABHK_SHAPE_COLLECTION_MEMBERS
+	BHK_BV_TREE_SHAPE_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/bhkCollisionObject.h b/include/obj/bhkCollisionObject.h
index 4f10555f..bfcbfba0 100644
--- a/include/obj/bhkCollisionObject.h
+++ b/include/obj/bhkCollisionObject.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKCOLLISIONOBJECT_H_
 #define _BHKCOLLISIONOBJECT_H_
 
-#include "NiCollisionObject.h"
+#include "bhkNiCollisionObject.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/AbhkConstraint.h b/include/obj/bhkConstraint.h
similarity index 78%
rename from include/obj/AbhkConstraint.h
rename to include/obj/bhkConstraint.h
index 80a7c531..efd09f51 100644
--- a/include/obj/AbhkConstraint.h
+++ b/include/obj/bhkConstraint.h
@@ -1,28 +1,25 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#ifndef _ABHKCONSTRAINT_H_
-#define _ABHKCONSTRAINT_H_
+#ifndef _BHKCONSTRAINT_H_
+#define _BHKCONSTRAINT_H_
 
 #include "bhkSerializable.h"
 namespace Niflib {
 
 // Forward define of referenced NIF objects
-class bhkShape;
-
-//#include "../gen/obj_defines.h"
-
-class AbhkConstraint;
-typedef Ref<AbhkConstraint> AbhkConstraintRef;
+class bhkEntity;
+class bhkConstraint;
+typedef Ref<bhkConstraint> bhkConstraintRef;
 
 /*!
- * AbhkConstraint - Describes a physical constraint.
+ * bhkConstraint - Describes a physical constraint.
  */
 
-class AbhkConstraint : public ABHK_CONSTRAINT_PARENT {
+class bhkConstraint : public BHK_CONSTRAINT_PARENT {
 public:
-	NIFLIB_API AbhkConstraint();
-	NIFLIB_API ~AbhkConstraint();
+	NIFLIB_API bhkConstraint();
+	NIFLIB_API ~bhkConstraint();
 	//Run-Time Type Information
 	NIFLIB_API static const Type TYPE;
 	NIFLIB_API static NiObject * Create();
@@ -34,7 +31,7 @@ public:
 	NIFLIB_HIDDEN virtual list<NiObjectRef> GetRefs() const;
 
 protected:
-	ABHK_CONSTRAINT_MEMBERS
+	BHK_CONSTRAINT_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/bhkConvexVerticesShape.h b/include/obj/bhkConvexVerticesShape.h
index 2be98e74..a8883359 100644
--- a/include/obj/bhkConvexVerticesShape.h
+++ b/include/obj/bhkConvexVerticesShape.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKCONVEXVERTICESSHAPE_H_
 #define _BHKCONVEXVERTICESSHAPE_H_
 
-#include "bhkSphereRepShape.h"
+#include "bhkConvexShape.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/bhkHingeConstraint.h b/include/obj/bhkHingeConstraint.h
index b9507fa2..eaedd37d 100644
--- a/include/obj/bhkHingeConstraint.h
+++ b/include/obj/bhkHingeConstraint.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKHINGECONSTRAINT_H_
 #define _BHKHINGECONSTRAINT_H_
 
-#include "AbhkConstraint.h"
+#include "bhkConstraint.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/bhkLimitedHingeConstraint.h b/include/obj/bhkLimitedHingeConstraint.h
index 46b1e92c..9a26f4a5 100644
--- a/include/obj/bhkLimitedHingeConstraint.h
+++ b/include/obj/bhkLimitedHingeConstraint.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKLIMITEDHINGECONSTRAINT_H_
 #define _BHKLIMITEDHINGECONSTRAINT_H_
 
-#include "AbhkConstraint.h"
+#include "bhkConstraint.h"
 
 // Include structures
 #include "../gen/LimitedHingeDescriptor.h"
diff --git a/include/obj/bhkListShape.h b/include/obj/bhkListShape.h
index 31a32edd..15d7c7a3 100644
--- a/include/obj/bhkListShape.h
+++ b/include/obj/bhkListShape.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKLISTSHAPE_H_
 #define _BHKLISTSHAPE_H_
 
-#include "AbhkShapeCollection.h"
+#include "bhkShapeCollection.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/bhkMalleableConstraint.h b/include/obj/bhkMalleableConstraint.h
index cde8a19e..cf2bdf18 100644
--- a/include/obj/bhkMalleableConstraint.h
+++ b/include/obj/bhkMalleableConstraint.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKMALLEABLECONSTRAINT_H_
 #define _BHKMALLEABLECONSTRAINT_H_
 
-#include "AbhkConstraint.h"
+#include "bhkConstraint.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/bhkMoppBvTreeShape.h b/include/obj/bhkMoppBvTreeShape.h
index b78838d0..0a7d961e 100644
--- a/include/obj/bhkMoppBvTreeShape.h
+++ b/include/obj/bhkMoppBvTreeShape.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKMOPPBVTREESHAPE_H_
 #define _BHKMOPPBVTREESHAPE_H_
 
-#include "bhkShape.h"
+#include "bhkBvTreeShape.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/bhkNiCollisionObject.h b/include/obj/bhkNiCollisionObject.h
new file mode 100644
index 00000000..a3d09cc3
--- /dev/null
+++ b/include/obj/bhkNiCollisionObject.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _BHKNICOLLISIONOBJECT_H_
+#define _BHKNICOLLISIONOBJECT_H_
+
+#include "NiCollisionObject.h"
+namespace Niflib {
+
+class bhkNiCollisionObject;
+typedef Ref<bhkNiCollisionObject> bhkNiCollisionObjectRef;
+
+/*!
+ * bhkNiCollisionObject - Havok related collision object?
+ */
+
+class bhkNiCollisionObject : public BHK_NI_COLLISION_OBJECT_PARENT {
+public:
+	NIFLIB_API bhkNiCollisionObject();
+	NIFLIB_API ~bhkNiCollisionObject();
+	//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:
+	BHK_NI_COLLISION_OBJECT_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/bhkNiTriStripsShape.h b/include/obj/bhkNiTriStripsShape.h
index 9cda4784..d1f75bd3 100644
--- a/include/obj/bhkNiTriStripsShape.h
+++ b/include/obj/bhkNiTriStripsShape.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKNITRISTRIPSSHAPE_H_
 #define _BHKNITRISTRIPSSHAPE_H_
 
-#include "bhkSphereRepShape.h"
+#include "bhkShapeCollection.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/bhkPCollisionObject.h b/include/obj/bhkPCollisionObject.h
new file mode 100644
index 00000000..297282bf
--- /dev/null
+++ b/include/obj/bhkPCollisionObject.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _BHKPCOLLISIONOBJECT_H_
+#define _BHKPCOLLISIONOBJECT_H_
+
+#include "bhkNiCollisionObject.h"
+namespace Niflib {
+
+class bhkPCollisionObject;
+typedef Ref<bhkPCollisionObject> bhkPCollisionObjectRef;
+
+/*!
+ * bhkPCollisionObject - Unknown.
+ */
+
+class bhkPCollisionObject : public BHK_P_COLLISION_OBJECT_PARENT {
+public:
+	NIFLIB_API bhkPCollisionObject();
+	NIFLIB_API ~bhkPCollisionObject();
+	//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:
+	BHK_P_COLLISION_OBJECT_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/bhkPackedNiTriStripsShape.h b/include/obj/bhkPackedNiTriStripsShape.h
index f9b00d43..7a1e4dff 100644
--- a/include/obj/bhkPackedNiTriStripsShape.h
+++ b/include/obj/bhkPackedNiTriStripsShape.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKPACKEDNITRISTRIPSSHAPE_H_
 #define _BHKPACKEDNITRISTRIPSSHAPE_H_
 
-#include "AbhkShapeCollection.h"
+#include "bhkShapeCollection.h"
 
 // Include structures
 #include "../Ref.h"
diff --git a/include/obj/bhkPhantom.h b/include/obj/bhkPhantom.h
new file mode 100644
index 00000000..e37d803a
--- /dev/null
+++ b/include/obj/bhkPhantom.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _BHKPHANTOM_H_
+#define _BHKPHANTOM_H_
+
+#include "bhkWorldObject.h"
+namespace Niflib {
+
+class bhkPhantom;
+typedef Ref<bhkPhantom> bhkPhantomRef;
+
+/*!
+ * bhkPhantom - Havok object that do not react with other objects when
+ * they collide (causing deflection, etc.) but still trigger collision
+ * notifications to the game.  Possible uses are traps, portals, AI
+ * fields, etc.
+ */
+
+class bhkPhantom : public BHK_PHANTOM_PARENT {
+public:
+	NIFLIB_API bhkPhantom();
+	NIFLIB_API ~bhkPhantom();
+	//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:
+	BHK_PHANTOM_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/bhkPrismaticConstraint.h b/include/obj/bhkPrismaticConstraint.h
index 6724a6a8..bdcd9522 100644
--- a/include/obj/bhkPrismaticConstraint.h
+++ b/include/obj/bhkPrismaticConstraint.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKPRISMATICCONSTRAINT_H_
 #define _BHKPRISMATICCONSTRAINT_H_
 
-#include "AbhkConstraint.h"
+#include "bhkConstraint.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/bhkRagdollConstraint.h b/include/obj/bhkRagdollConstraint.h
index 7f5d0876..9c95b524 100644
--- a/include/obj/bhkRagdollConstraint.h
+++ b/include/obj/bhkRagdollConstraint.h
@@ -4,7 +4,8 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKRAGDOLLCONSTRAINT_H_
 #define _BHKRAGDOLLCONSTRAINT_H_
 
-#include "AbhkRagdollConstraint.h"
+#include "bhkConstraint.h"
+#include "../gen/RagdollDescriptor.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/bhkRigidBody.h b/include/obj/bhkRigidBody.h
index 674a0fa4..223e67fb 100644
--- a/include/obj/bhkRigidBody.h
+++ b/include/obj/bhkRigidBody.h
@@ -12,7 +12,7 @@ All rights reserved.  Please see niflib.h for license. */
 namespace Niflib {
 
 // Forward define of referenced NIF objects
-class AbhkConstraint;
+class bhkConstraint;
 
 //#include "../gen/obj_defines.h"
 
diff --git a/include/obj/bhkSPCollisionObject.h b/include/obj/bhkSPCollisionObject.h
index 00ff94e1..cce53ae3 100644
--- a/include/obj/bhkSPCollisionObject.h
+++ b/include/obj/bhkSPCollisionObject.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKSPCOLLISIONOBJECT_H_
 #define _BHKSPCOLLISIONOBJECT_H_
 
-#include "NiCollisionObject.h"
+#include "bhkPCollisionObject.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/bhkShapeCollection.h b/include/obj/bhkShapeCollection.h
new file mode 100644
index 00000000..9dd20949
--- /dev/null
+++ b/include/obj/bhkShapeCollection.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _BHKSHAPECOLLECTION_H_
+#define _BHKSHAPECOLLECTION_H_
+
+#include "bhkShape.h"
+namespace Niflib {
+
+class bhkShapeCollection;
+typedef Ref<bhkShapeCollection> bhkShapeCollectionRef;
+
+/*!
+ * bhkShapeCollection - Havok collision object that uses multiple shapes?
+ */
+
+class bhkShapeCollection : public BHK_SHAPE_COLLECTION_PARENT {
+public:
+	NIFLIB_API bhkShapeCollection();
+	NIFLIB_API ~bhkShapeCollection();
+	//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:
+	BHK_SHAPE_COLLECTION_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/bhkShapePhantom.h b/include/obj/bhkShapePhantom.h
new file mode 100644
index 00000000..171798bc
--- /dev/null
+++ b/include/obj/bhkShapePhantom.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#ifndef _BHKSHAPEPHANTOM_H_
+#define _BHKSHAPEPHANTOM_H_
+
+#include "bhkPhantom.h"
+namespace Niflib {
+
+class bhkShapePhantom;
+typedef Ref<bhkShapePhantom> bhkShapePhantomRef;
+
+/*!
+ * bhkShapePhantom - A Havok phantom that uses a Havok shape object for
+ * its collision volume instead of just a bounding box.
+ */
+
+class bhkShapePhantom : public BHK_SHAPE_PHANTOM_PARENT {
+public:
+	NIFLIB_API bhkShapePhantom();
+	NIFLIB_API ~bhkShapePhantom();
+	//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:
+	BHK_SHAPE_PHANTOM_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/bhkSimpleShapePhantom.h b/include/obj/bhkSimpleShapePhantom.h
index 84f95a0c..bac9022c 100644
--- a/include/obj/bhkSimpleShapePhantom.h
+++ b/include/obj/bhkSimpleShapePhantom.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKSIMPLESHAPEPHANTOM_H_
 #define _BHKSIMPLESHAPEPHANTOM_H_
 
-#include "bhkEntity.h"
+#include "bhkShapePhantom.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/bhkStiffSpringConstraint.h b/include/obj/bhkStiffSpringConstraint.h
index 6c6b2cdf..ea0c2c38 100644
--- a/include/obj/bhkStiffSpringConstraint.h
+++ b/include/obj/bhkStiffSpringConstraint.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _BHKSTIFFSPRINGCONSTRAINT_H_
 #define _BHKSTIFFSPRINGCONSTRAINT_H_
 
-#include "AbhkConstraint.h"
+#include "bhkConstraint.h"
 namespace Niflib {
 
 //#include "../gen/obj_defines.h"
diff --git a/include/obj/hkPackedNiTriStripsData.h b/include/obj/hkPackedNiTriStripsData.h
index ab6c6b8b..acdfdd23 100644
--- a/include/obj/hkPackedNiTriStripsData.h
+++ b/include/obj/hkPackedNiTriStripsData.h
@@ -4,7 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #ifndef _HKPACKEDNITRISTRIPSDATA_H_
 #define _HKPACKEDNITRISTRIPSDATA_H_
 
-#include "AbhkShapeCollection.h"
+#include "bhkShapeCollection.h"
 
 // Include structures
 #include "../gen/hkTriangle.h"
diff --git a/niflib.vcproj b/niflib.vcproj
index d0911c9b..1375d391 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -346,38 +346,10 @@
 			<Filter
 				Name="obj"
 				>
-				<File
-					RelativePath=".\src\obj\AbhkConstraint.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\src\obj\AbhkRagdollConstraint.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\src\obj\AbhkShapeCollection.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\src\obj\ABoneLODController.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\src\obj\AKeyedData.cpp"
-					>
-				</File>
 				<File
 					RelativePath=".\src\obj\AParticleModifier.cpp"
 					>
 				</File>
-				<File
-					RelativePath=".\src\obj\APSysCtlr.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\src\obj\APSysData.cpp"
-					>
-				</File>
 				<File
 					RelativePath=".\src\obj\AvoidNode.cpp"
 					>
@@ -394,6 +366,10 @@
 					RelativePath=".\src\obj\bhkBoxShape.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\bhkBvTreeShape.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\bhkCapsuleShape.cpp"
 					>
@@ -402,6 +378,10 @@
 					RelativePath=".\src\obj\bhkCollisionObject.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\bhkConstraint.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\bhkConvexShape.cpp"
 					>
@@ -442,6 +422,10 @@
 					RelativePath=".\src\obj\bhkMultiSphereShape.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\bhkNiCollisionObject.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\bhkNiTriStripsShape.cpp"
 					>
@@ -450,6 +434,14 @@
 					RelativePath=".\src\obj\bhkPackedNiTriStripsShape.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\bhkPCollisionObject.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\bhkPhantom.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\bhkPrismaticConstraint.cpp"
 					>
@@ -478,6 +470,14 @@
 					RelativePath=".\src\obj\bhkShape.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\bhkShapeCollection.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\bhkShapePhantom.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\bhkSimpleShapePhantom.cpp"
 					>
@@ -526,6 +526,10 @@
 					RelativePath=".\src\obj\BSPSysArrayEmitter.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\BSWindModifier.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\BSXFlags.cpp"
 					>
@@ -570,6 +574,10 @@
 					RelativePath=".\src\obj\NiAVObject.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiAVObjectPalette.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiBillboardNode.cpp"
 					>
@@ -622,6 +630,10 @@
 					RelativePath=".\src\obj\NiBooleanExtraData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiBoolInterpController.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiBoolInterpolator.cpp"
 					>
@@ -666,10 +678,22 @@
 					RelativePath=".\src\obj\NiBSplineData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiBSplineFloatInterpolator.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiBSplineInterpolator.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiBSplinePoint3Interpolator.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\NiBSplineTransformInterpolator.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiCamera.cpp"
 					>
@@ -730,6 +754,10 @@
 					RelativePath=".\src\obj\NiExtraData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiExtraDataController.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiFlipController.cpp"
 					>
@@ -746,6 +774,10 @@
 					RelativePath=".\src\obj\NiFloatExtraDataController.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiFloatInterpController.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiFloatInterpolator.cpp"
 					>
@@ -786,10 +818,18 @@
 					RelativePath=".\src\obj\NiIntegersExtraData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiInterpController.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiInterpolator.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiKeyBasedInterpolator.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiKeyframeController.cpp"
 					>
@@ -930,6 +970,10 @@
 					RelativePath=".\src\obj\NiPlanarCollider.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiPoint3InterpController.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiPoint3Interpolator.cpp"
 					>
@@ -1046,6 +1090,18 @@
 					RelativePath=".\src\obj\NiPSysModifierActiveCtlr.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiPSysModifierBoolCtlr.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\NiPSysModifierCtlr.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\obj\NiPSysModifierFloatCtlr.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiPSysPlanarCollider.cpp"
 					>
@@ -1119,7 +1175,7 @@
 					>
 				</File>
 				<File
-					RelativePath=".\src\obj\NiSingleInterpolatorController.cpp"
+					RelativePath=".\src\obj\NiSingleInterpController.cpp"
 					>
 				</File>
 				<File
@@ -1166,10 +1222,18 @@
 					RelativePath=".\src\obj\NiStringsExtraData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiSwitchNode.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiTextKeyExtraData.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\src\obj\NiTexture.cpp"
+					>
+				</File>
 				<File
 					RelativePath=".\src\obj\NiTextureEffect.cpp"
 					>
@@ -1508,38 +1572,10 @@
 			<Filter
 				Name="obj"
 				>
-				<File
-					RelativePath=".\include\obj\AbhkConstraint.h"
-					>
-				</File>
-				<File
-					RelativePath=".\include\obj\AbhkRagdollConstraint.h"
-					>
-				</File>
-				<File
-					RelativePath=".\include\obj\AbhkShapeCollection.h"
-					>
-				</File>
-				<File
-					RelativePath=".\include\obj\ABoneLODController.h"
-					>
-				</File>
-				<File
-					RelativePath=".\include\obj\AKeyedData.h"
-					>
-				</File>
 				<File
 					RelativePath=".\include\obj\AParticleModifier.h"
 					>
 				</File>
-				<File
-					RelativePath=".\include\obj\APSysCtlr.h"
-					>
-				</File>
-				<File
-					RelativePath=".\include\obj\APSysData.h"
-					>
-				</File>
 				<File
 					RelativePath=".\include\obj\AvoidNode.h"
 					>
@@ -1556,6 +1592,10 @@
 					RelativePath=".\include\obj\bhkBoxShape.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\bhkBvTreeShape.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\bhkCapsuleShape.h"
 					>
@@ -1564,6 +1604,10 @@
 					RelativePath=".\include\obj\bhkCollisionObject.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\bhkConstraint.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\bhkConvexShape.h"
 					>
@@ -1604,6 +1648,10 @@
 					RelativePath=".\include\obj\bhkMultiSphereShape.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\bhkNiCollisionObject.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\bhkNiTriStripsShape.h"
 					>
@@ -1612,6 +1660,14 @@
 					RelativePath=".\include\obj\bhkPackedNiTriStripsShape.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\bhkPCollisionObject.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\bhkPhantom.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\bhkPrismaticConstraint.h"
 					>
@@ -1640,6 +1696,14 @@
 					RelativePath=".\include\obj\bhkShape.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\bhkShapeCollection.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\bhkShapePhantom.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\bhkSimpleShapePhantom.h"
 					>
@@ -1688,6 +1752,10 @@
 					RelativePath=".\include\obj\BSPSysArrayEmitter.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\BSWindModifier.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\BSXFlags.h"
 					>
@@ -1732,6 +1800,10 @@
 					RelativePath=".\include\obj\NiAVObject.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiAVObjectPalette.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiBillboardNode.h"
 					>
@@ -1784,6 +1856,10 @@
 					RelativePath=".\include\obj\NiBooleanExtraData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiBoolInterpController.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiBoolInterpolator.h"
 					>
@@ -1828,10 +1904,22 @@
 					RelativePath=".\include\obj\NiBSplineData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiBSplineFloatInterpolator.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiBSplineInterpolator.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiBSplinePoint3Interpolator.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\NiBSplineTransformInterpolator.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiCamera.h"
 					>
@@ -1892,6 +1980,10 @@
 					RelativePath=".\include\obj\NiExtraData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiExtraDataController.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiFlipController.h"
 					>
@@ -1908,6 +2000,10 @@
 					RelativePath=".\include\obj\NiFloatExtraDataController.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiFloatInterpController.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiFloatInterpolator.h"
 					>
@@ -1948,10 +2044,18 @@
 					RelativePath=".\include\obj\NiIntegersExtraData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiInterpController.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiInterpolator.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiKeyBasedInterpolator.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiKeyframeController.h"
 					>
@@ -2092,6 +2196,10 @@
 					RelativePath=".\include\obj\NiPlanarCollider.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiPoint3InterpController.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiPoint3Interpolator.h"
 					>
@@ -2208,6 +2316,18 @@
 					RelativePath=".\include\obj\NiPSysModifierActiveCtlr.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiPSysModifierBoolCtlr.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\NiPSysModifierCtlr.h"
+					>
+				</File>
+				<File
+					RelativePath=".\include\obj\NiPSysModifierFloatCtlr.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiPSysPlanarCollider.h"
 					>
@@ -2281,7 +2401,7 @@
 					>
 				</File>
 				<File
-					RelativePath=".\include\obj\NiSingleInterpolatorController.h"
+					RelativePath=".\include\obj\NiSingleInterpController.h"
 					>
 				</File>
 				<File
@@ -2328,10 +2448,18 @@
 					RelativePath=".\include\obj\NiStringsExtraData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiSwitchNode.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiTextKeyExtraData.h"
 					>
 				</File>
+				<File
+					RelativePath=".\include\obj\NiTexture.h"
+					>
+				</File>
 				<File
 					RelativePath=".\include\obj\NiTextureEffect.h"
 					>
diff --git a/src/gen/obj_impl.cpp b/src/gen/obj_impl.cpp
index b4d89b59..59bb6c9f 100644
--- a/src/gen/obj_impl.cpp
+++ b/src/gen/obj_impl.cpp
@@ -9,40 +9,72 @@ All rights reserved.  Please see niflib.h for license. */
 using namespace Niflib;
 using namespace std;
 
-#include "../../include/obj/bhkBlendCollisionObject.h"
-#include "../../include/obj/bhkBlendController.h"
-#include "../../include/obj/bhkBoxShape.h"
-#include "../../include/obj/bhkCapsuleShape.h"
-#include "../../include/obj/bhkCollisionObject.h"
-#include "../../include/obj/bhkConvexVerticesShape.h"
-#include "../../include/obj/bhkHingeConstraint.h"
-#include "../../include/obj/bhkLimitedHingeConstraint.h"
-#include "../../include/obj/bhkListShape.h"
-#include "../../include/obj/bhkMalleableConstraint.h"
-#include "../../include/obj/bhkMoppBvTreeShape.h"
-#include "../../include/obj/bhkMultiSphereShape.h"
-#include "../../include/obj/bhkNiTriStripsShape.h"
-#include "../../include/obj/bhkPackedNiTriStripsShape.h"
-#include "../../include/obj/bhkPrismaticConstraint.h"
-#include "../../include/obj/bhkRagdollConstraint.h"
+#include "../../include/obj/bhkSimpleShapePhantom.h"
 #include "../../include/obj/bhkRigidBody.h"
 #include "../../include/obj/bhkRigidBodyT.h"
-#include "../../include/obj/bhkSimpleShapePhantom.h"
-#include "../../include/obj/bhkSPCollisionObject.h"
-#include "../../include/obj/bhkSphereShape.h"
+#include "../../include/obj/bhkLimitedHingeConstraint.h"
+#include "../../include/obj/bhkMalleableConstraint.h"
 #include "../../include/obj/bhkStiffSpringConstraint.h"
+#include "../../include/obj/bhkRagdollConstraint.h"
+#include "../../include/obj/bhkPrismaticConstraint.h"
+#include "../../include/obj/bhkHingeConstraint.h"
 #include "../../include/obj/bhkTransformShape.h"
+#include "../../include/obj/bhkSphereShape.h"
+#include "../../include/obj/bhkCapsuleShape.h"
+#include "../../include/obj/bhkBoxShape.h"
+#include "../../include/obj/bhkConvexVerticesShape.h"
 #include "../../include/obj/bhkConvexTransformShape.h"
+#include "../../include/obj/bhkMultiSphereShape.h"
+#include "../../include/obj/bhkMoppBvTreeShape.h"
+#include "../../include/obj/bhkListShape.h"
+#include "../../include/obj/bhkPackedNiTriStripsShape.h"
+#include "../../include/obj/bhkNiTriStripsShape.h"
+#include "../../include/obj/NiFloatInterpolator.h"
+#include "../../include/obj/NiTransformInterpolator.h"
+#include "../../include/obj/NiPoint3Interpolator.h"
+#include "../../include/obj/NiPathInterpolator.h"
+#include "../../include/obj/NiBoolInterpolator.h"
+#include "../../include/obj/NiBoolTimelineInterpolator.h"
+#include "../../include/obj/NiCollisionObject.h"
+#include "../../include/obj/NiCollisionData.h"
+#include "../../include/obj/bhkCollisionObject.h"
+#include "../../include/obj/bhkBlendCollisionObject.h"
+#include "../../include/obj/bhkSPCollisionObject.h"
+#include "../../include/obj/NiMultiTargetTransformController.h"
+#include "../../include/obj/NiGeomMorpherController.h"
+#include "../../include/obj/NiTransformController.h"
+#include "../../include/obj/NiPSysEmitterCtlr.h"
+#include "../../include/obj/NiPSysModifierActiveCtlr.h"
+#include "../../include/obj/NiPSysEmitterDeclinationCtlr.h"
+#include "../../include/obj/NiPSysEmitterDeclinationVarCtlr.h"
+#include "../../include/obj/NiPSysEmitterInitialRadiusCtlr.h"
+#include "../../include/obj/NiPSysEmitterLifeSpanCtlr.h"
+#include "../../include/obj/NiPSysEmitterSpeedCtlr.h"
+#include "../../include/obj/NiPSysGravityStrengthCtlr.h"
+#include "../../include/obj/NiFlipController.h"
+#include "../../include/obj/NiAlphaController.h"
+#include "../../include/obj/NiTextureTransformController.h"
+#include "../../include/obj/NiLightDimmerController.h"
+#include "../../include/obj/NiVisController.h"
+#include "../../include/obj/NiMaterialColorController.h"
+#include "../../include/obj/NiLightColorController.h"
+#include "../../include/obj/NiFloatExtraDataController.h"
+#include "../../include/obj/NiBoneLODController.h"
+#include "../../include/obj/NiBSBoneLODController.h"
+#include "../../include/obj/bhkBlendController.h"
 #include "../../include/obj/BSBound.h"
 #include "../../include/obj/BSFurnitureMarker.h"
 #include "../../include/obj/BSParentVelocityModifier.h"
 #include "../../include/obj/BSPSysArrayEmitter.h"
-#include "../../include/obj/BSXFlags.h"
+#include "../../include/obj/BSWindModifier.h"
 #include "../../include/obj/hkPackedNiTriStripsData.h"
-#include "../../include/obj/NiAlphaController.h"
 #include "../../include/obj/NiAlphaProperty.h"
 #include "../../include/obj/NiAmbientLight.h"
+#include "../../include/obj/NiParticlesData.h"
+#include "../../include/obj/NiRotatingParticlesData.h"
 #include "../../include/obj/NiAutoNormalParticlesData.h"
+#include "../../include/obj/NiPSysData.h"
+#include "../../include/obj/NiMeshPSysData.h"
 #include "../../include/obj/NiBinaryExtraData.h"
 #include "../../include/obj/NiBinaryVoxelExtraData.h"
 #include "../../include/obj/NiBinaryVoxelData.h"
@@ -50,19 +82,14 @@ using namespace std;
 #include "../../include/obj/NiBlendFloatInterpolator.h"
 #include "../../include/obj/NiBlendPoint3Interpolator.h"
 #include "../../include/obj/NiBlendTransformInterpolator.h"
-#include "../../include/obj/NiBoneLODController.h"
 #include "../../include/obj/NiBoolData.h"
 #include "../../include/obj/NiBooleanExtraData.h"
-#include "../../include/obj/NiBoolInterpolator.h"
-#include "../../include/obj/NiBoolTimelineInterpolator.h"
-#include "../../include/obj/NiBSBoneLODController.h"
 #include "../../include/obj/NiBSplineBasisData.h"
 #include "../../include/obj/NiBSplineCompFloatInterpolator.h"
 #include "../../include/obj/NiBSplineCompPoint3Interpolator.h"
 #include "../../include/obj/NiBSplineCompTransformInterpolator.h"
 #include "../../include/obj/NiBSplineData.h"
 #include "../../include/obj/NiCamera.h"
-#include "../../include/obj/NiCollisionData.h"
 #include "../../include/obj/NiColorData.h"
 #include "../../include/obj/NiColorExtraData.h"
 #include "../../include/obj/NiControllerManager.h"
@@ -71,30 +98,22 @@ using namespace std;
 #include "../../include/obj/NiDefaultAVObjectPalette.h"
 #include "../../include/obj/NiDirectionalLight.h"
 #include "../../include/obj/NiDitherProperty.h"
-#include "../../include/obj/NiFlipController.h"
 #include "../../include/obj/NiRollController.h"
 #include "../../include/obj/NiFloatData.h"
 #include "../../include/obj/NiFloatExtraData.h"
-#include "../../include/obj/NiFloatExtraDataController.h"
-#include "../../include/obj/NiFloatInterpolator.h"
 #include "../../include/obj/NiFloatsExtraData.h"
 #include "../../include/obj/NiFogProperty.h"
-#include "../../include/obj/NiGeomMorpherController.h"
 #include "../../include/obj/NiGravity.h"
 #include "../../include/obj/NiIntegerExtraData.h"
+#include "../../include/obj/BSXFlags.h"
 #include "../../include/obj/NiIntegersExtraData.h"
 #include "../../include/obj/NiKeyframeController.h"
 #include "../../include/obj/BSKeyframeController.h"
 #include "../../include/obj/NiKeyframeData.h"
-#include "../../include/obj/NiLightColorController.h"
-#include "../../include/obj/NiLightDimmerController.h"
 #include "../../include/obj/NiLookAtController.h"
 #include "../../include/obj/NiLookAtInterpolator.h"
-#include "../../include/obj/NiMaterialColorController.h"
 #include "../../include/obj/NiMaterialProperty.h"
-#include "../../include/obj/NiMeshPSysData.h"
 #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"
@@ -114,17 +133,14 @@ using namespace std;
 #include "../../include/obj/NiParticles.h"
 #include "../../include/obj/NiAutoNormalParticles.h"
 #include "../../include/obj/NiParticleMeshes.h"
-#include "../../include/obj/NiParticlesData.h"
 #include "../../include/obj/NiParticleMeshesData.h"
 #include "../../include/obj/NiParticleSystem.h"
 #include "../../include/obj/NiMeshParticleSystem.h"
 #include "../../include/obj/NiParticleSystemController.h"
 #include "../../include/obj/NiBSPArrayController.h"
 #include "../../include/obj/NiPathController.h"
-#include "../../include/obj/NiPathInterpolator.h"
 #include "../../include/obj/NiPixelData.h"
 #include "../../include/obj/NiPlanarCollider.h"
-#include "../../include/obj/NiPoint3Interpolator.h"
 #include "../../include/obj/NiPointLight.h"
 #include "../../include/obj/NiPosData.h"
 #include "../../include/obj/NiPSysAgeDeathModifier.h"
@@ -134,21 +150,12 @@ using namespace std;
 #include "../../include/obj/NiPSysColliderManager.h"
 #include "../../include/obj/NiPSysColorModifier.h"
 #include "../../include/obj/NiPSysCylinderEmitter.h"
-#include "../../include/obj/NiPSysData.h"
 #include "../../include/obj/NiPSysDragModifier.h"
-#include "../../include/obj/NiPSysEmitterCtlr.h"
 #include "../../include/obj/NiPSysEmitterCtlrData.h"
-#include "../../include/obj/NiPSysEmitterDeclinationCtlr.h"
-#include "../../include/obj/NiPSysEmitterDeclinationVarCtlr.h"
-#include "../../include/obj/NiPSysEmitterInitialRadiusCtlr.h"
-#include "../../include/obj/NiPSysEmitterLifeSpanCtlr.h"
-#include "../../include/obj/NiPSysEmitterSpeedCtlr.h"
 #include "../../include/obj/NiPSysGravityModifier.h"
-#include "../../include/obj/NiPSysGravityStrengthCtlr.h"
 #include "../../include/obj/NiPSysGrowFadeModifier.h"
 #include "../../include/obj/NiPSysMeshEmitter.h"
 #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"
@@ -160,7 +167,6 @@ using namespace std;
 #include "../../include/obj/NiRangeLODData.h"
 #include "../../include/obj/NiScreenLODData.h"
 #include "../../include/obj/NiRotatingParticles.h"
-#include "../../include/obj/NiRotatingParticlesData.h"
 #include "../../include/obj/NiSequenceStreamHelper.h"
 #include "../../include/obj/NiShadeProperty.h"
 #include "../../include/obj/NiSkinData.h"
@@ -178,15 +184,12 @@ using namespace std;
 #include "../../include/obj/NiStringsExtraData.h"
 #include "../../include/obj/NiTextKeyExtraData.h"
 #include "../../include/obj/NiTextureEffect.h"
-#include "../../include/obj/NiTextureTransformController.h"
 #include "../../include/obj/NiTextureModeProperty.h"
 #include "../../include/obj/NiImage.h"
 #include "../../include/obj/NiTextureProperty.h"
 #include "../../include/obj/NiMultiTextureProperty.h"
 #include "../../include/obj/NiTexturingProperty.h"
-#include "../../include/obj/NiTransformController.h"
 #include "../../include/obj/NiTransformData.h"
-#include "../../include/obj/NiTransformInterpolator.h"
 #include "../../include/obj/NiTriShape.h"
 #include "../../include/obj/NiTriShapeData.h"
 #include "../../include/obj/NiTriStrips.h"
@@ -198,7 +201,6 @@ using namespace std;
 #include "../../include/obj/NiVectorExtraData.h"
 #include "../../include/obj/NiVertexColorProperty.h"
 #include "../../include/obj/NiVertWeightsExtraData.h"
-#include "../../include/obj/NiVisController.h"
 #include "../../include/obj/NiVisData.h"
 #include "../../include/obj/NiWireframeProperty.h"
 #include "../../include/obj/NiZBufferProperty.h"
@@ -269,31 +271,6 @@ std::list<NiObjectRef> NiObject::InternalGetRefs() const {
 	return refs;
 }
 
-void AKeyedData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::Read( in, link_stack, info );
-}
-
-void AKeyedData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-}
-
-std::string AKeyedData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	return out.str();
-}
-
-void AKeyedData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> AKeyedData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	return refs;
-}
-
 void AParticleModifier::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	NiObject::Read( in, link_stack, info );
@@ -467,514 +444,2270 @@ std::list<NiObjectRef> bhkSerializable::InternalGetRefs() const {
 	return refs;
 }
 
-void AbhkConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkWorldObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	bhkSerializable::Read( in, link_stack, info );
-	NifStream( numBodies, in, info );
-	bodies.resize(numBodies);
-	for (unsigned int i1 = 0; i1 < bodies.size(); i1++) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-	NifStream( priority, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( layer, in, info );
+	NifStream( colFilter, in, info );
+	NifStream( unknownShort, in, info );
 }
 
-void AbhkConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void bhkWorldObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	bhkSerializable::Write( out, link_map, info );
-	numBodies = (unsigned int)(bodies.size());
-	NifStream( numBodies, out, info );
-	for (unsigned int i1 = 0; i1 < bodies.size(); i1++) {
-		if ( bodies[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(bodies[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-	NifStream( priority, out, info );
+	if ( shape != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	NifStream( layer, out, info );
+	NifStream( colFilter, out, info );
+	NifStream( unknownShort, out, info );
 }
 
-std::string AbhkConstraint::InternalAsString( bool verbose ) const {
+std::string bhkWorldObject::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << bhkSerializable::asString();
-	numBodies = (unsigned int)(bodies.size());
-	out << "  Num Bodies:  " << numBodies << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < bodies.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 << "    Bodies[" << i1 << "]:  " << bodies[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Priority:  " << priority << endl;
+	out << "  Shape:  " << shape << endl;
+	out << "  Layer:  " << layer << endl;
+	out << "  Col Filter:  " << colFilter << endl;
+	out << "  Unknown Short:  " << unknownShort << endl;
 	return out.str();
 }
 
-void AbhkConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkWorldObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	bhkSerializable::FixLinks( objects, link_stack, info );
-	for (unsigned int i1 = 0; i1 < bodies.size(); i1++) {
-		bodies[i1] = FixLink<bhkShape>( objects, link_stack, info );
-	};
+	shape = FixLink<bhkShape>( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> AbhkConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> bhkWorldObject::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = bhkSerializable::GetRefs();
-	for (unsigned int i1 = 0; i1 < bodies.size(); i1++) {
-	};
+	if ( shape != NULL )
+		refs.push_back(StaticCast<NiObject>(shape));
 	return refs;
 }
 
-void AbhkRagdollConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::Read( in, link_stack, info );
-	NifStream( ragdoll.pivotA, in, info );
-	NifStream( ragdoll.planeA, in, info );
-	NifStream( ragdoll.twistA, in, info );
-	NifStream( ragdoll.pivotB, in, info );
-	NifStream( ragdoll.planeB, in, info );
-	NifStream( ragdoll.twistB, in, info );
-	NifStream( ragdoll.coneMinAngle, in, info );
-	NifStream( ragdoll.planeMinAngle, in, info );
-	NifStream( ragdoll.planeMaxAngle, in, info );
-	NifStream( ragdoll.twistMinAngle, in, info );
-	NifStream( ragdoll.twistMaxAngle, in, info );
-	NifStream( ragdoll.maxFriction, in, info );
+void bhkPhantom::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkWorldObject::Read( in, link_stack, info );
 }
 
-void AbhkRagdollConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkConstraint::Write( out, link_map, info );
-	NifStream( ragdoll.pivotA, out, info );
-	NifStream( ragdoll.planeA, out, info );
-	NifStream( ragdoll.twistA, out, info );
-	NifStream( ragdoll.pivotB, out, info );
-	NifStream( ragdoll.planeB, out, info );
-	NifStream( ragdoll.twistB, out, info );
-	NifStream( ragdoll.coneMinAngle, out, info );
-	NifStream( ragdoll.planeMinAngle, out, info );
-	NifStream( ragdoll.planeMaxAngle, out, info );
-	NifStream( ragdoll.twistMinAngle, out, info );
-	NifStream( ragdoll.twistMaxAngle, out, info );
-	NifStream( ragdoll.maxFriction, out, info );
+void bhkPhantom::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkWorldObject::Write( out, link_map, info );
 }
 
-std::string AbhkRagdollConstraint::InternalAsString( bool verbose ) const {
+std::string bhkPhantom::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkConstraint::asString();
-	out << "  Pivot A:  " << ragdoll.pivotA << endl;
-	out << "  Plane A:  " << ragdoll.planeA << endl;
-	out << "  Twist A:  " << ragdoll.twistA << endl;
-	out << "  Pivot B:  " << ragdoll.pivotB << endl;
-	out << "  Plane B:  " << ragdoll.planeB << endl;
-	out << "  Twist B:  " << ragdoll.twistB << endl;
-	out << "  Cone Min Angle:  " << ragdoll.coneMinAngle << endl;
-	out << "  Plane Min Angle:  " << ragdoll.planeMinAngle << endl;
-	out << "  Plane Max Angle:  " << ragdoll.planeMaxAngle << endl;
-	out << "  Twist Min Angle:  " << ragdoll.twistMinAngle << endl;
-	out << "  Twist Max Angle:  " << ragdoll.twistMaxAngle << endl;
-	out << "  Max Friction:  " << ragdoll.maxFriction << endl;
+	out << bhkWorldObject::asString();
 	return out.str();
 }
 
-void AbhkRagdollConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::FixLinks( objects, link_stack, info );
+void bhkPhantom::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkWorldObject::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> AbhkRagdollConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> bhkPhantom::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkConstraint::GetRefs();
+	refs = bhkWorldObject::GetRefs();
 	return refs;
 }
 
-void bhkShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSerializable::Read( in, link_stack, info );
+void bhkShapePhantom::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkPhantom::Read( in, link_stack, info );
 }
 
-void bhkShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkSerializable::Write( out, link_map, info );
+void bhkShapePhantom::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkPhantom::Write( out, link_map, info );
 }
 
-std::string bhkShape::InternalAsString( bool verbose ) const {
+std::string bhkShapePhantom::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkSerializable::asString();
+	out << bhkPhantom::asString();
 	return out.str();
 }
 
-void bhkShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSerializable::FixLinks( objects, link_stack, info );
+void bhkShapePhantom::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkPhantom::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkShape::InternalGetRefs() const {
+std::list<NiObjectRef> bhkShapePhantom::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkSerializable::GetRefs();
+	refs = bhkPhantom::GetRefs();
 	return refs;
 }
 
-void AbhkShapeCollection::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::Read( in, link_stack, info );
+void bhkSimpleShapePhantom::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShapePhantom::Read( in, link_stack, info );
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		NifStream( unkownFloats[i1], in, info );
+	};
+	for (unsigned int i1 = 0; i1 < 3; i1++) {
+		for (unsigned int i2 = 0; i2 < 5; i2++) {
+			NifStream( unknownFloats2[i1][i2], in, info );
+		};
+	};
+	NifStream( unknownFloat, in, info );
 }
 
-void AbhkShapeCollection::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkShape::Write( out, link_map, info );
+void bhkSimpleShapePhantom::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShapePhantom::Write( out, link_map, info );
+	for (unsigned int i1 = 0; i1 < 7; i1++) {
+		NifStream( unkownFloats[i1], out, info );
+	};
+	for (unsigned int i1 = 0; i1 < 3; i1++) {
+		for (unsigned int i2 = 0; i2 < 5; i2++) {
+			NifStream( unknownFloats2[i1][i2], out, info );
+		};
+	};
+	NifStream( unknownFloat, out, info );
 }
 
-std::string AbhkShapeCollection::InternalAsString( bool verbose ) const {
+std::string bhkSimpleShapePhantom::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkShape::asString();
-	return out.str();
-}
-
-void AbhkShapeCollection::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> AbhkShapeCollection::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = bhkShape::GetRefs();
-	return refs;
-}
-
-void bhkSphereRepShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::Read( in, link_stack, info );
-	NifStream( material, in, info );
-}
-
-void bhkSphereRepShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkShape::Write( out, link_map, info );
-	NifStream( material, out, info );
-}
-
-std::string bhkSphereRepShape::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << bhkShape::asString();
-	out << "  Material:  " << material << endl;
-	return out.str();
-}
-
-void bhkSphereRepShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> bhkSphereRepShape::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = bhkShape::GetRefs();
-	return refs;
-}
-
-void bhkConvexShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::Read( in, link_stack, info );
-}
-
-void bhkConvexShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkSphereRepShape::Write( out, link_map, info );
-}
-
-std::string bhkConvexShape::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << bhkSphereRepShape::asString();
-	return out.str();
-}
-
-void bhkConvexShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> bhkConvexShape::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = bhkSphereRepShape::GetRefs();
-	return refs;
-}
-
-void bhkWorldObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::Read( in, link_stack, info );
-}
-
-void bhkWorldObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkShape::Write( out, link_map, info );
-}
-
-std::string bhkWorldObject::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << bhkShape::asString();
+	out << bhkShapePhantom::asString();
+	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 << "    Unkown Floats[" << i1 << "]:  " << unkownFloats[i1] << endl;
+		array_output_count++;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 3; 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 < 5; i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				break;
+			};
+			out << "      Unknown Floats 2[" << i2 << "]:  " << unknownFloats2[i1][i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Unknown Float:  " << unknownFloat << endl;
 	return out.str();
 }
 
-void bhkWorldObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::FixLinks( objects, link_stack, info );
+void bhkSimpleShapePhantom::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShapePhantom::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkWorldObject::InternalGetRefs() const {
+std::list<NiObjectRef> bhkSimpleShapePhantom::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkShape::GetRefs();
+	refs = bhkShapePhantom::GetRefs();
 	return refs;
 }
 
 void bhkEntity::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
 	bhkWorldObject::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( layer, in, info );
-	NifStream( colFilter, in, info );
-	NifStream( unknownShort, in, info );
 }
 
 void bhkEntity::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	bhkWorldObject::Write( out, link_map, info );
-	if ( shape != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( layer, out, info );
-	NifStream( colFilter, out, info );
-	NifStream( unknownShort, out, info );
 }
 
 std::string bhkEntity::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
 	out << bhkWorldObject::asString();
-	out << "  Shape:  " << shape << endl;
-	out << "  Layer:  " << layer << endl;
-	out << "  Col Filter:  " << colFilter << endl;
-	out << "  Unknown Short:  " << unknownShort << endl;
 	return out.str();
 }
 
 void bhkEntity::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	bhkWorldObject::FixLinks( objects, link_stack, info );
-	shape = FixLink<bhkShape>( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> bhkEntity::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = bhkWorldObject::GetRefs();
-	if ( shape != NULL )
-		refs.push_back(StaticCast<NiObject>(shape));
-	return refs;
-}
-
-void NiCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( unknownShort, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-	if ( parent != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(parent) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( unknownShort, out, info );
-	if ( body != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(body) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiCollisionObject::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	out << "  Parent:  " << parent << endl;
-	out << "  Unknown Short:  " << unknownShort << endl;
-	out << "  Body:  " << body << endl;
-	return out.str();
-}
-
-void NiCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	parent = FixLink<NiAVObject>( objects, link_stack, info );
-	body = FixLink<NiObject>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiCollisionObject::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	if ( body != NULL )
-		refs.push_back(StaticCast<NiObject>(body));
 	return refs;
 }
 
-void NiExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkRigidBody::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	if ( info.version >= 0x0A000100 ) {
-		NifStream( name, in, info );
+	bhkEntity::Read( in, link_stack, info );
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		NifStream( unknown5Floats[i1], in, info );
 	};
-	if ( info.version <= 0x04020200 ) {
+	if ( info.version >= 0x14000004 ) {
+		for (unsigned int i2 = 0; i2 < 4; i2++) {
+			NifStream( unknown4Shorts[i2], in, info );
+		};
+		NifStream( layerCopy, in, info );
+		NifStream( colFilterCopy, in, info );
+		for (unsigned int i2 = 0; i2 < 7; i2++) {
+			NifStream( unknown7Shorts[i2], in, info );
+		};
+	};
+	NifStream( translation, in, info );
+	NifStream( unknownFloat00, in, info );
+	NifStream( rotation.x, in, info );
+	NifStream( rotation.y, in, info );
+	NifStream( rotation.z, in, info );
+	NifStream( rotation.w, in, info );
+	NifStream( linearVelocity, in, info );
+	NifStream( unknownFloat01, in, info );
+	NifStream( angularVelocity, in, info );
+	NifStream( unknownFloat02, in, info );
+	for (unsigned int i1 = 0; i1 < 12; i1++) {
+		NifStream( inertia[i1], in, info );
+	};
+	NifStream( center, in, info );
+	NifStream( unknownFloat03, in, info );
+	NifStream( mass, in, info );
+	NifStream( linearDamping, in, info );
+	NifStream( angularDamping, in, info );
+	NifStream( friction, in, info );
+	NifStream( restitution, in, info );
+	NifStream( maxLinearVelocity, in, info );
+	NifStream( maxAngularVelocity, in, info );
+	NifStream( penetrationDepth, in, info );
+	NifStream( motionSystem, in, info );
+	NifStream( unknownByte1, in, info );
+	NifStream( unknownByte2, in, info );
+	NifStream( qualityType, in, info );
+	NifStream( unknownInt6, in, info );
+	NifStream( unknownInt7, in, info );
+	NifStream( unknownInt8, in, info );
+	NifStream( numConstraints, in, info );
+	constraints.resize(numConstraints);
+	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
 		NifStream( block_num, in, info );
 		link_stack.push_back( block_num );
 	};
+	NifStream( unknownInt6, in, info );
 }
 
-void NiExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-	if ( info.version >= 0x0A000100 ) {
-		NifStream( name, out, info );
-	};
-	if ( info.version <= 0x04020200 ) {
-		if ( nextExtraData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(nextExtraData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+void bhkRigidBody::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkEntity::Write( out, link_map, info );
+	numConstraints = (unsigned int)(constraints.size());
+	for (unsigned int i1 = 0; i1 < 5; i1++) {
+		NifStream( unknown5Floats[i1], out, info );
 	};
-}
-
-std::string NiExtraData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	out << "  Name:  " << name << endl;
-	out << "  Next Extra Data:  " << nextExtraData << endl;
-	return out.str();
-}
-
-void NiExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x04020200 ) {
-		nextExtraData = FixLink<NiExtraData>( objects, link_stack, info );
+	if ( info.version >= 0x14000004 ) {
+		for (unsigned int i2 = 0; i2 < 4; i2++) {
+			NifStream( unknown4Shorts[i2], out, info );
+		};
+		NifStream( layerCopy, out, info );
+		NifStream( colFilterCopy, out, info );
+		for (unsigned int i2 = 0; i2 < 7; i2++) {
+			NifStream( unknown7Shorts[i2], out, info );
+		};
 	};
+	NifStream( translation, out, info );
+	NifStream( unknownFloat00, out, info );
+	NifStream( rotation.x, out, info );
+	NifStream( rotation.y, out, info );
+	NifStream( rotation.z, out, info );
+	NifStream( rotation.w, out, info );
+	NifStream( linearVelocity, out, info );
+	NifStream( unknownFloat01, out, info );
+	NifStream( angularVelocity, out, info );
+	NifStream( unknownFloat02, out, info );
+	for (unsigned int i1 = 0; i1 < 12; i1++) {
+		NifStream( inertia[i1], out, info );
+	};
+	NifStream( center, out, info );
+	NifStream( unknownFloat03, out, info );
+	NifStream( mass, out, info );
+	NifStream( linearDamping, out, info );
+	NifStream( angularDamping, out, info );
+	NifStream( friction, out, info );
+	NifStream( restitution, out, info );
+	NifStream( maxLinearVelocity, out, info );
+	NifStream( maxAngularVelocity, out, info );
+	NifStream( penetrationDepth, out, info );
+	NifStream( motionSystem, out, info );
+	NifStream( unknownByte1, out, info );
+	NifStream( unknownByte2, out, info );
+	NifStream( qualityType, out, info );
+	NifStream( unknownInt6, out, info );
+	NifStream( unknownInt7, out, info );
+	NifStream( unknownInt8, out, info );
+	NifStream( numConstraints, out, info );
+	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
+		if ( constraints[i1] != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(constraints[i1]) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	NifStream( unknownInt6, out, info );
 }
 
-std::list<NiObjectRef> NiExtraData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	if ( nextExtraData != NULL )
-		refs.push_back(StaticCast<NiObject>(nextExtraData));
-	return refs;
-}
-
-void NiInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::Read( in, link_stack, info );
-}
-
-void NiInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-}
-
-std::string NiInterpolator::InternalAsString( bool verbose ) const {
+std::string bhkRigidBody::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiObject::asString();
+	out << bhkEntity::asString();
+	numConstraints = (unsigned int)(constraints.size());
+	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 Floats[" << i1 << "]:  " << unknown5Floats[i1] << endl;
+		array_output_count++;
+	};
+	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 << "  Layer Copy:  " << layerCopy << endl;
+	out << "  Col Filter Copy:  " << colFilterCopy << 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 Shorts[" << i1 << "]:  " << unknown7Shorts[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Translation:  " << translation << endl;
+	out << "  Unknown Float 00:  " << unknownFloat00 << endl;
+	out << "  x:  " << rotation.x << endl;
+	out << "  y:  " << rotation.y << endl;
+	out << "  z:  " << rotation.z << endl;
+	out << "  w:  " << rotation.w << endl;
+	out << "  Linear Velocity:  " << linearVelocity << endl;
+	out << "  Unknown Float 01:  " << unknownFloat01 << endl;
+	out << "  Angular Velocity:  " << angularVelocity << endl;
+	out << "  Unknown Float 02:  " << unknownFloat02 << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 12; 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 << "    Inertia[" << i1 << "]:  " << inertia[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Center:  " << center << endl;
+	out << "  Unknown Float 03:  " << unknownFloat03 << endl;
+	out << "  Mass:  " << mass << endl;
+	out << "  Linear Damping:  " << linearDamping << endl;
+	out << "  Angular Damping:  " << angularDamping << endl;
+	out << "  Friction:  " << friction << endl;
+	out << "  Restitution:  " << restitution << endl;
+	out << "  Max Linear Velocity:  " << maxLinearVelocity << endl;
+	out << "  Max Angular Velocity:  " << maxAngularVelocity << endl;
+	out << "  Penetration Depth:  " << penetrationDepth << endl;
+	out << "  Motion System:  " << motionSystem << endl;
+	out << "  Unknown Byte 1:  " << unknownByte1 << endl;
+	out << "  Unknown Byte 2:  " << unknownByte2 << endl;
+	out << "  Quality Type:  " << qualityType << endl;
+	out << "  Unknown Int 6:  " << unknownInt6 << endl;
+	out << "  Unknown Int 7:  " << unknownInt7 << endl;
+	out << "  Unknown Int 8:  " << unknownInt8 << endl;
+	out << "  Num Constraints:  " << numConstraints << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < constraints.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 << "    Constraints[" << i1 << "]:  " << constraints[i1] << endl;
+		array_output_count++;
+	};
 	return out.str();
 }
 
-void NiInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
+void bhkRigidBody::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkEntity::FixLinks( objects, link_stack, info );
+	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
+		constraints[i1] = FixLink<bhkConstraint>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> NiInterpolator::InternalGetRefs() const {
+std::list<NiObjectRef> bhkRigidBody::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
+	refs = bhkEntity::GetRefs();
+	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
+		if ( constraints[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(constraints[i1]));
+	};
 	return refs;
 }
 
-void NiBlendInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( unknownShort, in, info );
-	NifStream( unknownInt, in, info );
+void bhkRigidBodyT::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkRigidBody::Read( in, link_stack, info );
 }
 
-void NiBlendInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( unknownShort, out, info );
-	NifStream( unknownInt, out, info );
+void bhkRigidBodyT::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkRigidBody::Write( out, link_map, info );
 }
 
-std::string NiBlendInterpolator::InternalAsString( bool verbose ) const {
+std::string bhkRigidBodyT::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Unknown Short:  " << unknownShort << endl;
-	out << "  Unknown Int:  " << unknownInt << endl;
+	out << bhkRigidBody::asString();
 	return out.str();
 }
 
-void NiBlendInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
+void bhkRigidBodyT::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkRigidBody::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiBlendInterpolator::InternalGetRefs() const {
+std::list<NiObjectRef> bhkRigidBodyT::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
+	refs = bhkRigidBody::GetRefs();
 	return refs;
 }
 
-void NiBSplineInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( startTime, in, info );
-	NifStream( stopTime, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
+	bhkSerializable::Read( in, link_stack, info );
+	NifStream( numEntities, in, info );
+	entities.resize(numEntities);
+	for (unsigned int i1 = 0; i1 < entities.size(); i1++) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+	NifStream( priority, in, info );
 }
 
-void NiBSplineInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( startTime, out, info );
-	NifStream( stopTime, out, info );
-	if ( splineData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(splineData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( basisData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(basisData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+void bhkConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkSerializable::Write( out, link_map, info );
+	numEntities = (unsigned int)(entities.size());
+	NifStream( numEntities, out, info );
+	for (unsigned int i1 = 0; i1 < entities.size(); i1++) {
+		if ( entities[i1] != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(entities[i1]) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	NifStream( priority, out, info );
 }
 
-std::string NiBSplineInterpolator::InternalAsString( bool verbose ) const {
+std::string bhkConstraint::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Start Time:  " << startTime << endl;
-	out << "  Stop Time:  " << stopTime << endl;
-	out << "  Spline Data:  " << splineData << endl;
-	out << "  Basis Data:  " << basisData << endl;
+	out << bhkSerializable::asString();
+	numEntities = (unsigned int)(entities.size());
+	out << "  Num Entities:  " << numEntities << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < entities.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 << "    Entities[" << i1 << "]:  " << entities[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Priority:  " << priority << endl;
 	return out.str();
 }
 
-void NiBSplineInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
-	splineData = FixLink<NiBSplineData>( objects, link_stack, info );
-	basisData = FixLink<NiBSplineBasisData>( objects, link_stack, info );
+void bhkConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSerializable::FixLinks( objects, link_stack, info );
+	for (unsigned int i1 = 0; i1 < entities.size(); i1++) {
+		entities[i1] = FixLink<bhkEntity>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> NiBSplineInterpolator::InternalGetRefs() const {
+std::list<NiObjectRef> bhkConstraint::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( splineData != NULL )
-		refs.push_back(StaticCast<NiObject>(splineData));
-	if ( basisData != NULL )
-		refs.push_back(StaticCast<NiObject>(basisData));
+	refs = bhkSerializable::GetRefs();
+	for (unsigned int i1 = 0; i1 < entities.size(); i1++) {
+	};
 	return refs;
 }
 
-void NiObjectNET::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	NifStream( name, in, info );
-	if ( info.version <= 0x04020200 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
+void bhkLimitedHingeConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::Read( in, link_stack, info );
+	NifStream( limitedHinge.pivotA, in, info );
+	NifStream( limitedHinge.axleA, in, info );
+	NifStream( limitedHinge.perp2axleina1, in, info );
+	NifStream( limitedHinge.perp2axleina2, in, info );
+	NifStream( limitedHinge.pivotB, in, info );
+	NifStream( limitedHinge.axleB, in, info );
+	NifStream( limitedHinge.perp2axleinb2, in, info );
+	NifStream( limitedHinge.minAngle, in, info );
+	NifStream( limitedHinge.maxAngle, in, info );
+	NifStream( limitedHinge.maxFriction, in, info );
+}
+
+void bhkLimitedHingeConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConstraint::Write( out, link_map, info );
+	NifStream( limitedHinge.pivotA, out, info );
+	NifStream( limitedHinge.axleA, out, info );
+	NifStream( limitedHinge.perp2axleina1, out, info );
+	NifStream( limitedHinge.perp2axleina2, out, info );
+	NifStream( limitedHinge.pivotB, out, info );
+	NifStream( limitedHinge.axleB, out, info );
+	NifStream( limitedHinge.perp2axleinb2, out, info );
+	NifStream( limitedHinge.minAngle, out, info );
+	NifStream( limitedHinge.maxAngle, out, info );
+	NifStream( limitedHinge.maxFriction, out, info );
+}
+
+std::string bhkLimitedHingeConstraint::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConstraint::asString();
+	out << "  Pivot A:  " << limitedHinge.pivotA << endl;
+	out << "  Axle A:  " << limitedHinge.axleA << endl;
+	out << "  Perp2AxleInA1:  " << limitedHinge.perp2axleina1 << endl;
+	out << "  Perp2AxleInA2:  " << limitedHinge.perp2axleina2 << endl;
+	out << "  Pivot B:  " << limitedHinge.pivotB << endl;
+	out << "  Axle B:  " << limitedHinge.axleB << endl;
+	out << "  Perp2AxleInB2:  " << limitedHinge.perp2axleinb2 << endl;
+	out << "  Min Angle:  " << limitedHinge.minAngle << endl;
+	out << "  Max Angle:  " << limitedHinge.maxAngle << endl;
+	out << "  Max Friction:  " << limitedHinge.maxFriction << endl;
+	return out.str();
+}
+
+void bhkLimitedHingeConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkLimitedHingeConstraint::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConstraint::GetRefs();
+	return refs;
+}
+
+void bhkMalleableConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	bhkConstraint::Read( in, link_stack, info );
+	NifStream( type, in, info );
+	NifStream( unknownInt2, 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( unknownInt3, in, info );
+	if ( (type == 7) ) {
+		NifStream( ragdoll.pivotA, in, info );
+		NifStream( ragdoll.planeA, in, info );
+		NifStream( ragdoll.twistA, in, info );
+		NifStream( ragdoll.pivotB, in, info );
+		NifStream( ragdoll.planeB, in, info );
+		NifStream( ragdoll.twistB, in, info );
+		NifStream( ragdoll.coneMinAngle, in, info );
+		NifStream( ragdoll.planeMinAngle, in, info );
+		NifStream( ragdoll.planeMaxAngle, in, info );
+		NifStream( ragdoll.twistMinAngle, in, info );
+		NifStream( ragdoll.twistMaxAngle, in, info );
+		NifStream( ragdoll.maxFriction, in, info );
+	};
+	if ( (type == 2) ) {
+		NifStream( limitedHinge.pivotA, in, info );
+		NifStream( limitedHinge.axleA, in, info );
+		NifStream( limitedHinge.perp2axleina1, in, info );
+		NifStream( limitedHinge.perp2axleina2, in, info );
+		NifStream( limitedHinge.pivotB, in, info );
+		NifStream( limitedHinge.axleB, in, info );
+		NifStream( limitedHinge.perp2axleinb2, in, info );
+		NifStream( limitedHinge.minAngle, in, info );
+		NifStream( limitedHinge.maxAngle, in, info );
+		NifStream( limitedHinge.maxFriction, in, info );
+	};
+	NifStream( tau, in, info );
+	NifStream( damping, in, info );
+}
+
+void bhkMalleableConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConstraint::Write( out, link_map, info );
+	NifStream( type, out, info );
+	NifStream( unknownInt2, out, info );
+	if ( unknownLink1 != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( unknownLink2 != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	NifStream( unknownInt3, out, info );
+	if ( (type == 7) ) {
+		NifStream( ragdoll.pivotA, out, info );
+		NifStream( ragdoll.planeA, out, info );
+		NifStream( ragdoll.twistA, out, info );
+		NifStream( ragdoll.pivotB, out, info );
+		NifStream( ragdoll.planeB, out, info );
+		NifStream( ragdoll.twistB, out, info );
+		NifStream( ragdoll.coneMinAngle, out, info );
+		NifStream( ragdoll.planeMinAngle, out, info );
+		NifStream( ragdoll.planeMaxAngle, out, info );
+		NifStream( ragdoll.twistMinAngle, out, info );
+		NifStream( ragdoll.twistMaxAngle, out, info );
+		NifStream( ragdoll.maxFriction, out, info );
+	};
+	if ( (type == 2) ) {
+		NifStream( limitedHinge.pivotA, out, info );
+		NifStream( limitedHinge.axleA, out, info );
+		NifStream( limitedHinge.perp2axleina1, out, info );
+		NifStream( limitedHinge.perp2axleina2, out, info );
+		NifStream( limitedHinge.pivotB, out, info );
+		NifStream( limitedHinge.axleB, out, info );
+		NifStream( limitedHinge.perp2axleinb2, out, info );
+		NifStream( limitedHinge.minAngle, out, info );
+		NifStream( limitedHinge.maxAngle, out, info );
+		NifStream( limitedHinge.maxFriction, out, info );
+	};
+	NifStream( tau, out, info );
+	NifStream( damping, out, info );
+}
+
+std::string bhkMalleableConstraint::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConstraint::asString();
+	out << "  Type:  " << type << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Unknown Link 1:  " << unknownLink1 << endl;
+	out << "  Unknown Link 2:  " << unknownLink2 << endl;
+	out << "  Unknown Int 3:  " << unknownInt3 << endl;
+	if ( (type == 7) ) {
+		out << "    Pivot A:  " << ragdoll.pivotA << endl;
+		out << "    Plane A:  " << ragdoll.planeA << endl;
+		out << "    Twist A:  " << ragdoll.twistA << endl;
+		out << "    Pivot B:  " << ragdoll.pivotB << endl;
+		out << "    Plane B:  " << ragdoll.planeB << endl;
+		out << "    Twist B:  " << ragdoll.twistB << endl;
+		out << "    Cone Min Angle:  " << ragdoll.coneMinAngle << endl;
+		out << "    Plane Min Angle:  " << ragdoll.planeMinAngle << endl;
+		out << "    Plane Max Angle:  " << ragdoll.planeMaxAngle << endl;
+		out << "    Twist Min Angle:  " << ragdoll.twistMinAngle << endl;
+		out << "    Twist Max Angle:  " << ragdoll.twistMaxAngle << endl;
+		out << "    Max Friction:  " << ragdoll.maxFriction << endl;
+	};
+	if ( (type == 2) ) {
+		out << "    Pivot A:  " << limitedHinge.pivotA << endl;
+		out << "    Axle A:  " << limitedHinge.axleA << endl;
+		out << "    Perp2AxleInA1:  " << limitedHinge.perp2axleina1 << endl;
+		out << "    Perp2AxleInA2:  " << limitedHinge.perp2axleina2 << endl;
+		out << "    Pivot B:  " << limitedHinge.pivotB << endl;
+		out << "    Axle B:  " << limitedHinge.axleB << endl;
+		out << "    Perp2AxleInB2:  " << limitedHinge.perp2axleinb2 << endl;
+		out << "    Min Angle:  " << limitedHinge.minAngle << endl;
+		out << "    Max Angle:  " << limitedHinge.maxAngle << endl;
+		out << "    Max Friction:  " << limitedHinge.maxFriction << endl;
+	};
+	out << "  Tau:  " << tau << endl;
+	out << "  Damping:  " << damping << endl;
+	return out.str();
+}
+
+void bhkMalleableConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::FixLinks( objects, link_stack, info );
+	unknownLink1 = FixLink<NiObject>( objects, link_stack, info );
+	unknownLink2 = FixLink<NiObject>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkMalleableConstraint::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConstraint::GetRefs();
+	if ( unknownLink1 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink1));
+	if ( unknownLink2 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink2));
+	return refs;
+}
+
+void bhkStiffSpringConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::Read( in, link_stack, info );
+	NifStream( pivotA, in, info );
+	NifStream( pivotB, in, info );
+	NifStream( length, in, info );
+}
+
+void bhkStiffSpringConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConstraint::Write( out, link_map, info );
+	NifStream( pivotA, out, info );
+	NifStream( pivotB, out, info );
+	NifStream( length, out, info );
+}
+
+std::string bhkStiffSpringConstraint::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConstraint::asString();
+	out << "  Pivot A:  " << pivotA << endl;
+	out << "  Pivot B:  " << pivotB << endl;
+	out << "  Length:  " << length << endl;
+	return out.str();
+}
+
+void bhkStiffSpringConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkStiffSpringConstraint::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConstraint::GetRefs();
+	return refs;
+}
+
+void bhkRagdollConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::Read( in, link_stack, info );
+	NifStream( ragdoll.pivotA, in, info );
+	NifStream( ragdoll.planeA, in, info );
+	NifStream( ragdoll.twistA, in, info );
+	NifStream( ragdoll.pivotB, in, info );
+	NifStream( ragdoll.planeB, in, info );
+	NifStream( ragdoll.twistB, in, info );
+	NifStream( ragdoll.coneMinAngle, in, info );
+	NifStream( ragdoll.planeMinAngle, in, info );
+	NifStream( ragdoll.planeMaxAngle, in, info );
+	NifStream( ragdoll.twistMinAngle, in, info );
+	NifStream( ragdoll.twistMaxAngle, in, info );
+	NifStream( ragdoll.maxFriction, in, info );
+}
+
+void bhkRagdollConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConstraint::Write( out, link_map, info );
+	NifStream( ragdoll.pivotA, out, info );
+	NifStream( ragdoll.planeA, out, info );
+	NifStream( ragdoll.twistA, out, info );
+	NifStream( ragdoll.pivotB, out, info );
+	NifStream( ragdoll.planeB, out, info );
+	NifStream( ragdoll.twistB, out, info );
+	NifStream( ragdoll.coneMinAngle, out, info );
+	NifStream( ragdoll.planeMinAngle, out, info );
+	NifStream( ragdoll.planeMaxAngle, out, info );
+	NifStream( ragdoll.twistMinAngle, out, info );
+	NifStream( ragdoll.twistMaxAngle, out, info );
+	NifStream( ragdoll.maxFriction, out, info );
+}
+
+std::string bhkRagdollConstraint::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConstraint::asString();
+	out << "  Pivot A:  " << ragdoll.pivotA << endl;
+	out << "  Plane A:  " << ragdoll.planeA << endl;
+	out << "  Twist A:  " << ragdoll.twistA << endl;
+	out << "  Pivot B:  " << ragdoll.pivotB << endl;
+	out << "  Plane B:  " << ragdoll.planeB << endl;
+	out << "  Twist B:  " << ragdoll.twistB << endl;
+	out << "  Cone Min Angle:  " << ragdoll.coneMinAngle << endl;
+	out << "  Plane Min Angle:  " << ragdoll.planeMinAngle << endl;
+	out << "  Plane Max Angle:  " << ragdoll.planeMaxAngle << endl;
+	out << "  Twist Min Angle:  " << ragdoll.twistMinAngle << endl;
+	out << "  Twist Max Angle:  " << ragdoll.twistMaxAngle << endl;
+	out << "  Max Friction:  " << ragdoll.maxFriction << endl;
+	return out.str();
+}
+
+void bhkRagdollConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkRagdollConstraint::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConstraint::GetRefs();
+	return refs;
+}
+
+void bhkPrismaticConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::Read( in, link_stack, info );
+	for (unsigned int i1 = 0; i1 < 8; i1++) {
+		NifStream( unknownVectors[i1], in, info );
+	};
+	for (unsigned int i1 = 0; i1 < 3; i1++) {
+		NifStream( unknownFloats2[i1], in, info );
+	};
+}
+
+void bhkPrismaticConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConstraint::Write( out, link_map, info );
+	for (unsigned int i1 = 0; i1 < 8; i1++) {
+		NifStream( unknownVectors[i1], out, info );
+	};
+	for (unsigned int i1 = 0; i1 < 3; i1++) {
+		NifStream( unknownFloats2[i1], out, info );
+	};
+}
+
+std::string bhkPrismaticConstraint::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConstraint::asString();
+	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 Vectors[" << i1 << "]:  " << unknownVectors[i1] << endl;
+		array_output_count++;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 3; 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 Floats 2[" << i1 << "]:  " << unknownFloats2[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void bhkPrismaticConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkPrismaticConstraint::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConstraint::GetRefs();
+	return refs;
+}
+
+void bhkHingeConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::Read( in, link_stack, info );
+	NifStream( pivotA, in, info );
+	NifStream( perp2axleina1, in, info );
+	NifStream( perp2axleina2, in, info );
+	NifStream( pivotB, in, info );
+	NifStream( axleB, in, info );
+}
+
+void bhkHingeConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConstraint::Write( out, link_map, info );
+	NifStream( pivotA, out, info );
+	NifStream( perp2axleina1, out, info );
+	NifStream( perp2axleina2, out, info );
+	NifStream( pivotB, out, info );
+	NifStream( axleB, out, info );
+}
+
+std::string bhkHingeConstraint::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConstraint::asString();
+	out << "  Pivot A:  " << pivotA << endl;
+	out << "  Perp2AxleInA1:  " << perp2axleina1 << endl;
+	out << "  Perp2AxleInA2:  " << perp2axleina2 << endl;
+	out << "  Pivot B:  " << pivotB << endl;
+	out << "  Axle B:  " << axleB << endl;
+	return out.str();
+}
+
+void bhkHingeConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConstraint::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkHingeConstraint::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConstraint::GetRefs();
+	return refs;
+}
+
+void bhkShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSerializable::Read( in, link_stack, info );
+}
+
+void bhkShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkSerializable::Write( out, link_map, info );
+}
+
+std::string bhkShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkSerializable::asString();
+	return out.str();
+}
+
+void bhkShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSerializable::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkSerializable::GetRefs();
+	return refs;
+}
+
+void bhkTransformShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	bhkShape::Read( in, link_stack, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( material, in, info );
+	NifStream( unknownFloat1, in, info );
+	for (unsigned int i1 = 0; i1 < 8; i1++) {
+		NifStream( unknown8Bytes[i1], in, info );
+	};
+	NifStream( transform, in, info );
+}
+
+void bhkTransformShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShape::Write( out, link_map, info );
+	if ( shape != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	NifStream( material, out, info );
+	NifStream( unknownFloat1, out, info );
+	for (unsigned int i1 = 0; i1 < 8; i1++) {
+		NifStream( unknown8Bytes[i1], out, info );
+	};
+	NifStream( transform, out, info );
+}
+
+std::string bhkTransformShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShape::asString();
+	out << "  Shape:  " << shape << endl;
+	out << "  Material:  " << material << endl;
+	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
+	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 8 Bytes[" << i1 << "]:  " << unknown8Bytes[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Transform:  " << transform << endl;
+	return out.str();
+}
+
+void bhkTransformShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::FixLinks( objects, link_stack, info );
+	shape = FixLink<bhkShape>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkTransformShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShape::GetRefs();
+	if ( shape != NULL )
+		refs.push_back(StaticCast<NiObject>(shape));
+	return refs;
+}
+
+void bhkSphereRepShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::Read( in, link_stack, info );
+	NifStream( material, in, info );
+	NifStream( radius, in, info );
+}
+
+void bhkSphereRepShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShape::Write( out, link_map, info );
+	NifStream( material, out, info );
+	NifStream( radius, out, info );
+}
+
+std::string bhkSphereRepShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShape::asString();
+	out << "  Material:  " << material << endl;
+	out << "  Radius:  " << radius << endl;
+	return out.str();
+}
+
+void bhkSphereRepShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkSphereRepShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShape::GetRefs();
+	return refs;
+}
+
+void bhkConvexShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSphereRepShape::Read( in, link_stack, info );
+}
+
+void bhkConvexShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkSphereRepShape::Write( out, link_map, info );
+}
+
+std::string bhkConvexShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkSphereRepShape::asString();
+	return out.str();
+}
+
+void bhkConvexShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSphereRepShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkConvexShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkSphereRepShape::GetRefs();
+	return refs;
+}
+
+void bhkSphereShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::Read( in, link_stack, info );
+}
+
+void bhkSphereShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConvexShape::Write( out, link_map, info );
+}
+
+std::string bhkSphereShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConvexShape::asString();
+	return out.str();
+}
+
+void bhkSphereShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkSphereShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConvexShape::GetRefs();
+	return refs;
+}
+
+void bhkCapsuleShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::Read( in, link_stack, info );
+	NifStream( unknownShort1, in, info );
+	NifStream( unknownShort2, in, info );
+	NifStream( unknownShort3, in, info );
+	NifStream( unknownShort4, in, info );
+	NifStream( firstPoint, in, info );
+	NifStream( radius1, in, info );
+	NifStream( secondPoint, in, info );
+	NifStream( radius2, in, info );
+}
+
+void bhkCapsuleShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConvexShape::Write( out, link_map, info );
+	NifStream( unknownShort1, out, info );
+	NifStream( unknownShort2, out, info );
+	NifStream( unknownShort3, out, info );
+	NifStream( unknownShort4, out, info );
+	NifStream( firstPoint, out, info );
+	NifStream( radius1, out, info );
+	NifStream( secondPoint, out, info );
+	NifStream( radius2, out, info );
+}
+
+std::string bhkCapsuleShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConvexShape::asString();
+	out << "  Unknown Short 1:  " << unknownShort1 << endl;
+	out << "  Unknown Short 2:  " << unknownShort2 << endl;
+	out << "  Unknown Short 3:  " << unknownShort3 << endl;
+	out << "  Unknown Short 4:  " << unknownShort4 << endl;
+	out << "  First Point:  " << firstPoint << endl;
+	out << "  Radius 1:  " << radius1 << endl;
+	out << "  Second Point:  " << secondPoint << endl;
+	out << "  Radius 2:  " << radius2 << endl;
+	return out.str();
+}
+
+void bhkCapsuleShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkCapsuleShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConvexShape::GetRefs();
+	return refs;
+}
+
+void bhkBoxShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::Read( in, link_stack, info );
+	NifStream( unknownShort1, in, info );
+	NifStream( unknownShort2, in, info );
+	NifStream( unknownShort3, in, info );
+	NifStream( unknownShort4, in, info );
+	NifStream( dimensions, in, info );
+	NifStream( min_Size, in, info );
+}
+
+void bhkBoxShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConvexShape::Write( out, link_map, info );
+	NifStream( unknownShort1, out, info );
+	NifStream( unknownShort2, out, info );
+	NifStream( unknownShort3, out, info );
+	NifStream( unknownShort4, out, info );
+	NifStream( dimensions, out, info );
+	NifStream( min_Size, out, info );
+}
+
+std::string bhkBoxShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConvexShape::asString();
+	out << "  Unknown Short 1:  " << unknownShort1 << endl;
+	out << "  Unknown Short 2:  " << unknownShort2 << endl;
+	out << "  Unknown Short 3:  " << unknownShort3 << endl;
+	out << "  Unknown Short 4:  " << unknownShort4 << endl;
+	out << "  Dimensions:  " << dimensions << endl;
+	out << "  Min. size:  " << min_Size << endl;
+	return out.str();
+}
+
+void bhkBoxShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkBoxShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConvexShape::GetRefs();
+	return refs;
+}
+
+void bhkConvexVerticesShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::Read( in, link_stack, info );
+	for (unsigned int i1 = 0; i1 < 6; i1++) {
+		NifStream( unknown6Floats[i1], in, info );
+	};
+	NifStream( numVertices, in, info );
+	vertices.resize(numVertices);
+	for (unsigned int i1 = 0; i1 < vertices.size(); i1++) {
+		NifStream( vertices[i1], in, info );
+	};
+	NifStream( numNormals, in, info );
+	normals.resize(numNormals);
+	for (unsigned int i1 = 0; i1 < normals.size(); i1++) {
+		NifStream( normals[i1], in, info );
+	};
+}
+
+void bhkConvexVerticesShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkConvexShape::Write( out, link_map, info );
+	numNormals = (unsigned int)(normals.size());
+	numVertices = (unsigned int)(vertices.size());
+	for (unsigned int i1 = 0; i1 < 6; i1++) {
+		NifStream( unknown6Floats[i1], out, info );
+	};
+	NifStream( numVertices, out, info );
+	for (unsigned int i1 = 0; i1 < vertices.size(); i1++) {
+		NifStream( vertices[i1], out, info );
+	};
+	NifStream( numNormals, out, info );
+	for (unsigned int i1 = 0; i1 < normals.size(); i1++) {
+		NifStream( normals[i1], out, info );
+	};
+}
+
+std::string bhkConvexVerticesShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkConvexShape::asString();
+	numNormals = (unsigned int)(normals.size());
+	numVertices = (unsigned int)(vertices.size());
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 6; 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 6 Floats[" << i1 << "]:  " << unknown6Floats[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Num Vertices:  " << numVertices << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < vertices.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 << "    Vertices[" << i1 << "]:  " << vertices[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Num Normals:  " << numNormals << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < normals.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 << "    Normals[" << i1 << "]:  " << normals[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void bhkConvexVerticesShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkConvexShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkConvexVerticesShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkConvexShape::GetRefs();
+	return refs;
+}
+
+void bhkConvexTransformShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkTransformShape::Read( in, link_stack, info );
+}
+
+void bhkConvexTransformShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkTransformShape::Write( out, link_map, info );
+}
+
+std::string bhkConvexTransformShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkTransformShape::asString();
+	return out.str();
+}
+
+void bhkConvexTransformShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkTransformShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkConvexTransformShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkTransformShape::GetRefs();
+	return refs;
+}
+
+void bhkMultiSphereShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSphereRepShape::Read( in, link_stack, info );
+	NifStream( unknownFloat1, in, info );
+	NifStream( unknownFloat2, in, info );
+	NifStream( numSpheres, in, info );
+	spheres.resize(numSpheres);
+	for (unsigned int i1 = 0; i1 < spheres.size(); i1++) {
+		NifStream( spheres[i1].center, in, info );
+		NifStream( spheres[i1].radius, in, info );
+	};
+}
+
+void bhkMultiSphereShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkSphereRepShape::Write( out, link_map, info );
+	numSpheres = (unsigned int)(spheres.size());
+	NifStream( unknownFloat1, out, info );
+	NifStream( unknownFloat2, out, info );
+	NifStream( numSpheres, out, info );
+	for (unsigned int i1 = 0; i1 < spheres.size(); i1++) {
+		NifStream( spheres[i1].center, out, info );
+		NifStream( spheres[i1].radius, out, info );
+	};
+}
+
+std::string bhkMultiSphereShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkSphereRepShape::asString();
+	numSpheres = (unsigned int)(spheres.size());
+	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
+	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
+	out << "  Num Spheres:  " << numSpheres << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < spheres.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		out << "    Center:  " << spheres[i1].center << endl;
+		out << "    Radius:  " << spheres[i1].radius << endl;
+	};
+	return out.str();
+}
+
+void bhkMultiSphereShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkSphereRepShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkMultiSphereShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkSphereRepShape::GetRefs();
+	return refs;
+}
+
+void bhkBvTreeShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::Read( in, link_stack, info );
+}
+
+void bhkBvTreeShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShape::Write( out, link_map, info );
+}
+
+std::string bhkBvTreeShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShape::asString();
+	return out.str();
+}
+
+void bhkBvTreeShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkBvTreeShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShape::GetRefs();
+	return refs;
+}
+
+void bhkMoppBvTreeShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	bhkBvTreeShape::Read( in, link_stack, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( material, in, info );
+	for (unsigned int i1 = 0; i1 < 8; i1++) {
+		NifStream( unknown8Bytes[i1], in, info );
+	};
+	NifStream( unknownFloat, in, info );
+	NifStream( moppDataSize, in, info );
+	if ( info.version >= 0x14000005 ) {
+		NifStream( objectCorner, in, info );
+		NifStream( scalingFactor, in, info );
+	};
+	moppData.resize(moppDataSize);
+	for (unsigned int i1 = 0; i1 < moppData.size(); i1++) {
+		NifStream( moppData[i1], in, info );
+	};
+}
+
+void bhkMoppBvTreeShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkBvTreeShape::Write( out, link_map, info );
+	moppDataSize = (unsigned int)(moppData.size());
+	if ( shape != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	NifStream( material, out, info );
+	for (unsigned int i1 = 0; i1 < 8; i1++) {
+		NifStream( unknown8Bytes[i1], out, info );
+	};
+	NifStream( unknownFloat, out, info );
+	NifStream( moppDataSize, out, info );
+	if ( info.version >= 0x14000005 ) {
+		NifStream( objectCorner, out, info );
+		NifStream( scalingFactor, out, info );
+	};
+	for (unsigned int i1 = 0; i1 < moppData.size(); i1++) {
+		NifStream( moppData[i1], out, info );
+	};
+}
+
+std::string bhkMoppBvTreeShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkBvTreeShape::asString();
+	moppDataSize = (unsigned int)(moppData.size());
+	out << "  Shape:  " << shape << endl;
+	out << "  Material:  " << material << endl;
+	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 8 Bytes[" << i1 << "]:  " << unknown8Bytes[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Unknown Float:  " << unknownFloat << endl;
+	out << "  MOPP Data Size:  " << moppDataSize << endl;
+	out << "  Object Corner:  " << objectCorner << endl;
+	out << "  Scaling Factor:  " << scalingFactor << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < moppData.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 << "    MOPP Data[" << i1 << "]:  " << moppData[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void bhkMoppBvTreeShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkBvTreeShape::FixLinks( objects, link_stack, info );
+	shape = FixLink<bhkShape>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkMoppBvTreeShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkBvTreeShape::GetRefs();
+	if ( shape != NULL )
+		refs.push_back(StaticCast<NiObject>(shape));
+	return refs;
+}
+
+void bhkShapeCollection::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::Read( in, link_stack, info );
+}
+
+void bhkShapeCollection::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShape::Write( out, link_map, info );
+}
+
+std::string bhkShapeCollection::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShape::asString();
+	return out.str();
+}
+
+void bhkShapeCollection::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShape::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkShapeCollection::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShape::GetRefs();
+	return refs;
+}
+
+void bhkListShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	bhkShapeCollection::Read( in, link_stack, info );
+	NifStream( numSubShapes, in, info );
+	subShapes.resize(numSubShapes);
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+	NifStream( material, in, info );
+	for (unsigned int i1 = 0; i1 < 6; i1++) {
+		NifStream( unknownFloats[i1], in, info );
+	};
+	NifStream( numUnknownInts, in, info );
+	unknownInts.resize(numUnknownInts);
+	for (unsigned int i1 = 0; i1 < unknownInts.size(); i1++) {
+		NifStream( unknownInts[i1], in, info );
+	};
+}
+
+void bhkListShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShapeCollection::Write( out, link_map, info );
+	numUnknownInts = (unsigned int)(unknownInts.size());
+	numSubShapes = (unsigned int)(subShapes.size());
+	NifStream( numSubShapes, out, info );
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		if ( subShapes[i1] != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(subShapes[i1]) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	NifStream( material, out, info );
+	for (unsigned int i1 = 0; i1 < 6; i1++) {
+		NifStream( unknownFloats[i1], out, info );
+	};
+	NifStream( numUnknownInts, out, info );
+	for (unsigned int i1 = 0; i1 < unknownInts.size(); i1++) {
+		NifStream( unknownInts[i1], out, info );
+	};
+}
+
+std::string bhkListShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShapeCollection::asString();
+	numUnknownInts = (unsigned int)(unknownInts.size());
+	numSubShapes = (unsigned int)(subShapes.size());
+	out << "  Num Sub Shapes:  " << numSubShapes << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < subShapes.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 << "    Sub Shapes[" << i1 << "]:  " << subShapes[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Material:  " << material << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 6; 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 Floats[" << i1 << "]:  " << unknownFloats[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Num Unknown Ints:  " << numUnknownInts << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < unknownInts.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 Ints[" << i1 << "]:  " << unknownInts[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void bhkListShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShapeCollection::FixLinks( objects, link_stack, info );
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		subShapes[i1] = FixLink<bhkShape>( objects, link_stack, info );
+	};
+}
+
+std::list<NiObjectRef> bhkListShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShapeCollection::GetRefs();
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		if ( subShapes[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(subShapes[i1]));
+	};
+	return refs;
+}
+
+void bhkPackedNiTriStripsShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	bhkShapeCollection::Read( in, link_stack, info );
+	NifStream( numSubShapes, in, info );
+	subShapes.resize(numSubShapes);
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		NifStream( subShapes[i1].layer, in, info );
+		NifStream( subShapes[i1].colFilter, in, info );
+		NifStream( subShapes[i1].unknownShort, in, info );
+		NifStream( subShapes[i1].vertexCount___, in, info );
+		NifStream( subShapes[i1].material, in, info );
+	};
+	for (unsigned int i1 = 0; i1 < 9; i1++) {
+		NifStream( unknownFloats[i1], in, info );
+	};
+	NifStream( scale, in, info );
+	for (unsigned int i1 = 0; i1 < 3; i1++) {
+		NifStream( unknownFloats2[i1], in, info );
+	};
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void bhkPackedNiTriStripsShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShapeCollection::Write( out, link_map, info );
+	numSubShapes = (unsigned short)(subShapes.size());
+	NifStream( numSubShapes, out, info );
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		NifStream( subShapes[i1].layer, out, info );
+		NifStream( subShapes[i1].colFilter, out, info );
+		NifStream( subShapes[i1].unknownShort, out, info );
+		NifStream( subShapes[i1].vertexCount___, out, info );
+		NifStream( subShapes[i1].material, out, info );
+	};
+	for (unsigned int i1 = 0; i1 < 9; i1++) {
+		NifStream( unknownFloats[i1], out, info );
+	};
+	NifStream( scale, out, info );
+	for (unsigned int i1 = 0; i1 < 3; i1++) {
+		NifStream( unknownFloats2[i1], out, info );
+	};
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string bhkPackedNiTriStripsShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShapeCollection::asString();
+	numSubShapes = (unsigned short)(subShapes.size());
+	out << "  Num Sub Shapes:  " << numSubShapes << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		out << "    Layer:  " << subShapes[i1].layer << endl;
+		out << "    Col Filter:  " << subShapes[i1].colFilter << endl;
+		out << "    Unknown Short:  " << subShapes[i1].unknownShort << endl;
+		out << "    Vertex Count (?):  " << subShapes[i1].vertexCount___ << endl;
+		out << "    Material:  " << subShapes[i1].material << endl;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 9; 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 Floats[" << i1 << "]:  " << unknownFloats[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Scale:  " << scale << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 3; 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 Floats 2[" << i1 << "]:  " << unknownFloats2[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void bhkPackedNiTriStripsShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShapeCollection::FixLinks( objects, link_stack, info );
+	data = FixLink<hkPackedNiTriStripsData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkPackedNiTriStripsShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShapeCollection::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void bhkNiTriStripsShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	bhkShapeCollection::Read( in, link_stack, info );
+	NifStream( material, in, info );
+	NifStream( unknownFloat1, in, info );
+	NifStream( unknownInt1, in, info );
+	for (unsigned int i1 = 0; i1 < 4; i1++) {
+		NifStream( unknownInts1[i1], in, info );
+	};
+	NifStream( unknownInt2, in, info );
+	NifStream( scale, in, info );
+	NifStream( unknownInt3, 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 );
+	};
+	NifStream( numDataLayers, in, info );
+	dataLayers.resize(numDataLayers);
+	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
+		NifStream( dataLayers[i1].layer, in, info );
+		NifStream( dataLayers[i1].colFilter, in, info );
+		NifStream( dataLayers[i1].unknownShort, in, info );
+	};
+}
+
+void bhkNiTriStripsShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkShapeCollection::Write( out, link_map, info );
+	numDataLayers = (unsigned int)(dataLayers.size());
+	numStripsData = (unsigned int)(stripsData.size());
+	NifStream( material, out, info );
+	NifStream( unknownFloat1, out, info );
+	NifStream( unknownInt1, out, info );
+	for (unsigned int i1 = 0; i1 < 4; i1++) {
+		NifStream( unknownInts1[i1], out, info );
+	};
+	NifStream( unknownInt2, out, info );
+	NifStream( scale, out, info );
+	NifStream( unknownInt3, 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 );
+	};
+	NifStream( numDataLayers, out, info );
+	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
+		NifStream( dataLayers[i1].layer, out, info );
+		NifStream( dataLayers[i1].colFilter, out, info );
+		NifStream( dataLayers[i1].unknownShort, out, info );
+	};
+}
+
+std::string bhkNiTriStripsShape::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkShapeCollection::asString();
+	numDataLayers = (unsigned int)(dataLayers.size());
+	numStripsData = (unsigned int)(stripsData.size());
+	out << "  Material:  " << material << endl;
+	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
+	out << "  Unknown Int 1:  " << unknownInt1 << 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 Ints 1[" << i1 << "]:  " << unknownInts1[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Scale:  " << scale << endl;
+	out << "  Unknown Int 3:  " << unknownInt3 << endl;
+	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++;
+	};
+	out << "  Num Data Layers:  " << numDataLayers << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		out << "    Layer:  " << dataLayers[i1].layer << endl;
+		out << "    Col Filter:  " << dataLayers[i1].colFilter << endl;
+		out << "    Unknown Short:  " << dataLayers[i1].unknownShort << endl;
+	};
+	return out.str();
+}
+
+void bhkNiTriStripsShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkShapeCollection::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> bhkNiTriStripsShape::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkShapeCollection::GetRefs();
+	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
+		if ( stripsData[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(stripsData[i1]));
+	};
+	return refs;
+}
+
+void NiExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiObject::Read( in, link_stack, info );
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( name, in, info );
+	};
+	if ( info.version <= 0x04020200 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+}
+
+void NiExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( name, out, info );
+	};
+	if ( info.version <= 0x04020200 ) {
+		if ( nextExtraData != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(nextExtraData) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+}
+
+std::string NiExtraData::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiObject::asString();
+	out << "  Name:  " << name << endl;
+	out << "  Next Extra Data:  " << nextExtraData << endl;
+	return out.str();
+}
+
+void NiExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x04020200 ) {
+		nextExtraData = FixLink<NiExtraData>( objects, link_stack, info );
+	};
+}
+
+std::list<NiObjectRef> NiExtraData::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	if ( nextExtraData != NULL )
+		refs.push_back(StaticCast<NiObject>(nextExtraData));
+	return refs;
+}
+
+void NiInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::Read( in, link_stack, info );
+}
+
+void NiInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+}
+
+std::string NiInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiObject::asString();
+	return out.str();
+}
+
+void NiInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	return refs;
+}
+
+void NiKeyBasedInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpolator::Read( in, link_stack, info );
+}
+
+void NiKeyBasedInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiInterpolator::Write( out, link_map, info );
+}
+
+std::string NiKeyBasedInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiInterpolator::asString();
+	return out.str();
+}
+
+void NiKeyBasedInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiKeyBasedInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpolator::GetRefs();
+	return refs;
+}
+
+void NiFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiKeyBasedInterpolator::Read( in, link_stack, info );
+	NifStream( floatValue, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiFloatInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiKeyBasedInterpolator::Write( out, link_map, info );
+	NifStream( floatValue, out, info );
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiFloatInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiKeyBasedInterpolator::asString();
+	out << "  Float Value:  " << floatValue << endl;
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiFloatInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiKeyBasedInterpolator::FixLinks( objects, link_stack, info );
+	data = FixLink<NiFloatData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiFloatInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiKeyBasedInterpolator::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiTransformInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiKeyBasedInterpolator::Read( in, link_stack, info );
+	NifStream( translation, in, info );
+	NifStream( rotation, in, info );
+	NifStream( scale, in, info );
+	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
+		for (unsigned int i2 = 0; i2 < 3; i2++) {
+			NifStream( unknownBytes[i2], in, info );
+		};
+	};
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiTransformInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiKeyBasedInterpolator::Write( out, link_map, info );
+	NifStream( translation, out, info );
+	NifStream( rotation, out, info );
+	NifStream( scale, out, info );
+	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
+		for (unsigned int i2 = 0; i2 < 3; i2++) {
+			NifStream( unknownBytes[i2], out, info );
+		};
+	};
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiTransformInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiKeyBasedInterpolator::asString();
+	out << "  Translation:  " << translation << endl;
+	out << "  Rotation:  " << rotation << endl;
+	out << "  Scale:  " << scale << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 3; 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[" << i1 << "]:  " << unknownBytes[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiTransformInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiKeyBasedInterpolator::FixLinks( objects, link_stack, info );
+	data = FixLink<NiTransformData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiTransformInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiKeyBasedInterpolator::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiPoint3Interpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiKeyBasedInterpolator::Read( in, link_stack, info );
+	NifStream( point3Value, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiPoint3Interpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiKeyBasedInterpolator::Write( out, link_map, info );
+	NifStream( point3Value, out, info );
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiPoint3Interpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiKeyBasedInterpolator::asString();
+	out << "  Point 3 Value:  " << point3Value << endl;
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiPoint3Interpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiKeyBasedInterpolator::FixLinks( objects, link_stack, info );
+	data = FixLink<NiPosData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiPoint3Interpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiKeyBasedInterpolator::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiPathInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiKeyBasedInterpolator::Read( in, link_stack, info );
+	NifStream( unknownShort, in, info );
+	NifStream( unknownInt, in, info );
+	NifStream( unknownFloat1, in, info );
+	NifStream( unknownFloat2, in, info );
+	NifStream( unknownShort2, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiPathInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiKeyBasedInterpolator::Write( out, link_map, info );
+	NifStream( unknownShort, out, info );
+	NifStream( unknownInt, out, info );
+	NifStream( unknownFloat1, out, info );
+	NifStream( unknownFloat2, out, info );
+	NifStream( unknownShort2, out, info );
+	if ( posData != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(posData) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( floatData != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(floatData) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiPathInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiKeyBasedInterpolator::asString();
+	out << "  Unknown Short:  " << unknownShort << endl;
+	out << "  Unknown Int:  " << unknownInt << endl;
+	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
+	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
+	out << "  Unknown Short 2:  " << unknownShort2 << endl;
+	out << "  Pos Data:  " << posData << endl;
+	out << "  Float Data:  " << floatData << endl;
+	return out.str();
+}
+
+void NiPathInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiKeyBasedInterpolator::FixLinks( objects, link_stack, info );
+	posData = FixLink<NiPosData>( objects, link_stack, info );
+	floatData = FixLink<NiFloatData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiPathInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiKeyBasedInterpolator::GetRefs();
+	if ( posData != NULL )
+		refs.push_back(StaticCast<NiObject>(posData));
+	if ( floatData != NULL )
+		refs.push_back(StaticCast<NiObject>(floatData));
+	return refs;
+}
+
+void NiBoolInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiKeyBasedInterpolator::Read( in, link_stack, info );
+	NifStream( boolValue, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiBoolInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiKeyBasedInterpolator::Write( out, link_map, info );
+	NifStream( boolValue, out, info );
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiBoolInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiKeyBasedInterpolator::asString();
+	out << "  Bool Value:  " << boolValue << endl;
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiBoolInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiKeyBasedInterpolator::FixLinks( objects, link_stack, info );
+	data = FixLink<NiBoolData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBoolInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiKeyBasedInterpolator::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiBoolTimelineInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBoolInterpolator::Read( in, link_stack, info );
+}
+
+void NiBoolTimelineInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBoolInterpolator::Write( out, link_map, info );
+}
+
+std::string NiBoolTimelineInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiBoolInterpolator::asString();
+	return out.str();
+}
+
+void NiBoolTimelineInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBoolInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBoolTimelineInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiBoolInterpolator::GetRefs();
+	return refs;
+}
+
+void NiBlendInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpolator::Read( in, link_stack, info );
+	NifStream( unknownShort, in, info );
+	NifStream( unknownInt, in, info );
+}
+
+void NiBlendInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiInterpolator::Write( out, link_map, info );
+	NifStream( unknownShort, out, info );
+	NifStream( unknownInt, out, info );
+}
+
+std::string NiBlendInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiInterpolator::asString();
+	out << "  Unknown Short:  " << unknownShort << endl;
+	out << "  Unknown Int:  " << unknownInt << endl;
+	return out.str();
+}
+
+void NiBlendInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBlendInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpolator::GetRefs();
+	return refs;
+}
+
+void NiBSplineInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiInterpolator::Read( in, link_stack, info );
+	NifStream( startTime, in, info );
+	NifStream( stopTime, in, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+}
+
+void NiBSplineInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiInterpolator::Write( out, link_map, info );
+	NifStream( startTime, out, info );
+	NifStream( stopTime, out, info );
+	if ( splineData != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(splineData) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( basisData != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(basisData) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+}
+
+std::string NiBSplineInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiInterpolator::asString();
+	out << "  Start Time:  " << startTime << endl;
+	out << "  Stop Time:  " << stopTime << endl;
+	out << "  Spline Data:  " << splineData << endl;
+	out << "  Basis Data:  " << basisData << endl;
+	return out.str();
+}
+
+void NiBSplineInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpolator::FixLinks( objects, link_stack, info );
+	splineData = FixLink<NiBSplineData>( objects, link_stack, info );
+	basisData = FixLink<NiBSplineBasisData>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBSplineInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpolator::GetRefs();
+	if ( splineData != NULL )
+		refs.push_back(StaticCast<NiObject>(splineData));
+	if ( basisData != NULL )
+		refs.push_back(StaticCast<NiObject>(basisData));
+	return refs;
+}
+
+void NiObjectNET::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiObject::Read( in, link_stack, info );
+	NifStream( name, in, info );
+	if ( info.version <= 0x04020200 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
 	if ( info.version >= 0x0A000100 ) {
 		NifStream( numExtraDataList, in, info );
 		extraDataList.resize(numExtraDataList);
@@ -1036,30 +2769,314 @@ std::string NiObjectNET::InternalAsString( bool verbose ) const {
 	return out.str();
 }
 
-void NiObjectNET::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x04020200 ) {
-		extraData = FixLink<NiExtraData>( objects, link_stack, info );
-	};
-	if ( info.version >= 0x0A000100 ) {
-		for (unsigned int i2 = 0; i2 < extraDataList.size(); i2++) {
-			extraDataList[i2] = FixLink<NiExtraData>( objects, link_stack, info );
-		};
-	};
-	controller = FixLink<NiTimeController>( objects, link_stack, info );
+void NiObjectNET::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x04020200 ) {
+		extraData = FixLink<NiExtraData>( objects, link_stack, info );
+	};
+	if ( info.version >= 0x0A000100 ) {
+		for (unsigned int i2 = 0; i2 < extraDataList.size(); i2++) {
+			extraDataList[i2] = FixLink<NiExtraData>( objects, link_stack, info );
+		};
+	};
+	controller = FixLink<NiTimeController>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiObjectNET::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	if ( extraData != NULL )
+		refs.push_back(StaticCast<NiObject>(extraData));
+	for (unsigned int i1 = 0; i1 < extraDataList.size(); i1++) {
+		if ( extraDataList[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(extraDataList[i1]));
+	};
+	if ( controller != NULL )
+		refs.push_back(StaticCast<NiObject>(controller));
+	return refs;
+}
+
+void NiCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiObject::Read( in, link_stack, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	if ( info.version >= 0x14000004 ) {
+		NifStream( unknownShort, in, info );
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+}
+
+void NiCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+	if ( target != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( info.version >= 0x14000004 ) {
+		NifStream( unknownShort, out, info );
+		if ( body != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(body) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+}
+
+std::string NiCollisionObject::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiObject::asString();
+	out << "  Target:  " << target << endl;
+	out << "  Unknown Short:  " << unknownShort << endl;
+	out << "  Body:  " << body << endl;
+	return out.str();
+}
+
+void NiCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+	target = FixLink<NiAVObject>( objects, link_stack, info );
+	if ( info.version >= 0x14000004 ) {
+		body = FixLink<NiObject>( objects, link_stack, info );
+	};
+}
+
+std::list<NiObjectRef> NiCollisionObject::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	if ( body != NULL )
+		refs.push_back(StaticCast<NiObject>(body));
+	return refs;
+}
+
+void NiCollisionData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiCollisionObject::Read( in, link_stack, info );
+	NifStream( unknownInt1, in, info );
+	if ( ( info.version >= 0x0A010000 ) && ( info.version <= 0x0A010000 ) ) {
+		NifStream( unknownInt2, in, info );
+	};
+	NifStream( unknownByte, in, info );
+	NifStream( collisionType, in, info );
+	if ( (collisionType == 0) ) {
+		NifStream( unknownInt2, in, info );
+		NifStream( unknownVector, in, info );
+	};
+	if ( (collisionType == 2) ) {
+		for (unsigned int i2 = 0; i2 < 8; i2++) {
+			NifStream( unknownFloat1[i2], in, info );
+		};
+	};
+	if ( (collisionType == 1) ) {
+		for (unsigned int i2 = 0; i2 < 15; i2++) {
+			NifStream( unknownFloat2[i2], in, info );
+		};
+	};
+}
+
+void NiCollisionData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiCollisionObject::Write( out, link_map, info );
+	NifStream( unknownInt1, out, info );
+	if ( ( info.version >= 0x0A010000 ) && ( info.version <= 0x0A010000 ) ) {
+		NifStream( unknownInt2, out, info );
+	};
+	NifStream( unknownByte, out, info );
+	NifStream( collisionType, out, info );
+	if ( (collisionType == 0) ) {
+		NifStream( unknownInt2, out, info );
+		NifStream( unknownVector, out, info );
+	};
+	if ( (collisionType == 2) ) {
+		for (unsigned int i2 = 0; i2 < 8; i2++) {
+			NifStream( unknownFloat1[i2], out, info );
+		};
+	};
+	if ( (collisionType == 1) ) {
+		for (unsigned int i2 = 0; i2 < 15; i2++) {
+			NifStream( unknownFloat2[i2], out, info );
+		};
+	};
+}
+
+std::string NiCollisionData::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiCollisionObject::asString();
+	out << "  Unknown Int 1:  " << unknownInt1 << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Unknown Byte:  " << unknownByte << endl;
+	out << "  Collision Type:  " << collisionType << endl;
+	if ( (collisionType == 0) ) {
+		out << "    Unknown Vector:  " << unknownVector << endl;
+	};
+	if ( (collisionType == 2) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < 8; 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 Float 1[" << i2 << "]:  " << unknownFloat1[i2] << endl;
+			array_output_count++;
+		};
+	};
+	if ( (collisionType == 1) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < 15; 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 Float 2[" << i2 << "]:  " << unknownFloat2[i2] << endl;
+			array_output_count++;
+		};
+	};
+	return out.str();
+}
+
+void NiCollisionData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiCollisionObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiCollisionData::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiCollisionObject::GetRefs();
+	return refs;
+}
+
+void bhkNiCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiCollisionObject::Read( in, link_stack, info );
+}
+
+void bhkNiCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiCollisionObject::Write( out, link_map, info );
+}
+
+std::string bhkNiCollisionObject::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiCollisionObject::asString();
+	return out.str();
+}
+
+void bhkNiCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiCollisionObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkNiCollisionObject::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiCollisionObject::GetRefs();
+	return refs;
+}
+
+void bhkCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkNiCollisionObject::Read( in, link_stack, info );
+}
+
+void bhkCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkNiCollisionObject::Write( out, link_map, info );
+}
+
+std::string bhkCollisionObject::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkNiCollisionObject::asString();
+	return out.str();
+}
+
+void bhkCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkNiCollisionObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkCollisionObject::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkNiCollisionObject::GetRefs();
+	return refs;
+}
+
+void bhkBlendCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkCollisionObject::Read( in, link_stack, info );
+	NifStream( unknownFloat1, in, info );
+	NifStream( unknownFloat2, in, info );
+}
+
+void bhkBlendCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkCollisionObject::Write( out, link_map, info );
+	NifStream( unknownFloat1, out, info );
+	NifStream( unknownFloat2, out, info );
+}
+
+std::string bhkBlendCollisionObject::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkCollisionObject::asString();
+	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
+	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
+	return out.str();
+}
+
+void bhkBlendCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkCollisionObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkBlendCollisionObject::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkCollisionObject::GetRefs();
+	return refs;
+}
+
+void bhkPCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkNiCollisionObject::Read( in, link_stack, info );
+}
+
+void bhkPCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkNiCollisionObject::Write( out, link_map, info );
+}
+
+std::string bhkPCollisionObject::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkNiCollisionObject::asString();
+	return out.str();
+}
+
+void bhkPCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkNiCollisionObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> bhkPCollisionObject::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = bhkNiCollisionObject::GetRefs();
+	return refs;
+}
+
+void bhkSPCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkPCollisionObject::Read( in, link_stack, info );
+}
+
+void bhkSPCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	bhkPCollisionObject::Write( out, link_map, info );
+}
+
+std::string bhkSPCollisionObject::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << bhkPCollisionObject::asString();
+	return out.str();
+}
+
+void bhkSPCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	bhkPCollisionObject::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiObjectNET::InternalGetRefs() const {
+std::list<NiObjectRef> bhkSPCollisionObject::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	if ( extraData != NULL )
-		refs.push_back(StaticCast<NiObject>(extraData));
-	for (unsigned int i1 = 0; i1 < extraDataList.size(); i1++) {
-		if ( extraDataList[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(extraDataList[i1]));
-	};
-	if ( controller != NULL )
-		refs.push_back(StaticCast<NiObject>(controller));
+	refs = bhkPCollisionObject::GetRefs();
 	return refs;
 }
 
@@ -1088,11 +3105,7 @@ void NiAVObject::InternalRead( istream& in, list<unsigned int> & link_stack, con
 			NifStream( boundingBox.radius, in, info );
 		};
 	};
-	if ( ( info.version >= 0x0A000100 ) && ( info.version <= 0x0A020000 ) ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-	if ( info.version >= 0x14000004 ) {
+	if ( info.version >= 0x0A000100 ) {
 		NifStream( block_num, in, info );
 		link_stack.push_back( block_num );
 	};
@@ -1124,13 +3137,7 @@ void NiAVObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int
 			NifStream( boundingBox.radius, out, info );
 		};
 	};
-	if ( ( info.version >= 0x0A000100 ) && ( info.version <= 0x0A020000 ) ) {
-		if ( collisionData != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(collisionData) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-	if ( info.version >= 0x14000004 ) {
+	if ( info.version >= 0x0A000100 ) {
 		if ( collisionObject != NULL )
 			NifStream( link_map.find( StaticCast<NiObject>(collisionObject) )->second, out, info );
 		else
@@ -1168,7 +3175,6 @@ std::string NiAVObject::InternalAsString( bool verbose ) const {
 		out << "    Rotation:  " << boundingBox.rotation << endl;
 		out << "    Radius:  " << boundingBox.radius << endl;
 	};
-	out << "  Collision Data:  " << collisionData << endl;
 	out << "  Collision Object:  " << collisionObject << endl;
 	return out.str();
 }
@@ -1178,10 +3184,7 @@ void NiAVObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects
 	for (unsigned int i1 = 0; i1 < properties.size(); i1++) {
 		properties[i1] = FixLink<NiProperty>( objects, link_stack, info );
 	};
-	if ( ( info.version >= 0x0A000100 ) && ( info.version <= 0x0A020000 ) ) {
-		collisionData = FixLink<NiCollisionData>( objects, link_stack, info );
-	};
-	if ( info.version >= 0x14000004 ) {
+	if ( info.version >= 0x0A000100 ) {
 		collisionObject = FixLink<NiCollisionObject>( objects, link_stack, info );
 	};
 }
@@ -1193,8 +3196,6 @@ std::list<NiObjectRef> NiAVObject::InternalGetRefs() const {
 		if ( properties[i1] != NULL )
 			refs.push_back(StaticCast<NiObject>(properties[i1]));
 	};
-	if ( collisionData != NULL )
-		refs.push_back(StaticCast<NiObject>(collisionData));
 	if ( collisionObject != NULL )
 		refs.push_back(StaticCast<NiObject>(collisionObject));
 	return refs;
@@ -1493,1205 +3494,799 @@ void NiPSysVolumeEmitter::InternalWrite( ostream& out, const map<NiObjectRef,uns
 			NifStream( link_map.find( StaticCast<NiObject>(emitterObject) )->second, out, info );
 		else
 			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiPSysVolumeEmitter::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiPSysEmitter::asString();
-	out << "  Emitter Object:  " << emitterObject << endl;
-	return out.str();
-}
-
-void NiPSysVolumeEmitter::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiPSysEmitter::FixLinks( objects, link_stack, info );
-	if ( info.version >= 0x0A010000 ) {
-		emitterObject = FixLink<NiNode>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiPSysVolumeEmitter::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiPSysEmitter::GetRefs();
-	return refs;
-}
-
-void NiTimeController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( flags, in, info );
-	NifStream( frequency, in, info );
-	NifStream( phase, in, info );
-	NifStream( startTime, in, info );
-	NifStream( stopTime, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiTimeController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-	if ( nextController != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(nextController) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( flags, out, info );
-	NifStream( frequency, out, info );
-	NifStream( phase, out, info );
-	NifStream( startTime, out, info );
-	NifStream( stopTime, out, info );
-	if ( target != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiTimeController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	out << "  Next Controller:  " << nextController << endl;
-	out << "  Flags:  " << flags << endl;
-	out << "  Frequency:  " << frequency << endl;
-	out << "  Phase:  " << phase << endl;
-	out << "  Start Time:  " << startTime << endl;
-	out << "  Stop Time:  " << stopTime << endl;
-	out << "  Target:  " << target << endl;
-	return out.str();
-}
-
-void NiTimeController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	nextController = FixLink<NiTimeController>( objects, link_stack, info );
-	target = FixLink<NiObjectNET>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiTimeController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	if ( nextController != NULL )
-		refs.push_back(StaticCast<NiObject>(nextController));
-	return refs;
-}
-
-void ABoneLODController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	NifStream( unknownInt1, in, info );
-	NifStream( numNodeGroups, in, info );
-	NifStream( numNodeGroups2, in, info );
-	nodeGroups.resize(numNodeGroups);
-	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
-		NifStream( nodeGroups[i1].numNodes, in, info );
-		nodeGroups[i1].nodes.resize(nodeGroups[i1].numNodes);
-		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
-}
-
-void ABoneLODController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	numNodeGroups = (unsigned int)(nodeGroups.size());
-	NifStream( unknownInt1, out, info );
-	NifStream( numNodeGroups, out, info );
-	NifStream( numNodeGroups2, out, info );
-	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
-		nodeGroups[i1].numNodes = (unsigned int)(nodeGroups[i1].nodes.size());
-		NifStream( nodeGroups[i1].numNodes, out, info );
-		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
-			if ( nodeGroups[i1].nodes[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(nodeGroups[i1].nodes[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
-}
-
-std::string ABoneLODController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	numNodeGroups = (unsigned int)(nodeGroups.size());
-	out << "  Unknown Int 1:  " << unknownInt1 << endl;
-	out << "  Num Node Groups:  " << numNodeGroups << endl;
-	out << "  Num Node Groups 2:  " << numNodeGroups2 << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		nodeGroups[i1].numNodes = (unsigned int)(nodeGroups[i1].nodes.size());
-		out << "    Num Nodes:  " << nodeGroups[i1].numNodes << endl;
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); 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 << "      Nodes[" << i2 << "]:  " << nodeGroups[i1].nodes[i2] << endl;
-			array_output_count++;
-		};
-	};
-	return out.str();
-}
-
-void ABoneLODController::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 < nodeGroups.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
-			nodeGroups[i1].nodes[i2] = FixLink<NiNode>( objects, link_stack, info );
-		};
-	};
-}
-
-std::list<NiObjectRef> ABoneLODController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
-		};
-	};
-	return refs;
-}
-
-void NiSingleInterpolatorController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiSingleInterpolatorController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	if ( info.version >= 0x0A020000 ) {
-		if ( interpolator != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(interpolator) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiSingleInterpolatorController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	out << "  Interpolator:  " << interpolator << endl;
-	return out.str();
-}
-
-void NiSingleInterpolatorController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiTimeController::FixLinks( objects, link_stack, info );
-	if ( info.version >= 0x0A020000 ) {
-		interpolator = FixLink<NiInterpolator>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiSingleInterpolatorController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	if ( interpolator != NULL )
-		refs.push_back(StaticCast<NiObject>(interpolator));
-	return refs;
-}
-
-void APSysCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-	NifStream( modifierName, in, info );
-}
-
-void APSysCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::Write( out, link_map, info );
-	NifStream( modifierName, out, info );
+	};
 }
 
-std::string APSysCtlr::InternalAsString( bool verbose ) const {
+std::string NiPSysVolumeEmitter::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	out << "  Modifier Name:  " << modifierName << endl;
+	out << NiPSysEmitter::asString();
+	out << "  Emitter Object:  " << emitterObject << endl;
 	return out.str();
 }
 
-void APSysCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
+void NiPSysVolumeEmitter::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysEmitter::FixLinks( objects, link_stack, info );
+	if ( info.version >= 0x0A010000 ) {
+		emitterObject = FixLink<NiNode>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> APSysCtlr::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysVolumeEmitter::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
+	refs = NiPSysEmitter::GetRefs();
 	return refs;
 }
 
-void NiGeometry::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiTimeController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiAVObject::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( flags, in, info );
+	NifStream( frequency, in, info );
+	NifStream( phase, in, info );
+	NifStream( startTime, in, info );
+	NifStream( stopTime, in, info );
 	NifStream( block_num, in, info );
 	link_stack.push_back( block_num );
-	if ( info.version >= 0x0303000D ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-	if ( info.version >= 0x0A000100 ) {
-		NifStream( hasShader, in, info );
-		if ( (hasShader != 0) ) {
-			NifStream( shaderName, in, info );
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
 }
 
-void NiGeometry::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiAVObject::Write( out, link_map, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+void NiTimeController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+	if ( nextController != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(nextController) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	NifStream( flags, out, info );
+	NifStream( frequency, out, info );
+	NifStream( phase, out, info );
+	NifStream( startTime, out, info );
+	NifStream( stopTime, out, info );
+	if ( target != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(target) )->second, out, info );
 	else
 		NifStream( 0xffffffff, out, info );
-	if ( info.version >= 0x0303000D ) {
-		if ( skinInstance != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(skinInstance) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-	if ( info.version >= 0x0A000100 ) {
-		NifStream( hasShader, out, info );
-		if ( (hasShader != 0) ) {
-			NifStream( shaderName, out, info );
-			if ( unknownLink != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
 }
 
-std::string NiGeometry::InternalAsString( bool verbose ) const {
+std::string NiTimeController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiAVObject::asString();
-	out << "  Data:  " << data << endl;
-	out << "  Skin Instance:  " << skinInstance << endl;
-	out << "  Has Shader:  " << hasShader << endl;
-	if ( (hasShader != 0) ) {
-		out << "    Shader Name:  " << shaderName << endl;
-		out << "    Unknown Link:  " << unknownLink << endl;
-	};
+	out << NiObject::asString();
+	out << "  Next Controller:  " << nextController << endl;
+	out << "  Flags:  " << flags << endl;
+	out << "  Frequency:  " << frequency << endl;
+	out << "  Phase:  " << phase << endl;
+	out << "  Start Time:  " << startTime << endl;
+	out << "  Stop Time:  " << stopTime << endl;
+	out << "  Target:  " << target << endl;
 	return out.str();
 }
 
-void NiGeometry::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiAVObject::FixLinks( objects, link_stack, info );
-	data = FixLink<NiGeometryData>( objects, link_stack, info );
-	if ( info.version >= 0x0303000D ) {
-		skinInstance = FixLink<NiSkinInstance>( objects, link_stack, info );
-	};
-	if ( info.version >= 0x0A000100 ) {
-		if ( (hasShader != 0) ) {
-			unknownLink = FixLink<NiObject>( objects, link_stack, info );
-		};
-	};
+void NiTimeController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+	nextController = FixLink<NiTimeController>( objects, link_stack, info );
+	target = FixLink<NiObjectNET>( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiGeometry::InternalGetRefs() const {
+std::list<NiObjectRef> NiTimeController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiAVObject::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	if ( skinInstance != NULL )
-		refs.push_back(StaticCast<NiObject>(skinInstance));
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
+	refs = NiObject::GetRefs();
+	if ( nextController != NULL )
+		refs.push_back(StaticCast<NiObject>(nextController));
 	return refs;
 }
 
-void NiTriBasedGeom::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometry::Read( in, link_stack, info );
+void NiInterpController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiTimeController::Read( in, link_stack, info );
 }
 
-void NiTriBasedGeom::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiGeometry::Write( out, link_map, info );
+void NiInterpController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiTimeController::Write( out, link_map, info );
 }
 
-std::string NiTriBasedGeom::InternalAsString( bool verbose ) const {
+std::string NiInterpController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiGeometry::asString();
+	out << NiTimeController::asString();
 	return out.str();
 }
 
-void NiTriBasedGeom::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometry::FixLinks( objects, link_stack, info );
+void NiInterpController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiTimeController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiTriBasedGeom::InternalGetRefs() const {
+std::list<NiObjectRef> NiInterpController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiGeometry::GetRefs();
+	refs = NiTimeController::GetRefs();
 	return refs;
 }
 
-void NiGeometryData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiMultiTargetTransformController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( name, in, info );
-	};
-	NifStream( numVertices, in, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( unknownShort1, in, info );
-	};
-	NifStream( hasVertices, in, info );
-	if ( (hasVertices != 0) ) {
-		vertices.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < vertices.size(); i2++) {
-			NifStream( vertices[i2], in, info );
-		};
-	};
-	if ( info.version >= 0x0A000100 ) {
-		NifStream( numUvSets2, in, info );
-		NifStream( unknownByte, in, info );
-	};
-	NifStream( hasNormals, in, info );
-	if ( (hasNormals != 0) ) {
-		normals.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < normals.size(); i2++) {
-			NifStream( normals[i2], in, info );
-		};
-	};
-	if ( info.version >= 0x0A010000 ) {
-		if ( (((hasNormals != 0)) && ((unknownByte & 16))) ) {
-			unknownVectors1.resize(numVertices);
-			for (unsigned int i3 = 0; i3 < unknownVectors1.size(); i3++) {
-				NifStream( unknownVectors1[i3], in, info );
-			};
-			unknownVectors2.resize(numVertices);
-			for (unsigned int i3 = 0; i3 < unknownVectors2.size(); i3++) {
-				NifStream( unknownVectors2[i3], in, info );
-			};
-		};
-	};
-	NifStream( center, in, info );
-	NifStream( radius, in, info );
-	NifStream( hasVertexColors, in, info );
-	if ( (hasVertexColors != 0) ) {
-		vertexColors.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < vertexColors.size(); i2++) {
-			NifStream( vertexColors[i2], in, info );
-		};
-	};
-	if ( info.version <= 0x04020200 ) {
-		NifStream( numUvSets, in, info );
+	NiInterpController::Read( in, link_stack, info );
+	NifStream( numExtraTargets, in, info );
+	extraTargets.resize(numExtraTargets);
+	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
-	if ( info.version <= 0x04000002 ) {
-		NifStream( hasUv, in, info );
+}
+
+void NiMultiTargetTransformController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiInterpController::Write( out, link_map, info );
+	numExtraTargets = (unsigned short)(extraTargets.size());
+	NifStream( numExtraTargets, out, info );
+	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
+		if ( extraTargets[i1] != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(extraTargets[i1]) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
 	};
-	if ( info.version <= 0x04020200 ) {
-		uvSets.resize(numUvSets);
-		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
-			uvSets[i2].resize(numVertices);
-			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
-				NifStream( uvSets[i2][i3], in, info );
-			};
+}
+
+std::string NiMultiTargetTransformController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiInterpController::asString();
+	numExtraTargets = (unsigned short)(extraTargets.size());
+	out << "  Num Extra Targets:  " << numExtraTargets << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
 		};
-	};
-	if ( info.version >= 0x0A000100 ) {
-		uvSets.resize((numUvSets2 & 63));
-		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
-			uvSets[i2].resize(numVertices);
-			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
-				NifStream( uvSets[i2][i3], in, info );
-			};
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
 		};
-		NifStream( unknownShort2, in, info );
-	};
-	if ( info.version >= 0x14000004 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
+		out << "    Extra Targets[" << i1 << "]:  " << extraTargets[i1] << endl;
+		array_output_count++;
 	};
+	return out.str();
 }
 
-void NiGeometryData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-	numUvSets = (unsigned short)(uvSets.size());
-	numUvSets2 = (byte)(uvSets.size());
-	numVertices = (unsigned short)(vertices.size());
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( name, out, info );
-	};
-	NifStream( numVertices, out, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( unknownShort1, out, info );
+void NiMultiTargetTransformController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpController::FixLinks( objects, link_stack, info );
+	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
+		extraTargets[i1] = FixLink<NiNode>( objects, link_stack, info );
 	};
-	NifStream( hasVertices, out, info );
-	if ( (hasVertices != 0) ) {
-		for (unsigned int i2 = 0; i2 < vertices.size(); i2++) {
-			NifStream( vertices[i2], out, info );
-		};
+}
+
+std::list<NiObjectRef> NiMultiTargetTransformController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpController::GetRefs();
+	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
 	};
-	if ( info.version >= 0x0A000100 ) {
-		NifStream( numUvSets2, out, info );
-		NifStream( unknownByte, out, info );
+	return refs;
+}
+
+void NiGeomMorpherController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiInterpController::Read( in, link_stack, info );
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( unknown, in, info );
 	};
-	NifStream( hasNormals, out, info );
-	if ( (hasNormals != 0) ) {
-		for (unsigned int i2 = 0; i2 < normals.size(); i2++) {
-			NifStream( normals[i2], out, info );
-		};
+	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
+		NifStream( unknown2, in, info );
 	};
-	if ( info.version >= 0x0A010000 ) {
-		if ( (((hasNormals != 0)) && ((unknownByte & 16))) ) {
-			for (unsigned int i3 = 0; i3 < unknownVectors1.size(); i3++) {
-				NifStream( unknownVectors1[i3], out, info );
-			};
-			for (unsigned int i3 = 0; i3 < unknownVectors2.size(); i3++) {
-				NifStream( unknownVectors2[i3], out, info );
-			};
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	NifStream( unknownByte, in, info );
+	if ( info.version >= 0x0A01006A ) {
+		NifStream( numInterpolators, in, info );
+		interpolators.resize(numInterpolators);
+		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
 		};
 	};
-	NifStream( center, out, info );
-	NifStream( radius, out, info );
-	NifStream( hasVertexColors, out, info );
-	if ( (hasVertexColors != 0) ) {
-		for (unsigned int i2 = 0; i2 < vertexColors.size(); i2++) {
-			NifStream( vertexColors[i2], out, info );
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( numUnknownInts, in, info );
+		unknownInts.resize(numUnknownInts);
+		for (unsigned int i2 = 0; i2 < unknownInts.size(); i2++) {
+			NifStream( unknownInts[i2], in, info );
 		};
 	};
-	if ( info.version <= 0x04020200 ) {
-		NifStream( numUvSets, out, info );
+}
+
+void NiGeomMorpherController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiInterpController::Write( out, link_map, info );
+	numUnknownInts = (unsigned int)(unknownInts.size());
+	numInterpolators = (unsigned int)(interpolators.size());
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( unknown, out, info );
 	};
-	if ( info.version <= 0x04000002 ) {
-		NifStream( hasUv, out, info );
+	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
+		NifStream( unknown2, out, info );
 	};
-	if ( info.version <= 0x04020200 ) {
-		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
-				NifStream( uvSets[i2][i3], out, info );
-			};
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	NifStream( unknownByte, out, info );
+	if ( info.version >= 0x0A01006A ) {
+		NifStream( numInterpolators, out, info );
+		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
+			if ( interpolators[i2] != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(interpolators[i2]) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
 		};
 	};
-	if ( info.version >= 0x0A000100 ) {
-		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
-				NifStream( uvSets[i2][i3], out, info );
-			};
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( numUnknownInts, out, info );
+		for (unsigned int i2 = 0; i2 < unknownInts.size(); i2++) {
+			NifStream( unknownInts[i2], out, info );
 		};
-		NifStream( unknownShort2, out, info );
-	};
-	if ( info.version >= 0x14000004 ) {
-		if ( unknownLink != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
 	};
 }
 
-std::string NiGeometryData::InternalAsString( bool verbose ) const {
+std::string NiGeomMorpherController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	numUvSets = (unsigned short)(uvSets.size());
-	numUvSets2 = (byte)(uvSets.size());
-	numVertices = (unsigned short)(vertices.size());
-	out << "  Name:  " << name << endl;
-	out << "  Num Vertices:  " << numVertices << endl;
-	out << "  Unknown Short 1:  " << unknownShort1 << endl;
-	out << "  Has Vertices:  " << hasVertices << endl;
-	if ( (hasVertices != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < vertices.size(); 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 << "      Vertices[" << i2 << "]:  " << vertices[i2] << endl;
-			array_output_count++;
-		};
-	};
-	out << "  Num UV Sets 2:  " << numUvSets2 << endl;
+	out << NiInterpController::asString();
+	numUnknownInts = (unsigned int)(unknownInts.size());
+	numInterpolators = (unsigned int)(interpolators.size());
+	out << "  Unknown:  " << unknown << endl;
+	out << "  Unknown 2:  " << unknown2 << endl;
+	out << "  Data:  " << data << endl;
 	out << "  Unknown Byte:  " << unknownByte << endl;
-	out << "  Has Normals:  " << hasNormals << endl;
-	if ( (hasNormals != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < normals.size(); 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 << "      Normals[" << i2 << "]:  " << normals[i2] << endl;
-			array_output_count++;
-		};
-	};
-	if ( (((hasNormals != 0)) && ((unknownByte & 16))) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownVectors1.size(); 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 Vectors 1[" << i2 << "]:  " << unknownVectors1[i2] << endl;
-			array_output_count++;
-		};
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownVectors2.size(); 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 Vectors 2[" << i2 << "]:  " << unknownVectors2[i2] << endl;
-			array_output_count++;
+	out << "  Num Interpolators:  " << numInterpolators << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < interpolators.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
 		};
-	};
-	out << "  Center:  " << center << endl;
-	out << "  Radius:  " << radius << endl;
-	out << "  Has Vertex Colors:  " << hasVertexColors << endl;
-	if ( (hasVertexColors != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < vertexColors.size(); 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 << "      Vertex Colors[" << i2 << "]:  " << vertexColors[i2] << endl;
-			array_output_count++;
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
 		};
+		out << "    Interpolators[" << i1 << "]:  " << interpolators[i1] << endl;
+		array_output_count++;
 	};
-	out << "  Num UV Sets:  " << numUvSets << endl;
-	out << "  Has UV:  " << hasUv << endl;
+	out << "  Num Unknown Ints:  " << numUnknownInts << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < uvSets.size(); i1++) {
+	for (unsigned int i1 = 0; i1 < unknownInts.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 < uvSets[i1].size(); i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				break;
-			};
-			out << "      UV Sets[" << i2 << "]:  " << uvSets[i1][i2] << endl;
-			array_output_count++;
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			break;
 		};
+		out << "    Unknown Ints[" << i1 << "]:  " << unknownInts[i1] << endl;
+		array_output_count++;
 	};
-	out << "  Unknown Short 2:  " << unknownShort2 << endl;
-	out << "  Unknown Link:  " << unknownLink << endl;
 	return out.str();
 }
 
-void NiGeometryData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	if ( info.version >= 0x14000004 ) {
-		unknownLink = FixLink<NiObject>( objects, link_stack, info );
-	};
+void NiGeomMorpherController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpController::FixLinks( objects, link_stack, info );
+	data = FixLink<NiMorphData>( objects, link_stack, info );
+	if ( info.version >= 0x0A01006A ) {
+		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
+			interpolators[i2] = FixLink<NiInterpolator>( objects, link_stack, info );
+		};
+	};
+}
+
+std::list<NiObjectRef> NiGeomMorpherController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpController::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	for (unsigned int i1 = 0; i1 < interpolators.size(); i1++) {
+		if ( interpolators[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(interpolators[i1]));
+	};
+	return refs;
+}
+
+void NiSingleInterpController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiInterpController::Read( in, link_stack, info );
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+}
+
+void NiSingleInterpController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiInterpController::Write( out, link_map, info );
+	if ( info.version >= 0x0A020000 ) {
+		if ( interpolator != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(interpolator) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+}
+
+std::string NiSingleInterpController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiInterpController::asString();
+	out << "  Interpolator:  " << interpolator << endl;
+	return out.str();
+}
+
+void NiSingleInterpController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version >= 0x0A020000 ) {
+		interpolator = FixLink<NiInterpolator>( objects, link_stack, info );
+	};
+}
+
+std::list<NiObjectRef> NiSingleInterpController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpController::GetRefs();
+	if ( interpolator != NULL )
+		refs.push_back(StaticCast<NiObject>(interpolator));
+	return refs;
+}
+
+void NiTransformController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::Read( in, link_stack, info );
+}
+
+void NiTransformController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiSingleInterpController::Write( out, link_map, info );
+}
+
+std::string NiTransformController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiSingleInterpController::asString();
+	return out.str();
+}
+
+void NiTransformController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiGeometryData::InternalGetRefs() const {
+std::list<NiObjectRef> NiTransformController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
+	refs = NiSingleInterpController::GetRefs();
 	return refs;
 }
 
-void NiTriBasedGeomData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometryData::Read( in, link_stack, info );
-	NifStream( numTriangles, in, info );
+void NiPSysModifierCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::Read( in, link_stack, info );
+	NifStream( modifierName, in, info );
 }
 
-void NiTriBasedGeomData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiGeometryData::Write( out, link_map, info );
-	NifStream( numTriangles, out, info );
+void NiPSysModifierCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiSingleInterpController::Write( out, link_map, info );
+	NifStream( modifierName, out, info );
 }
 
-std::string NiTriBasedGeomData::InternalAsString( bool verbose ) const {
+std::string NiPSysModifierCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiGeometryData::asString();
-	out << "  Num Triangles:  " << numTriangles << endl;
+	out << NiSingleInterpController::asString();
+	out << "  Modifier Name:  " << modifierName << endl;
 	return out.str();
 }
 
-void NiTriBasedGeomData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometryData::FixLinks( objects, link_stack, info );
+void NiPSysModifierCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiTriBasedGeomData::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysModifierCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiGeometryData::GetRefs();
+	refs = NiSingleInterpController::GetRefs();
 	return refs;
 }
 
-void APSysData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometryData::Read( in, link_stack, info );
-	NifStream( hasUnknownFloats1, in, info );
-	if ( (hasUnknownFloats1 != 0) ) {
-		unknownFloats1.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < unknownFloats1.size(); i2++) {
-			NifStream( unknownFloats1[i2], in, info );
-		};
-	};
-	NifStream( unknownShort3, in, info );
-	NifStream( hasUnknownFloats2, in, info );
-	if ( (hasUnknownFloats2 != 0) ) {
-		unknownFloats2.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < unknownFloats2.size(); i2++) {
-			NifStream( unknownFloats2[i2], in, info );
-		};
+void NiPSysEmitterCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiPSysModifierCtlr::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
-	NifStream( hasUnknownFloats3, in, info );
-	if ( (hasUnknownFloats3 != 0) ) {
-		unknownFloats3.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < unknownFloats3.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 4; i3++) {
-				NifStream( unknownFloats3[i2][i3], in, info );
-			};
-		};
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
 }
 
-void APSysData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiGeometryData::Write( out, link_map, info );
-	NifStream( hasUnknownFloats1, out, info );
-	if ( (hasUnknownFloats1 != 0) ) {
-		for (unsigned int i2 = 0; i2 < unknownFloats1.size(); i2++) {
-			NifStream( unknownFloats1[i2], out, info );
-		};
-	};
-	NifStream( unknownShort3, out, info );
-	NifStream( hasUnknownFloats2, out, info );
-	if ( (hasUnknownFloats2 != 0) ) {
-		for (unsigned int i2 = 0; i2 < unknownFloats2.size(); i2++) {
-			NifStream( unknownFloats2[i2], out, info );
-		};
+void NiPSysEmitterCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierCtlr::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 );
 	};
-	NifStream( hasUnknownFloats3, out, info );
-	if ( (hasUnknownFloats3 != 0) ) {
-		for (unsigned int i2 = 0; i2 < unknownFloats3.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 4; i3++) {
-				NifStream( unknownFloats3[i2][i3], out, info );
-			};
-		};
+	if ( info.version >= 0x0A020000 ) {
+		if ( visibilityInterpolator != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(visibilityInterpolator) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
 	};
 }
 
-std::string APSysData::InternalAsString( bool verbose ) const {
+std::string NiPSysEmitterCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiGeometryData::asString();
-	out << "  Has Unknown Floats 1:  " << hasUnknownFloats1 << endl;
-	if ( (hasUnknownFloats1 != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownFloats1.size(); 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 Floats 1[" << i2 << "]:  " << unknownFloats1[i2] << endl;
-			array_output_count++;
-		};
-	};
-	out << "  Unknown Short 3:  " << unknownShort3 << endl;
-	out << "  Has Unknown Floats 2:  " << hasUnknownFloats2 << endl;
-	if ( (hasUnknownFloats2 != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownFloats2.size(); 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 Floats 2[" << i2 << "]:  " << unknownFloats2[i2] << endl;
-			array_output_count++;
-		};
+	out << NiPSysModifierCtlr::asString();
+	out << "  Data:  " << data << endl;
+	out << "  Visibility Interpolator:  " << visibilityInterpolator << endl;
+	return out.str();
+}
+
+void NiPSysEmitterCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierCtlr::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiPSysEmitterCtlrData>( objects, link_stack, info );
 	};
-	out << "  Has Unknown Floats 3:  " << hasUnknownFloats3 << endl;
-	if ( (hasUnknownFloats3 != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownFloats3.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 < 4; i3++) {
-				if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-					break;
-				};
-				out << "        Unknown Floats 3[" << i3 << "]:  " << unknownFloats3[i2][i3] << endl;
-				array_output_count++;
-			};
-		};
+	if ( info.version >= 0x0A020000 ) {
+		visibilityInterpolator = FixLink<NiInterpolator>( objects, link_stack, info );
 	};
+}
+
+std::list<NiObjectRef> NiPSysEmitterCtlr::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiPSysModifierCtlr::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	if ( visibilityInterpolator != NULL )
+		refs.push_back(StaticCast<NiObject>(visibilityInterpolator));
+	return refs;
+}
+
+void NiPSysModifierBoolCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierCtlr::Read( in, link_stack, info );
+}
+
+void NiPSysModifierBoolCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierCtlr::Write( out, link_map, info );
+}
+
+std::string NiPSysModifierBoolCtlr::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiPSysModifierCtlr::asString();
 	return out.str();
 }
 
-void APSysData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometryData::FixLinks( objects, link_stack, info );
+void NiPSysModifierBoolCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierCtlr::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> APSysData::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysModifierBoolCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiGeometryData::GetRefs();
+	refs = NiPSysModifierCtlr::GetRefs();
 	return refs;
 }
 
-void bhkBlendCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiCollisionObject::Read( in, link_stack, info );
-	NifStream( unknownFloat1, in, info );
-	NifStream( unknownFloat2, in, info );
+void NiPSysModifierActiveCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiPSysModifierBoolCtlr::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
 }
 
-void bhkBlendCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiCollisionObject::Write( out, link_map, info );
-	NifStream( unknownFloat1, out, info );
-	NifStream( unknownFloat2, out, info );
+void NiPSysModifierActiveCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierBoolCtlr::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 bhkBlendCollisionObject::InternalAsString( bool verbose ) const {
+std::string NiPSysModifierActiveCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiCollisionObject::asString();
-	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
-	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
+	out << NiPSysModifierBoolCtlr::asString();
+	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
-void bhkBlendCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiCollisionObject::FixLinks( objects, link_stack, info );
+void NiPSysModifierActiveCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierBoolCtlr::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiVisData>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> bhkBlendCollisionObject::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysModifierActiveCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiCollisionObject::GetRefs();
+	refs = NiPSysModifierBoolCtlr::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
-void bhkBlendController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiTimeController::Read( in, link_stack, info );
-	NifStream( unknownInt, in, info );
+void NiPSysModifierFloatCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiPSysModifierCtlr::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
 }
 
-void bhkBlendController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	NifStream( unknownInt, out, info );
+void NiPSysModifierFloatCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierCtlr::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 bhkBlendController::InternalAsString( bool verbose ) const {
+std::string NiPSysModifierFloatCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	out << "  Unknown Int:  " << unknownInt << endl;
+	out << NiPSysModifierCtlr::asString();
+	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
-void bhkBlendController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiTimeController::FixLinks( objects, link_stack, info );
+void NiPSysModifierFloatCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierCtlr::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiFloatData>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> bhkBlendController::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysModifierFloatCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
+	refs = NiPSysModifierCtlr::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
-void bhkBoxShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkConvexShape::Read( in, link_stack, info );
-	NifStream( unknownFloat1, in, info );
-	NifStream( unknownShort1, in, info );
-	NifStream( unknownShort2, in, info );
-	NifStream( unknownShort3, in, info );
-	NifStream( unknownShort4, in, info );
-	NifStream( dimensions, in, info );
-	NifStream( min_Size, in, info );
+void NiPSysEmitterDeclinationCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::Read( in, link_stack, info );
 }
 
-void bhkBoxShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkConvexShape::Write( out, link_map, info );
-	NifStream( unknownFloat1, out, info );
-	NifStream( unknownShort1, out, info );
-	NifStream( unknownShort2, out, info );
-	NifStream( unknownShort3, out, info );
-	NifStream( unknownShort4, out, info );
-	NifStream( dimensions, out, info );
-	NifStream( min_Size, out, info );
+void NiPSysEmitterDeclinationCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierFloatCtlr::Write( out, link_map, info );
+}
+
+std::string NiPSysEmitterDeclinationCtlr::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiPSysModifierFloatCtlr::asString();
+	return out.str();
+}
+
+void NiPSysEmitterDeclinationCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiPSysEmitterDeclinationCtlr::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiPSysModifierFloatCtlr::GetRefs();
+	return refs;
+}
+
+void NiPSysEmitterDeclinationVarCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::Read( in, link_stack, info );
 }
 
-std::string bhkBoxShape::InternalAsString( bool verbose ) const {
+void NiPSysEmitterDeclinationVarCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierFloatCtlr::Write( out, link_map, info );
+}
+
+std::string NiPSysEmitterDeclinationVarCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkConvexShape::asString();
-	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
-	out << "  Unknown Short 1:  " << unknownShort1 << endl;
-	out << "  Unknown Short 2:  " << unknownShort2 << endl;
-	out << "  Unknown Short 3:  " << unknownShort3 << endl;
-	out << "  Unknown Short 4:  " << unknownShort4 << endl;
-	out << "  Dimensions:  " << dimensions << endl;
-	out << "  Min. size:  " << min_Size << endl;
+	out << NiPSysModifierFloatCtlr::asString();
 	return out.str();
 }
 
-void bhkBoxShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkConvexShape::FixLinks( objects, link_stack, info );
+void NiPSysEmitterDeclinationVarCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkBoxShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysEmitterDeclinationVarCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkConvexShape::GetRefs();
+	refs = NiPSysModifierFloatCtlr::GetRefs();
 	return refs;
 }
 
-void bhkCapsuleShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkConvexShape::Read( in, link_stack, info );
-	NifStream( radius, in, info );
-	NifStream( unknownShort1, in, info );
-	NifStream( unknownShort2, in, info );
-	NifStream( unknownShort3, in, info );
-	NifStream( unknownShort4, in, info );
-	NifStream( firstPoint, in, info );
-	NifStream( radius1, in, info );
-	NifStream( secondPoint, in, info );
-	NifStream( radius2, in, info );
+void NiPSysEmitterInitialRadiusCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::Read( in, link_stack, info );
 }
 
-void bhkCapsuleShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkConvexShape::Write( out, link_map, info );
-	NifStream( radius, out, info );
-	NifStream( unknownShort1, out, info );
-	NifStream( unknownShort2, out, info );
-	NifStream( unknownShort3, out, info );
-	NifStream( unknownShort4, out, info );
-	NifStream( firstPoint, out, info );
-	NifStream( radius1, out, info );
-	NifStream( secondPoint, out, info );
-	NifStream( radius2, out, info );
+void NiPSysEmitterInitialRadiusCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierFloatCtlr::Write( out, link_map, info );
 }
 
-std::string bhkCapsuleShape::InternalAsString( bool verbose ) const {
+std::string NiPSysEmitterInitialRadiusCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkConvexShape::asString();
-	out << "  Radius:  " << radius << endl;
-	out << "  Unknown Short 1:  " << unknownShort1 << endl;
-	out << "  Unknown Short 2:  " << unknownShort2 << endl;
-	out << "  Unknown Short 3:  " << unknownShort3 << endl;
-	out << "  Unknown Short 4:  " << unknownShort4 << endl;
-	out << "  First Point:  " << firstPoint << endl;
-	out << "  Radius 1:  " << radius1 << endl;
-	out << "  Second Point:  " << secondPoint << endl;
-	out << "  Radius 2:  " << radius2 << endl;
+	out << NiPSysModifierFloatCtlr::asString();
 	return out.str();
 }
 
-void bhkCapsuleShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkConvexShape::FixLinks( objects, link_stack, info );
+void NiPSysEmitterInitialRadiusCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkCapsuleShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysEmitterInitialRadiusCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkConvexShape::GetRefs();
+	refs = NiPSysModifierFloatCtlr::GetRefs();
 	return refs;
 }
 
-void bhkCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiCollisionObject::Read( in, link_stack, info );
+void NiPSysEmitterLifeSpanCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::Read( in, link_stack, info );
 }
 
-void bhkCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiCollisionObject::Write( out, link_map, info );
+void NiPSysEmitterLifeSpanCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierFloatCtlr::Write( out, link_map, info );
 }
 
-std::string bhkCollisionObject::InternalAsString( bool verbose ) const {
+std::string NiPSysEmitterLifeSpanCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiCollisionObject::asString();
+	out << NiPSysModifierFloatCtlr::asString();
 	return out.str();
 }
 
-void bhkCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiCollisionObject::FixLinks( objects, link_stack, info );
+void NiPSysEmitterLifeSpanCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkCollisionObject::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysEmitterLifeSpanCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiCollisionObject::GetRefs();
+	refs = NiPSysModifierFloatCtlr::GetRefs();
 	return refs;
 }
 
-void bhkConvexVerticesShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::Read( in, link_stack, info );
-	for (unsigned int i1 = 0; i1 < 7; i1++) {
-		NifStream( unknownFloats1[i1], in, info );
-	};
-	NifStream( numVertices, in, info );
-	vertices.resize(numVertices);
-	for (unsigned int i1 = 0; i1 < vertices.size(); i1++) {
-		NifStream( vertices[i1], in, info );
-	};
-	NifStream( numNormals, in, info );
-	normals.resize(numNormals);
-	for (unsigned int i1 = 0; i1 < normals.size(); i1++) {
-		NifStream( normals[i1], in, info );
-	};
+void NiPSysEmitterSpeedCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::Read( in, link_stack, info );
 }
 
-void bhkConvexVerticesShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkSphereRepShape::Write( out, link_map, info );
-	numNormals = (unsigned int)(normals.size());
-	numVertices = (unsigned int)(vertices.size());
-	for (unsigned int i1 = 0; i1 < 7; i1++) {
-		NifStream( unknownFloats1[i1], out, info );
-	};
-	NifStream( numVertices, out, info );
-	for (unsigned int i1 = 0; i1 < vertices.size(); i1++) {
-		NifStream( vertices[i1], out, info );
-	};
-	NifStream( numNormals, out, info );
-	for (unsigned int i1 = 0; i1 < normals.size(); i1++) {
-		NifStream( normals[i1], out, info );
-	};
+void NiPSysEmitterSpeedCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierFloatCtlr::Write( out, link_map, info );
 }
 
-std::string bhkConvexVerticesShape::InternalAsString( bool verbose ) const {
+std::string NiPSysEmitterSpeedCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkSphereRepShape::asString();
-	numNormals = (unsigned int)(normals.size());
-	numVertices = (unsigned int)(vertices.size());
-	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 Floats 1[" << i1 << "]:  " << unknownFloats1[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Num Vertices:  " << numVertices << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < vertices.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 << "    Vertices[" << i1 << "]:  " << vertices[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Num Normals:  " << numNormals << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < normals.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 << "    Normals[" << i1 << "]:  " << normals[i1] << endl;
-		array_output_count++;
-	};
+	out << NiPSysModifierFloatCtlr::asString();
 	return out.str();
 }
 
-void bhkConvexVerticesShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::FixLinks( objects, link_stack, info );
+void NiPSysEmitterSpeedCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkConvexVerticesShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysEmitterSpeedCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkSphereRepShape::GetRefs();
+	refs = NiPSysModifierFloatCtlr::GetRefs();
 	return refs;
 }
 
-void bhkHingeConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::Read( in, link_stack, info );
-	NifStream( pivotA, in, info );
-	NifStream( perp2axleina1, in, info );
-	NifStream( perp2axleina2, in, info );
-	NifStream( pivotB, in, info );
-	NifStream( axleB, in, info );
+void NiPSysGravityStrengthCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::Read( in, link_stack, info );
 }
 
-void bhkHingeConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkConstraint::Write( out, link_map, info );
-	NifStream( pivotA, out, info );
-	NifStream( perp2axleina1, out, info );
-	NifStream( perp2axleina2, out, info );
-	NifStream( pivotB, out, info );
-	NifStream( axleB, out, info );
+void NiPSysGravityStrengthCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifierFloatCtlr::Write( out, link_map, info );
 }
 
-std::string bhkHingeConstraint::InternalAsString( bool verbose ) const {
+std::string NiPSysGravityStrengthCtlr::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkConstraint::asString();
-	out << "  Pivot A:  " << pivotA << endl;
-	out << "  Perp2AxleInA1:  " << perp2axleina1 << endl;
-	out << "  Perp2AxleInA2:  " << perp2axleina2 << endl;
-	out << "  Pivot B:  " << pivotB << endl;
-	out << "  Axle B:  " << axleB << endl;
+	out << NiPSysModifierFloatCtlr::asString();
 	return out.str();
 }
 
-void bhkHingeConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::FixLinks( objects, link_stack, info );
+void NiPSysGravityStrengthCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifierFloatCtlr::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkHingeConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysGravityStrengthCtlr::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkConstraint::GetRefs();
+	refs = NiPSysModifierFloatCtlr::GetRefs();
 	return refs;
 }
 
-void bhkLimitedHingeConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::Read( in, link_stack, info );
-	NifStream( limitedHinge.pivotA, in, info );
-	NifStream( limitedHinge.axleA, in, info );
-	NifStream( limitedHinge.perp2axleina1, in, info );
-	NifStream( limitedHinge.perp2axleina2, in, info );
-	NifStream( limitedHinge.pivotB, in, info );
-	NifStream( limitedHinge.axleB, in, info );
-	NifStream( limitedHinge.perp2axleinb2, in, info );
-	NifStream( limitedHinge.minAngle, in, info );
-	NifStream( limitedHinge.maxAngle, in, info );
-	NifStream( limitedHinge.maxFriction, in, info );
+void NiFloatInterpController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::Read( in, link_stack, info );
 }
 
-void bhkLimitedHingeConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkConstraint::Write( out, link_map, info );
-	NifStream( limitedHinge.pivotA, out, info );
-	NifStream( limitedHinge.axleA, out, info );
-	NifStream( limitedHinge.perp2axleina1, out, info );
-	NifStream( limitedHinge.perp2axleina2, out, info );
-	NifStream( limitedHinge.pivotB, out, info );
-	NifStream( limitedHinge.axleB, out, info );
-	NifStream( limitedHinge.perp2axleinb2, out, info );
-	NifStream( limitedHinge.minAngle, out, info );
-	NifStream( limitedHinge.maxAngle, out, info );
-	NifStream( limitedHinge.maxFriction, out, info );
+void NiFloatInterpController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiSingleInterpController::Write( out, link_map, info );
 }
 
-std::string bhkLimitedHingeConstraint::InternalAsString( bool verbose ) const {
+std::string NiFloatInterpController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkConstraint::asString();
-	out << "  Pivot A:  " << limitedHinge.pivotA << endl;
-	out << "  Axle A:  " << limitedHinge.axleA << endl;
-	out << "  Perp2AxleInA1:  " << limitedHinge.perp2axleina1 << endl;
-	out << "  Perp2AxleInA2:  " << limitedHinge.perp2axleina2 << endl;
-	out << "  Pivot B:  " << limitedHinge.pivotB << endl;
-	out << "  Axle B:  " << limitedHinge.axleB << endl;
-	out << "  Perp2AxleInB2:  " << limitedHinge.perp2axleinb2 << endl;
-	out << "  Min Angle:  " << limitedHinge.minAngle << endl;
-	out << "  Max Angle:  " << limitedHinge.maxAngle << endl;
-	out << "  Max Friction:  " << limitedHinge.maxFriction << endl;
+	out << NiSingleInterpController::asString();
 	return out.str();
 }
 
-void bhkLimitedHingeConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::FixLinks( objects, link_stack, info );
+void NiFloatInterpController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkLimitedHingeConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> NiFloatInterpController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkConstraint::GetRefs();
+	refs = NiSingleInterpController::GetRefs();
 	return refs;
 }
 
-void bhkListShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiFlipController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	AbhkShapeCollection::Read( in, link_stack, info );
-	NifStream( numSubShapes, in, info );
-	subShapes.resize(numSubShapes);
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
+	NiFloatInterpController::Read( in, link_stack, info );
+	NifStream( textureSlot, in, info );
+	if ( ( info.version >= 0x04000000 ) && ( info.version <= 0x0A010000 ) ) {
+		NifStream( unknownInt2, in, info );
 	};
-	NifStream( material, in, info );
-	for (unsigned int i1 = 0; i1 < 6; i1++) {
-		NifStream( unknownFloats[i1], in, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( delta, in, info );
 	};
-	NifStream( numUnknownInts, in, info );
-	unknownInts.resize(numUnknownInts);
-	for (unsigned int i1 = 0; i1 < unknownInts.size(); i1++) {
-		NifStream( unknownInts[i1], in, info );
+	NifStream( numSources, in, info );
+	if ( info.version >= 0x04000000 ) {
+		sources.resize(numSources);
+		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
+		};
+	};
+	if ( info.version <= 0x03010000 ) {
+		image.resize(numSources);
+		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
+		};
+	};
+}
+
+void NiFlipController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiFloatInterpController::Write( out, link_map, info );
+	numSources = (unsigned int)(sources.size());
+	NifStream( textureSlot, out, info );
+	if ( ( info.version >= 0x04000000 ) && ( info.version <= 0x0A010000 ) ) {
+		NifStream( unknownInt2, out, info );
 	};
-}
-
-void bhkListShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkShapeCollection::Write( out, link_map, info );
-	numUnknownInts = (unsigned int)(unknownInts.size());
-	numSubShapes = (unsigned int)(subShapes.size());
-	NifStream( numSubShapes, out, info );
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		if ( subShapes[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(subShapes[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( delta, out, info );
 	};
-	NifStream( material, out, info );
-	for (unsigned int i1 = 0; i1 < 6; i1++) {
-		NifStream( unknownFloats[i1], out, info );
+	NifStream( numSources, out, info );
+	if ( info.version >= 0x04000000 ) {
+		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
+			if ( sources[i2] != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(sources[i2]) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
+		};
 	};
-	NifStream( numUnknownInts, out, info );
-	for (unsigned int i1 = 0; i1 < unknownInts.size(); i1++) {
-		NifStream( unknownInts[i1], out, info );
+	if ( info.version <= 0x03010000 ) {
+		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
+			if ( image[i2] != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(image[i2]) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
+		};
 	};
 }
 
-std::string bhkListShape::InternalAsString( bool verbose ) const {
+std::string NiFlipController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkShapeCollection::asString();
-	numUnknownInts = (unsigned int)(unknownInts.size());
-	numSubShapes = (unsigned int)(subShapes.size());
-	out << "  Num Sub Shapes:  " << numSubShapes << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < subShapes.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 << "    Sub Shapes[" << i1 << "]:  " << subShapes[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Material:  " << material << endl;
+	out << NiFloatInterpController::asString();
+	numSources = (unsigned int)(sources.size());
+	out << "  Texture Slot:  " << textureSlot << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Delta:  " << delta << endl;
+	out << "  Num Sources:  " << numSources << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 6; i1++) {
+	for (unsigned int i1 = 0; i1 < sources.size(); i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 			break;
@@ -2699,12 +4294,11 @@ std::string bhkListShape::InternalAsString( bool verbose ) const {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			break;
 		};
-		out << "    Unknown Floats[" << i1 << "]:  " << unknownFloats[i1] << endl;
+		out << "    Sources[" << i1 << "]:  " << sources[i1] << endl;
 		array_output_count++;
 	};
-	out << "  Num Unknown Ints:  " << numUnknownInts << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownInts.size(); i1++) {
+	for (unsigned int i1 = 0; i1 < image.size(); i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 			break;
@@ -2712,584 +4306,511 @@ std::string bhkListShape::InternalAsString( bool verbose ) const {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			break;
 		};
-		out << "    Unknown Ints[" << i1 << "]:  " << unknownInts[i1] << endl;
+		out << "    Image[" << i1 << "]:  " << image[i1] << endl;
 		array_output_count++;
 	};
 	return out.str();
 }
 
-void bhkListShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkShapeCollection::FixLinks( objects, link_stack, info );
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		subShapes[i1] = FixLink<bhkShape>( objects, link_stack, info );
+void NiFlipController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiFloatInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version >= 0x04000000 ) {
+		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
+			sources[i2] = FixLink<NiSourceTexture>( objects, link_stack, info );
+		};
+	};
+	if ( info.version <= 0x03010000 ) {
+		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
+			image[i2] = FixLink<NiImage>( objects, link_stack, info );
+		};
 	};
 }
 
-std::list<NiObjectRef> bhkListShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiFlipController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkShapeCollection::GetRefs();
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		if ( subShapes[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(subShapes[i1]));
+	refs = NiFloatInterpController::GetRefs();
+	for (unsigned int i1 = 0; i1 < sources.size(); i1++) {
+		if ( sources[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(sources[i1]));
+	};
+	for (unsigned int i1 = 0; i1 < image.size(); i1++) {
+		if ( image[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(image[i1]));
 	};
 	return refs;
 }
 
-void bhkMalleableConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiAlphaController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	AbhkConstraint::Read( in, link_stack, info );
-	NifStream( type, in, info );
-	NifStream( unknownInt2, 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( unknownInt3, in, info );
-	if ( (type == 7) ) {
-		NifStream( ragdoll.pivotA, in, info );
-		NifStream( ragdoll.planeA, in, info );
-		NifStream( ragdoll.twistA, in, info );
-		NifStream( ragdoll.pivotB, in, info );
-		NifStream( ragdoll.planeB, in, info );
-		NifStream( ragdoll.twistB, in, info );
-		NifStream( ragdoll.coneMinAngle, in, info );
-		NifStream( ragdoll.planeMinAngle, in, info );
-		NifStream( ragdoll.planeMaxAngle, in, info );
-		NifStream( ragdoll.twistMinAngle, in, info );
-		NifStream( ragdoll.twistMaxAngle, in, info );
-		NifStream( ragdoll.maxFriction, in, info );
+	NiFloatInterpController::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
-	if ( (type == 2) ) {
-		NifStream( limitedHinge.pivotA, in, info );
-		NifStream( limitedHinge.axleA, in, info );
-		NifStream( limitedHinge.perp2axleina1, in, info );
-		NifStream( limitedHinge.perp2axleina2, in, info );
-		NifStream( limitedHinge.pivotB, in, info );
-		NifStream( limitedHinge.axleB, in, info );
-		NifStream( limitedHinge.perp2axleinb2, in, info );
-		NifStream( limitedHinge.minAngle, in, info );
-		NifStream( limitedHinge.maxAngle, in, info );
-		NifStream( limitedHinge.maxFriction, in, info );
+}
+
+void NiAlphaController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiFloatInterpController::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 );
 	};
-	NifStream( tau, in, info );
-	NifStream( damping, in, info );
 }
 
-void bhkMalleableConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkConstraint::Write( out, link_map, info );
-	NifStream( type, out, info );
-	NifStream( unknownInt2, out, info );
-	if ( unknownLink1 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( unknownLink2 != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( unknownInt3, out, info );
-	if ( (type == 7) ) {
-		NifStream( ragdoll.pivotA, out, info );
-		NifStream( ragdoll.planeA, out, info );
-		NifStream( ragdoll.twistA, out, info );
-		NifStream( ragdoll.pivotB, out, info );
-		NifStream( ragdoll.planeB, out, info );
-		NifStream( ragdoll.twistB, out, info );
-		NifStream( ragdoll.coneMinAngle, out, info );
-		NifStream( ragdoll.planeMinAngle, out, info );
-		NifStream( ragdoll.planeMaxAngle, out, info );
-		NifStream( ragdoll.twistMinAngle, out, info );
-		NifStream( ragdoll.twistMaxAngle, out, info );
-		NifStream( ragdoll.maxFriction, out, info );
+std::string NiAlphaController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiFloatInterpController::asString();
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiAlphaController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiFloatInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiFloatData>( objects, link_stack, info );
 	};
-	if ( (type == 2) ) {
-		NifStream( limitedHinge.pivotA, out, info );
-		NifStream( limitedHinge.axleA, out, info );
-		NifStream( limitedHinge.perp2axleina1, out, info );
-		NifStream( limitedHinge.perp2axleina2, out, info );
-		NifStream( limitedHinge.pivotB, out, info );
-		NifStream( limitedHinge.axleB, out, info );
-		NifStream( limitedHinge.perp2axleinb2, out, info );
-		NifStream( limitedHinge.minAngle, out, info );
-		NifStream( limitedHinge.maxAngle, out, info );
-		NifStream( limitedHinge.maxFriction, out, info );
+}
+
+std::list<NiObjectRef> NiAlphaController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiFloatInterpController::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiTextureTransformController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiFloatInterpController::Read( in, link_stack, info );
+	NifStream( unknown2, in, info );
+	NifStream( textureSlot, in, info );
+	NifStream( operation, in, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
-	NifStream( tau, out, info );
-	NifStream( damping, out, info );
 }
 
-std::string bhkMalleableConstraint::InternalAsString( bool verbose ) const {
+void NiTextureTransformController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiFloatInterpController::Write( out, link_map, info );
+	NifStream( unknown2, out, info );
+	NifStream( textureSlot, out, info );
+	NifStream( operation, out, 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 NiTextureTransformController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkConstraint::asString();
-	out << "  Type:  " << type << endl;
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Unknown Link 1:  " << unknownLink1 << endl;
-	out << "  Unknown Link 2:  " << unknownLink2 << endl;
-	out << "  Unknown Int 3:  " << unknownInt3 << endl;
-	if ( (type == 7) ) {
-		out << "    Pivot A:  " << ragdoll.pivotA << endl;
-		out << "    Plane A:  " << ragdoll.planeA << endl;
-		out << "    Twist A:  " << ragdoll.twistA << endl;
-		out << "    Pivot B:  " << ragdoll.pivotB << endl;
-		out << "    Plane B:  " << ragdoll.planeB << endl;
-		out << "    Twist B:  " << ragdoll.twistB << endl;
-		out << "    Cone Min Angle:  " << ragdoll.coneMinAngle << endl;
-		out << "    Plane Min Angle:  " << ragdoll.planeMinAngle << endl;
-		out << "    Plane Max Angle:  " << ragdoll.planeMaxAngle << endl;
-		out << "    Twist Min Angle:  " << ragdoll.twistMinAngle << endl;
-		out << "    Twist Max Angle:  " << ragdoll.twistMaxAngle << endl;
-		out << "    Max Friction:  " << ragdoll.maxFriction << endl;
-	};
-	if ( (type == 2) ) {
-		out << "    Pivot A:  " << limitedHinge.pivotA << endl;
-		out << "    Axle A:  " << limitedHinge.axleA << endl;
-		out << "    Perp2AxleInA1:  " << limitedHinge.perp2axleina1 << endl;
-		out << "    Perp2AxleInA2:  " << limitedHinge.perp2axleina2 << endl;
-		out << "    Pivot B:  " << limitedHinge.pivotB << endl;
-		out << "    Axle B:  " << limitedHinge.axleB << endl;
-		out << "    Perp2AxleInB2:  " << limitedHinge.perp2axleinb2 << endl;
-		out << "    Min Angle:  " << limitedHinge.minAngle << endl;
-		out << "    Max Angle:  " << limitedHinge.maxAngle << endl;
-		out << "    Max Friction:  " << limitedHinge.maxFriction << endl;
+	out << NiFloatInterpController::asString();
+	out << "  Unknown2:  " << unknown2 << endl;
+	out << "  Texture Slot:  " << textureSlot << endl;
+	out << "  Operation:  " << operation << endl;
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiTextureTransformController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiFloatInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiFloatData>( objects, link_stack, info );
 	};
-	out << "  Tau:  " << tau << endl;
-	out << "  Damping:  " << damping << endl;
+}
+
+std::list<NiObjectRef> NiTextureTransformController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiFloatInterpController::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiLightDimmerController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiFloatInterpController::Read( in, link_stack, info );
+}
+
+void NiLightDimmerController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiFloatInterpController::Write( out, link_map, info );
+}
+
+std::string NiLightDimmerController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiFloatInterpController::asString();
 	return out.str();
 }
 
-void bhkMalleableConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::FixLinks( objects, link_stack, info );
-	unknownLink1 = FixLink<NiObject>( objects, link_stack, info );
-	unknownLink2 = FixLink<NiObject>( objects, link_stack, info );
+void NiLightDimmerController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiFloatInterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkMalleableConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> NiLightDimmerController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkConstraint::GetRefs();
-	if ( unknownLink1 != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink1));
-	if ( unknownLink2 != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink2));
+	refs = NiFloatInterpController::GetRefs();
 	return refs;
 }
 
-void bhkMoppBvTreeShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	bhkShape::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( material, in, info );
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		NifStream( unknown8Bytes[i1], in, info );
-	};
-	NifStream( unknownFloat, in, info );
-	NifStream( moppDataSize, in, info );
-	if ( info.version >= 0x14000005 ) {
-		NifStream( objectCorner, in, info );
-		NifStream( scalingFactor, in, info );
-	};
-	moppData.resize(moppDataSize);
-	for (unsigned int i1 = 0; i1 < moppData.size(); i1++) {
-		NifStream( moppData[i1], in, info );
-	};
+void NiBoolInterpController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::Read( in, link_stack, info );
 }
 
-void bhkMoppBvTreeShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkShape::Write( out, link_map, info );
-	moppDataSize = (unsigned int)(moppData.size());
-	if ( shape != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(shape) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( material, out, info );
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		NifStream( unknown8Bytes[i1], out, info );
-	};
-	NifStream( unknownFloat, out, info );
-	NifStream( moppDataSize, out, info );
-	if ( info.version >= 0x14000005 ) {
-		NifStream( objectCorner, out, info );
-		NifStream( scalingFactor, out, info );
-	};
-	for (unsigned int i1 = 0; i1 < moppData.size(); i1++) {
-		NifStream( moppData[i1], out, info );
-	};
+void NiBoolInterpController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiSingleInterpController::Write( out, link_map, info );
 }
 
-std::string bhkMoppBvTreeShape::InternalAsString( bool verbose ) const {
+std::string NiBoolInterpController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkShape::asString();
-	moppDataSize = (unsigned int)(moppData.size());
-	out << "  Shape:  " << shape << endl;
-	out << "  Material:  " << material << endl;
-	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 8 Bytes[" << i1 << "]:  " << unknown8Bytes[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Unknown Float:  " << unknownFloat << endl;
-	out << "  MOPP Data Size:  " << moppDataSize << endl;
-	out << "  Object Corner:  " << objectCorner << endl;
-	out << "  Scaling Factor:  " << scalingFactor << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < moppData.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 << "    MOPP Data[" << i1 << "]:  " << moppData[i1] << endl;
-		array_output_count++;
-	};
+	out << NiSingleInterpController::asString();
 	return out.str();
 }
 
-void bhkMoppBvTreeShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkShape::FixLinks( objects, link_stack, info );
-	shape = FixLink<bhkShape>( objects, link_stack, info );
+void NiBoolInterpController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkMoppBvTreeShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiBoolInterpController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkShape::GetRefs();
-	if ( shape != NULL )
-		refs.push_back(StaticCast<NiObject>(shape));
+	refs = NiSingleInterpController::GetRefs();
 	return refs;
 }
 
-void bhkMultiSphereShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::Read( in, link_stack, info );
-	NifStream( unknownFloat1, in, info );
-	NifStream( unknownFloat2, in, info );
-	NifStream( unknownFloat3, in, info );
-	NifStream( numSpheres, in, info );
-	spheres.resize(numSpheres);
-	for (unsigned int i1 = 0; i1 < spheres.size(); i1++) {
-		NifStream( spheres[i1].center, in, info );
-		NifStream( spheres[i1].radius, in, info );
+void NiVisController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiBoolInterpController::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
 }
 
-void bhkMultiSphereShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkSphereRepShape::Write( out, link_map, info );
-	numSpheres = (unsigned int)(spheres.size());
-	NifStream( unknownFloat1, out, info );
-	NifStream( unknownFloat2, out, info );
-	NifStream( unknownFloat3, out, info );
-	NifStream( numSpheres, out, info );
-	for (unsigned int i1 = 0; i1 < spheres.size(); i1++) {
-		NifStream( spheres[i1].center, out, info );
-		NifStream( spheres[i1].radius, out, info );
+void NiVisController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBoolInterpController::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 bhkMultiSphereShape::InternalAsString( bool verbose ) const {
+std::string NiVisController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkSphereRepShape::asString();
-	numSpheres = (unsigned int)(spheres.size());
-	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
-	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
-	out << "  Unknown Float 3:  " << unknownFloat3 << endl;
-	out << "  Num Spheres:  " << numSpheres << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < spheres.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		out << "    Center:  " << spheres[i1].center << endl;
-		out << "    Radius:  " << spheres[i1].radius << endl;
-	};
+	out << NiBoolInterpController::asString();
+	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
-void bhkMultiSphereShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkSphereRepShape::FixLinks( objects, link_stack, info );
+void NiVisController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBoolInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiVisData>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> bhkMultiSphereShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiVisController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkSphereRepShape::GetRefs();
+	refs = NiBoolInterpController::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
-void bhkNiTriStripsShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiPoint3InterpController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	bhkSphereRepShape::Read( in, link_stack, info );
-	NifStream( unknownFloat1, in, info );
-	NifStream( unknownInt1, in, info );
-	for (unsigned int i1 = 0; i1 < 4; i1++) {
-		NifStream( unknownInts1[i1], in, info );
+	NiSingleInterpController::Read( in, link_stack, info );
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( targetColor, in, info );
 	};
-	NifStream( unknownInt2, in, info );
-	NifStream( scale, in, info );
-	NifStream( unknownInt3, in, info );
-	NifStream( numStripsData, in, info );
-	stripsData.resize(numStripsData);
-	for (unsigned int i1 = 0; i1 < stripsData.size(); i1++) {
+	if ( info.version <= 0x0A010000 ) {
 		NifStream( block_num, in, info );
 		link_stack.push_back( block_num );
 	};
-	NifStream( numDataLayers, in, info );
-	dataLayers.resize(numDataLayers);
-	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
-		NifStream( dataLayers[i1].layer, in, info );
-		NifStream( dataLayers[i1].colFilter, in, info );
-		NifStream( dataLayers[i1].unknownShort, in, info );
-	};
 }
 
-void bhkNiTriStripsShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkSphereRepShape::Write( out, link_map, info );
-	numDataLayers = (unsigned int)(dataLayers.size());
-	numStripsData = (unsigned int)(stripsData.size());
-	NifStream( unknownFloat1, out, info );
-	NifStream( unknownInt1, out, info );
-	for (unsigned int i1 = 0; i1 < 4; i1++) {
-		NifStream( unknownInts1[i1], out, info );
+void NiPoint3InterpController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiSingleInterpController::Write( out, link_map, info );
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( targetColor, out, info );
 	};
-	NifStream( unknownInt2, out, info );
-	NifStream( scale, out, info );
-	NifStream( unknownInt3, 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 );
+	if ( info.version <= 0x0A010000 ) {
+		if ( data != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
 		else
 			NifStream( 0xffffffff, out, info );
 	};
-	NifStream( numDataLayers, out, info );
-	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
-		NifStream( dataLayers[i1].layer, out, info );
-		NifStream( dataLayers[i1].colFilter, out, info );
-		NifStream( dataLayers[i1].unknownShort, out, info );
+}
+
+std::string NiPoint3InterpController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiSingleInterpController::asString();
+	out << "  Target Color:  " << targetColor << endl;
+	out << "  Data:  " << data << endl;
+	return out.str();
+}
+
+void NiPoint3InterpController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiPosData>( objects, link_stack, info );
 	};
 }
 
-std::string bhkNiTriStripsShape::InternalAsString( bool verbose ) const {
+std::list<NiObjectRef> NiPoint3InterpController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiSingleInterpController::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	return refs;
+}
+
+void NiMaterialColorController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPoint3InterpController::Read( in, link_stack, info );
+}
+
+void NiMaterialColorController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPoint3InterpController::Write( out, link_map, info );
+}
+
+std::string NiMaterialColorController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiPoint3InterpController::asString();
+	return out.str();
+}
+
+void NiMaterialColorController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPoint3InterpController::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiMaterialColorController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiPoint3InterpController::GetRefs();
+	return refs;
+}
+
+void NiLightColorController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPoint3InterpController::Read( in, link_stack, info );
+}
+
+void NiLightColorController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPoint3InterpController::Write( out, link_map, info );
+}
+
+std::string NiLightColorController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkSphereRepShape::asString();
-	numDataLayers = (unsigned int)(dataLayers.size());
-	numStripsData = (unsigned int)(stripsData.size());
-	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
-	out << "  Unknown Int 1:  " << unknownInt1 << 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 Ints 1[" << i1 << "]:  " << unknownInts1[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Scale:  " << scale << endl;
-	out << "  Unknown Int 3:  " << unknownInt3 << endl;
-	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++;
-	};
-	out << "  Num Data Layers:  " << numDataLayers << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < dataLayers.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		out << "    Layer:  " << dataLayers[i1].layer << endl;
-		out << "    Col Filter:  " << dataLayers[i1].colFilter << endl;
-		out << "    Unknown Short:  " << dataLayers[i1].unknownShort << endl;
-	};
+	out << NiPoint3InterpController::asString();
 	return out.str();
 }
 
-void bhkNiTriStripsShape::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 );
-	};
+void NiLightColorController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPoint3InterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkNiTriStripsShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiLightColorController::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]));
-	};
+	refs = NiPoint3InterpController::GetRefs();
 	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 );
-	NifStream( numSubShapes, in, info );
-	subShapes.resize(numSubShapes);
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		NifStream( subShapes[i1].layer, in, info );
-		NifStream( subShapes[i1].colFilter, in, info );
-		NifStream( subShapes[i1].unknownShort, in, info );
-		NifStream( subShapes[i1].vertexCount___, in, info );
-		NifStream( subShapes[i1].material, in, info );
-	};
-	for (unsigned int i1 = 0; i1 < 9; i1++) {
-		NifStream( unknownFloats[i1], in, info );
-	};
-	NifStream( scale, in, info );
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknownFloats2[i1], in, info );
-	};
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
+void NiExtraDataController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::Read( in, link_stack, info );
 }
 
-void bhkPackedNiTriStripsShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkShapeCollection::Write( out, link_map, info );
-	numSubShapes = (unsigned short)(subShapes.size());
-	NifStream( numSubShapes, out, info );
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		NifStream( subShapes[i1].layer, out, info );
-		NifStream( subShapes[i1].colFilter, out, info );
-		NifStream( subShapes[i1].unknownShort, out, info );
-		NifStream( subShapes[i1].vertexCount___, out, info );
-		NifStream( subShapes[i1].material, out, info );
-	};
-	for (unsigned int i1 = 0; i1 < 9; i1++) {
-		NifStream( unknownFloats[i1], out, info );
-	};
-	NifStream( scale, out, info );
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknownFloats2[i1], out, info );
-	};
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+void NiExtraDataController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiSingleInterpController::Write( out, link_map, info );
 }
 
-std::string bhkPackedNiTriStripsShape::InternalAsString( bool verbose ) const {
+std::string NiExtraDataController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkShapeCollection::asString();
-	numSubShapes = (unsigned short)(subShapes.size());
-	out << "  Num Sub Shapes:  " << numSubShapes << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < subShapes.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		out << "    Layer:  " << subShapes[i1].layer << endl;
-		out << "    Col Filter:  " << subShapes[i1].colFilter << endl;
-		out << "    Unknown Short:  " << subShapes[i1].unknownShort << endl;
-		out << "    Vertex Count (?):  " << subShapes[i1].vertexCount___ << endl;
-		out << "    Material:  " << subShapes[i1].material << endl;
-	};
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 9; 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 Floats[" << i1 << "]:  " << unknownFloats[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Scale:  " << scale << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 3; 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 Floats 2[" << i1 << "]:  " << unknownFloats2[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Data:  " << data << endl;
+	out << NiSingleInterpController::asString();
 	return out.str();
 }
 
-void bhkPackedNiTriStripsShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkShapeCollection::FixLinks( objects, link_stack, info );
-	data = FixLink<hkPackedNiTriStripsData>( objects, link_stack, info );
+void NiExtraDataController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkPackedNiTriStripsShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiExtraDataController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkShapeCollection::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
+	refs = NiSingleInterpController::GetRefs();
 	return refs;
 }
 
-void bhkPrismaticConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::Read( in, link_stack, info );
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		NifStream( unknownVectors[i1], in, info );
+void NiFloatExtraDataController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiExtraDataController::Read( in, link_stack, info );
+	NifStream( controllerData, in, info );
+}
+
+void NiFloatExtraDataController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiExtraDataController::Write( out, link_map, info );
+	NifStream( controllerData, out, info );
+}
+
+std::string NiFloatExtraDataController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiExtraDataController::asString();
+	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 ) {
+	NiExtraDataController::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiFloatExtraDataController::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiExtraDataController::GetRefs();
+	return refs;
+}
+
+void NiBoneLODController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiTimeController::Read( in, link_stack, info );
+	NifStream( unknownInt1, in, info );
+	NifStream( numNodeGroups, in, info );
+	NifStream( numNodeGroups2, in, info );
+	nodeGroups.resize(numNodeGroups);
+	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
+		NifStream( nodeGroups[i1].numNodes, in, info );
+		nodeGroups[i1].nodes.resize(nodeGroups[i1].numNodes);
+		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
+		};
 	};
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknownFloats2[i1], in, info );
+	if ( info.version <= 0x0A000100 ) {
+		NifStream( numShapeGroups, in, info );
+		shapeGroups1.resize(numShapeGroups);
+		for (unsigned int i2 = 0; i2 < shapeGroups1.size(); i2++) {
+			NifStream( shapeGroups1[i2].numLinkPairs, in, info );
+			shapeGroups1[i2].linkPairs.resize(shapeGroups1[i2].numLinkPairs);
+			for (unsigned int i3 = 0; i3 < shapeGroups1[i2].linkPairs.size(); i3++) {
+				NifStream( block_num, in, info );
+				link_stack.push_back( block_num );
+				NifStream( block_num, in, info );
+				link_stack.push_back( block_num );
+			};
+		};
+		NifStream( numShapeGroups2, in, info );
+		shapeGroups2.resize(numShapeGroups2);
+		for (unsigned int i2 = 0; i2 < shapeGroups2.size(); i2++) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
+		};
 	};
 }
 
-void bhkPrismaticConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkConstraint::Write( out, link_map, info );
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
-		NifStream( unknownVectors[i1], out, info );
+void NiBoneLODController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiTimeController::Write( out, link_map, info );
+	numShapeGroups2 = (unsigned int)(shapeGroups2.size());
+	numShapeGroups = (unsigned int)(shapeGroups1.size());
+	numNodeGroups = (unsigned int)(nodeGroups.size());
+	NifStream( unknownInt1, out, info );
+	NifStream( numNodeGroups, out, info );
+	NifStream( numNodeGroups2, out, info );
+	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
+		nodeGroups[i1].numNodes = (unsigned int)(nodeGroups[i1].nodes.size());
+		NifStream( nodeGroups[i1].numNodes, out, info );
+		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
+			if ( nodeGroups[i1].nodes[i2] != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(nodeGroups[i1].nodes[i2]) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
+		};
 	};
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		NifStream( unknownFloats2[i1], out, info );
+	if ( info.version <= 0x0A000100 ) {
+		NifStream( numShapeGroups, out, info );
+		for (unsigned int i2 = 0; i2 < shapeGroups1.size(); i2++) {
+			shapeGroups1[i2].numLinkPairs = (unsigned int)(shapeGroups1[i2].linkPairs.size());
+			NifStream( shapeGroups1[i2].numLinkPairs, out, info );
+			for (unsigned int i3 = 0; i3 < shapeGroups1[i2].linkPairs.size(); i3++) {
+				if ( shapeGroups1[i2].linkPairs[i3].shape != NULL )
+					NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i2].linkPairs[i3].shape) )->second, out, info );
+				else
+					NifStream( 0xffffffff, out, info );
+				if ( shapeGroups1[i2].linkPairs[i3].skinInstance != NULL )
+					NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i2].linkPairs[i3].skinInstance) )->second, out, info );
+				else
+					NifStream( 0xffffffff, out, info );
+			};
+		};
+		NifStream( numShapeGroups2, out, info );
+		for (unsigned int i2 = 0; i2 < shapeGroups2.size(); i2++) {
+			if ( shapeGroups2[i2] != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(shapeGroups2[i2]) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
+		};
+	};
+}
+
+std::string NiBoneLODController::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiTimeController::asString();
+	numShapeGroups2 = (unsigned int)(shapeGroups2.size());
+	numShapeGroups = (unsigned int)(shapeGroups1.size());
+	numNodeGroups = (unsigned int)(nodeGroups.size());
+	out << "  Unknown Int 1:  " << unknownInt1 << endl;
+	out << "  Num Node Groups:  " << numNodeGroups << endl;
+	out << "  Num Node Groups 2:  " << numNodeGroups2 << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
+		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+			break;
+		};
+		nodeGroups[i1].numNodes = (unsigned int)(nodeGroups[i1].nodes.size());
+		out << "    Num Nodes:  " << nodeGroups[i1].numNodes << endl;
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); 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 << "      Nodes[" << i2 << "]:  " << nodeGroups[i1].nodes[i2] << endl;
+			array_output_count++;
+		};
 	};
-}
-
-std::string bhkPrismaticConstraint::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << AbhkConstraint::asString();
+	out << "  Num Shape Groups:  " << numShapeGroups << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 8; i1++) {
+	for (unsigned int i1 = 0; i1 < shapeGroups1.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;
+		shapeGroups1[i1].numLinkPairs = (unsigned int)(shapeGroups1[i1].linkPairs.size());
+		out << "    Num Link Pairs:  " << shapeGroups1[i1].numLinkPairs << endl;
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
+				break;
+			};
+			out << "      Shape:  " << shapeGroups1[i1].linkPairs[i2].shape << endl;
+			out << "      Skin Instance:  " << shapeGroups1[i1].linkPairs[i2].skinInstance << endl;
 		};
-		out << "    Unknown Vectors[" << i1 << "]:  " << unknownVectors[i1] << endl;
-		array_output_count++;
 	};
+	out << "  Num Shape Groups 2:  " << numShapeGroups2 << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
+	for (unsigned int i1 = 0; i1 < shapeGroups2.size(); i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 			break;
@@ -3297,514 +4818,515 @@ std::string bhkPrismaticConstraint::InternalAsString( bool verbose ) const {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 			break;
 		};
-		out << "    Unknown Floats 2[" << i1 << "]:  " << unknownFloats2[i1] << endl;
+		out << "    Shape Groups 2[" << i1 << "]:  " << shapeGroups2[i1] << endl;
 		array_output_count++;
 	};
 	return out.str();
 }
 
-void bhkPrismaticConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::FixLinks( objects, link_stack, info );
+void NiBoneLODController::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 < nodeGroups.size(); i1++) {
+		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
+			nodeGroups[i1].nodes[i2] = FixLink<NiNode>( objects, link_stack, info );
+		};
+	};
+	if ( info.version <= 0x0A000100 ) {
+		for (unsigned int i2 = 0; i2 < shapeGroups1.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < shapeGroups1[i2].linkPairs.size(); i3++) {
+				shapeGroups1[i2].linkPairs[i3].shape = FixLink<NiTriShape>( objects, link_stack, info );
+				shapeGroups1[i2].linkPairs[i3].skinInstance = FixLink<NiSkinInstance>( objects, link_stack, info );
+			};
+		};
+		for (unsigned int i2 = 0; i2 < shapeGroups2.size(); i2++) {
+			shapeGroups2[i2] = FixLink<NiTriShape>( objects, link_stack, info );
+		};
+	};
 }
 
-std::list<NiObjectRef> bhkPrismaticConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> NiBoneLODController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkConstraint::GetRefs();
+	refs = NiTimeController::GetRefs();
+	for (unsigned int i1 = 0; i1 < nodeGroups.size(); i1++) {
+		for (unsigned int i2 = 0; i2 < nodeGroups[i1].nodes.size(); i2++) {
+		};
+	};
+	for (unsigned int i1 = 0; i1 < shapeGroups1.size(); i1++) {
+		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
+			if ( shapeGroups1[i1].linkPairs[i2].shape != NULL )
+				refs.push_back(StaticCast<NiObject>(shapeGroups1[i1].linkPairs[i2].shape));
+			if ( shapeGroups1[i1].linkPairs[i2].skinInstance != NULL )
+				refs.push_back(StaticCast<NiObject>(shapeGroups1[i1].linkPairs[i2].skinInstance));
+		};
+	};
+	for (unsigned int i1 = 0; i1 < shapeGroups2.size(); i1++) {
+		if ( shapeGroups2[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(shapeGroups2[i1]));
+	};
 	return refs;
 }
 
-void bhkRagdollConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkRagdollConstraint::Read( in, link_stack, info );
+void NiBSBoneLODController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBoneLODController::Read( in, link_stack, info );
 }
 
-void bhkRagdollConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkRagdollConstraint::Write( out, link_map, info );
+void NiBSBoneLODController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBoneLODController::Write( out, link_map, info );
 }
 
-std::string bhkRagdollConstraint::InternalAsString( bool verbose ) const {
+std::string NiBSBoneLODController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkRagdollConstraint::asString();
+	out << NiBoneLODController::asString();
 	return out.str();
 }
 
-void bhkRagdollConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkRagdollConstraint::FixLinks( objects, link_stack, info );
+void NiBSBoneLODController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBoneLODController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkRagdollConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> NiBSBoneLODController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkRagdollConstraint::GetRefs();
+	refs = NiBoneLODController::GetRefs();
 	return refs;
 }
 
-void bhkRigidBody::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiGeometry::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	bhkEntity::Read( in, link_stack, info );
-	for (unsigned int i1 = 0; i1 < 5; i1++) {
-		NifStream( unknown5Floats[i1], in, info );
-	};
-	if ( info.version >= 0x14000004 ) {
-		for (unsigned int i2 = 0; i2 < 4; i2++) {
-			NifStream( unknown4Shorts[i2], in, info );
-		};
-		NifStream( layerCopy, in, info );
-		NifStream( colFilterCopy, in, info );
-		for (unsigned int i2 = 0; i2 < 7; i2++) {
-			NifStream( unknown7Shorts[i2], in, info );
-		};
-	};
-	NifStream( translation, in, info );
-	NifStream( unknownFloat00, in, info );
-	NifStream( rotation.x, in, info );
-	NifStream( rotation.y, in, info );
-	NifStream( rotation.z, in, info );
-	NifStream( rotation.w, in, info );
-	NifStream( linearVelocity, in, info );
-	NifStream( unknownFloat01, in, info );
-	NifStream( angularVelocity, in, info );
-	NifStream( unknownFloat02, in, info );
-	for (unsigned int i1 = 0; i1 < 12; i1++) {
-		NifStream( inertia[i1], in, info );
-	};
-	NifStream( center, in, info );
-	NifStream( unknownFloat03, in, info );
-	NifStream( mass, in, info );
-	NifStream( linearDamping, in, info );
-	NifStream( angularDamping, in, info );
-	NifStream( friction, in, info );
-	NifStream( restitution, in, info );
-	NifStream( maxLinearVelocity, in, info );
-	NifStream( maxAngularVelocity, in, info );
-	NifStream( penetrationDepth, in, info );
-	NifStream( motionSystem, in, info );
-	NifStream( unknownByte1, in, info );
-	NifStream( unknownByte2, in, info );
-	NifStream( qualityType, in, info );
-	NifStream( unknownInt6, in, info );
-	NifStream( unknownInt7, in, info );
-	NifStream( unknownInt8, in, info );
-	NifStream( numConstraints, in, info );
-	constraints.resize(numConstraints);
-	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-	NifStream( unknownInt6, in, info );
-}
-
-void bhkRigidBody::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkEntity::Write( out, link_map, info );
-	numConstraints = (unsigned int)(constraints.size());
-	for (unsigned int i1 = 0; i1 < 5; i1++) {
-		NifStream( unknown5Floats[i1], out, info );
-	};
-	if ( info.version >= 0x14000004 ) {
-		for (unsigned int i2 = 0; i2 < 4; i2++) {
-			NifStream( unknown4Shorts[i2], out, info );
-		};
-		NifStream( layerCopy, out, info );
-		NifStream( colFilterCopy, out, info );
-		for (unsigned int i2 = 0; i2 < 7; i2++) {
-			NifStream( unknown7Shorts[i2], out, info );
-		};
-	};
-	NifStream( translation, out, info );
-	NifStream( unknownFloat00, out, info );
-	NifStream( rotation.x, out, info );
-	NifStream( rotation.y, out, info );
-	NifStream( rotation.z, out, info );
-	NifStream( rotation.w, out, info );
-	NifStream( linearVelocity, out, info );
-	NifStream( unknownFloat01, out, info );
-	NifStream( angularVelocity, out, info );
-	NifStream( unknownFloat02, out, info );
-	for (unsigned int i1 = 0; i1 < 12; i1++) {
-		NifStream( inertia[i1], out, info );
-	};
-	NifStream( center, out, info );
-	NifStream( unknownFloat03, out, info );
-	NifStream( mass, out, info );
-	NifStream( linearDamping, out, info );
-	NifStream( angularDamping, out, info );
-	NifStream( friction, out, info );
-	NifStream( restitution, out, info );
-	NifStream( maxLinearVelocity, out, info );
-	NifStream( maxAngularVelocity, out, info );
-	NifStream( penetrationDepth, out, info );
-	NifStream( motionSystem, out, info );
-	NifStream( unknownByte1, out, info );
-	NifStream( unknownByte2, out, info );
-	NifStream( qualityType, out, info );
-	NifStream( unknownInt6, out, info );
-	NifStream( unknownInt7, out, info );
-	NifStream( unknownInt8, out, info );
-	NifStream( numConstraints, out, info );
-	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
-		if ( constraints[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(constraints[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-	NifStream( unknownInt6, out, info );
-}
-
-std::string bhkRigidBody::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << bhkEntity::asString();
-	numConstraints = (unsigned int)(constraints.size());
-	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 Floats[" << i1 << "]:  " << unknown5Floats[i1] << endl;
-		array_output_count++;
-	};
-	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 << "  Layer Copy:  " << layerCopy << endl;
-	out << "  Col Filter Copy:  " << colFilterCopy << 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 Shorts[" << i1 << "]:  " << unknown7Shorts[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Translation:  " << translation << endl;
-	out << "  Unknown Float 00:  " << unknownFloat00 << endl;
-	out << "  x:  " << rotation.x << endl;
-	out << "  y:  " << rotation.y << endl;
-	out << "  z:  " << rotation.z << endl;
-	out << "  w:  " << rotation.w << endl;
-	out << "  Linear Velocity:  " << linearVelocity << endl;
-	out << "  Unknown Float 01:  " << unknownFloat01 << endl;
-	out << "  Angular Velocity:  " << angularVelocity << endl;
-	out << "  Unknown Float 02:  " << unknownFloat02 << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 12; 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 << "    Inertia[" << i1 << "]:  " << inertia[i1] << endl;
-		array_output_count++;
+	NiAVObject::Read( in, link_stack, info );
+	NifStream( block_num, in, info );
+	link_stack.push_back( block_num );
+	if ( info.version >= 0x0303000D ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
 	};
-	out << "  Center:  " << center << endl;
-	out << "  Unknown Float 03:  " << unknownFloat03 << endl;
-	out << "  Mass:  " << mass << endl;
-	out << "  Linear Damping:  " << linearDamping << endl;
-	out << "  Angular Damping:  " << angularDamping << endl;
-	out << "  Friction:  " << friction << endl;
-	out << "  Restitution:  " << restitution << endl;
-	out << "  Max Linear Velocity:  " << maxLinearVelocity << endl;
-	out << "  Max Angular Velocity:  " << maxAngularVelocity << endl;
-	out << "  Penetration Depth:  " << penetrationDepth << endl;
-	out << "  Motion System:  " << motionSystem << endl;
-	out << "  Unknown Byte 1:  " << unknownByte1 << endl;
-	out << "  Unknown Byte 2:  " << unknownByte2 << endl;
-	out << "  Quality Type:  " << qualityType << endl;
-	out << "  Unknown Int 6:  " << unknownInt6 << endl;
-	out << "  Unknown Int 7:  " << unknownInt7 << endl;
-	out << "  Unknown Int 8:  " << unknownInt8 << endl;
-	out << "  Num Constraints:  " << numConstraints << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( hasShader, in, info );
+		if ( (hasShader != 0) ) {
+			NifStream( shaderName, in, info );
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
 		};
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
+	};
+}
+
+void NiGeometry::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiAVObject::Write( out, link_map, info );
+	if ( data != NULL )
+		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	else
+		NifStream( 0xffffffff, out, info );
+	if ( info.version >= 0x0303000D ) {
+		if ( skinInstance != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(skinInstance) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( hasShader, out, info );
+		if ( (hasShader != 0) ) {
+			NifStream( shaderName, out, info );
+			if ( unknownLink != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
 		};
-		out << "    Constraints[" << i1 << "]:  " << constraints[i1] << endl;
-		array_output_count++;
+	};
+}
+
+std::string NiGeometry::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiAVObject::asString();
+	out << "  Data:  " << data << endl;
+	out << "  Skin Instance:  " << skinInstance << endl;
+	out << "  Has Shader:  " << hasShader << endl;
+	if ( (hasShader != 0) ) {
+		out << "    Shader Name:  " << shaderName << endl;
+		out << "    Unknown Link:  " << unknownLink << endl;
 	};
 	return out.str();
 }
 
-void bhkRigidBody::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkEntity::FixLinks( objects, link_stack, info );
-	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
-		constraints[i1] = FixLink<AbhkConstraint>( objects, link_stack, info );
+void NiGeometry::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiAVObject::FixLinks( objects, link_stack, info );
+	data = FixLink<NiGeometryData>( objects, link_stack, info );
+	if ( info.version >= 0x0303000D ) {
+		skinInstance = FixLink<NiSkinInstance>( objects, link_stack, info );
+	};
+	if ( info.version >= 0x0A000100 ) {
+		if ( (hasShader != 0) ) {
+			unknownLink = FixLink<NiObject>( objects, link_stack, info );
+		};
 	};
 }
 
-std::list<NiObjectRef> bhkRigidBody::InternalGetRefs() const {
+std::list<NiObjectRef> NiGeometry::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkEntity::GetRefs();
-	for (unsigned int i1 = 0; i1 < constraints.size(); i1++) {
-		if ( constraints[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(constraints[i1]));
-	};
+	refs = NiAVObject::GetRefs();
+	if ( data != NULL )
+		refs.push_back(StaticCast<NiObject>(data));
+	if ( skinInstance != NULL )
+		refs.push_back(StaticCast<NiObject>(skinInstance));
+	if ( unknownLink != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink));
 	return refs;
 }
 
-void bhkRigidBodyT::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkRigidBody::Read( in, link_stack, info );
+void NiTriBasedGeom::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiGeometry::Read( in, link_stack, info );
 }
 
-void bhkRigidBodyT::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkRigidBody::Write( out, link_map, info );
+void NiTriBasedGeom::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiGeometry::Write( out, link_map, info );
 }
 
-std::string bhkRigidBodyT::InternalAsString( bool verbose ) const {
+std::string NiTriBasedGeom::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkRigidBody::asString();
+	out << NiGeometry::asString();
 	return out.str();
 }
 
-void bhkRigidBodyT::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkRigidBody::FixLinks( objects, link_stack, info );
+void NiTriBasedGeom::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiGeometry::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkRigidBodyT::InternalGetRefs() const {
+std::list<NiObjectRef> NiTriBasedGeom::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkRigidBody::GetRefs();
+	refs = NiGeometry::GetRefs();
 	return refs;
 }
 
-void bhkSimpleShapePhantom::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkEntity::Read( in, link_stack, info );
-	for (unsigned int i1 = 0; i1 < 7; i1++) {
-		NifStream( unkownFloats[i1], in, info );
+void NiGeometryData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiObject::Read( in, link_stack, info );
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( name, in, info );
 	};
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		for (unsigned int i2 = 0; i2 < 5; i2++) {
-			NifStream( unknownFloats2[i1][i2], in, info );
+	NifStream( numVertices, in, info );
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( unknownShort1, in, info );
+	};
+	NifStream( hasVertices, in, info );
+	if ( (hasVertices != 0) ) {
+		vertices.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < vertices.size(); i2++) {
+			NifStream( vertices[i2], in, info );
+		};
+	};
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( numUvSets2, in, info );
+		NifStream( unknownByte1, in, info );
+	};
+	NifStream( hasNormals, in, info );
+	if ( (hasNormals != 0) ) {
+		normals.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < normals.size(); i2++) {
+			NifStream( normals[i2], in, info );
+		};
+	};
+	if ( info.version >= 0x0A010000 ) {
+		if ( (((hasNormals != 0)) && ((unknownByte1 & 16))) ) {
+			unknownVectors1.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < unknownVectors1.size(); i3++) {
+				NifStream( unknownVectors1[i3], in, info );
+			};
+			unknownVectors2.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < unknownVectors2.size(); i3++) {
+				NifStream( unknownVectors2[i3], in, info );
+			};
+		};
+	};
+	NifStream( center, in, info );
+	NifStream( radius, in, info );
+	NifStream( hasVertexColors, in, info );
+	if ( (hasVertexColors != 0) ) {
+		vertexColors.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < vertexColors.size(); i2++) {
+			NifStream( vertexColors[i2], in, info );
+		};
+	};
+	if ( info.version <= 0x04020200 ) {
+		NifStream( numUvSets, in, info );
+	};
+	if ( info.version <= 0x04000002 ) {
+		NifStream( hasUv, in, info );
+	};
+	if ( info.version <= 0x04020200 ) {
+		uvSets.resize(numUvSets);
+		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
+			uvSets[i2].resize(numVertices);
+			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
+				NifStream( uvSets[i2][i3], in, info );
+			};
+		};
+	};
+	if ( info.version >= 0x0A000100 ) {
+		uvSets.resize((numUvSets2 & 63));
+		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
+			uvSets[i2].resize(numVertices);
+			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
+				NifStream( uvSets[i2][i3], in, info );
+			};
+		};
+		NifStream( unknownShort2, in, info );
+	};
+	if ( info.version >= 0x14000004 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+}
+
+void NiGeometryData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+	numUvSets = (unsigned short)(uvSets.size());
+	numUvSets2 = (byte)(uvSets.size());
+	numVertices = (unsigned short)(vertices.size());
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( name, out, info );
+	};
+	NifStream( numVertices, out, info );
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( unknownShort1, out, info );
+	};
+	NifStream( hasVertices, out, info );
+	if ( (hasVertices != 0) ) {
+		for (unsigned int i2 = 0; i2 < vertices.size(); i2++) {
+			NifStream( vertices[i2], out, info );
+		};
+	};
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( numUvSets2, out, info );
+		NifStream( unknownByte1, out, info );
+	};
+	NifStream( hasNormals, out, info );
+	if ( (hasNormals != 0) ) {
+		for (unsigned int i2 = 0; i2 < normals.size(); i2++) {
+			NifStream( normals[i2], out, info );
+		};
+	};
+	if ( info.version >= 0x0A010000 ) {
+		if ( (((hasNormals != 0)) && ((unknownByte1 & 16))) ) {
+			for (unsigned int i3 = 0; i3 < unknownVectors1.size(); i3++) {
+				NifStream( unknownVectors1[i3], out, info );
+			};
+			for (unsigned int i3 = 0; i3 < unknownVectors2.size(); i3++) {
+				NifStream( unknownVectors2[i3], out, info );
+			};
+		};
+	};
+	NifStream( center, out, info );
+	NifStream( radius, out, info );
+	NifStream( hasVertexColors, out, info );
+	if ( (hasVertexColors != 0) ) {
+		for (unsigned int i2 = 0; i2 < vertexColors.size(); i2++) {
+			NifStream( vertexColors[i2], out, info );
+		};
+	};
+	if ( info.version <= 0x04020200 ) {
+		NifStream( numUvSets, out, info );
+	};
+	if ( info.version <= 0x04000002 ) {
+		NifStream( hasUv, out, info );
+	};
+	if ( info.version <= 0x04020200 ) {
+		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
+				NifStream( uvSets[i2][i3], out, info );
+			};
 		};
 	};
-	NifStream( unknownFloat, in, info );
-}
-
-void bhkSimpleShapePhantom::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkEntity::Write( out, link_map, info );
-	for (unsigned int i1 = 0; i1 < 7; i1++) {
-		NifStream( unkownFloats[i1], out, info );
-	};
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
-		for (unsigned int i2 = 0; i2 < 5; i2++) {
-			NifStream( unknownFloats2[i1][i2], out, info );
+	if ( info.version >= 0x0A000100 ) {
+		for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) {
+				NifStream( uvSets[i2][i3], out, info );
+			};
 		};
+		NifStream( unknownShort2, out, info );
+	};
+	if ( info.version >= 0x14000004 ) {
+		if ( unknownLink1 != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink1) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
 	};
-	NifStream( unknownFloat, out, info );
 }
 
-std::string bhkSimpleShapePhantom::InternalAsString( bool verbose ) const {
+std::string NiGeometryData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkEntity::asString();
-	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;
+	out << NiObject::asString();
+	numUvSets = (unsigned short)(uvSets.size());
+	numUvSets2 = (byte)(uvSets.size());
+	numVertices = (unsigned short)(vertices.size());
+	out << "  Name:  " << name << endl;
+	out << "  Num Vertices:  " << numVertices << endl;
+	out << "  Unknown Short 1:  " << unknownShort1 << endl;
+	out << "  Has Vertices:  " << hasVertices << endl;
+	if ( (hasVertices != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < vertices.size(); 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 << "      Vertices[" << i2 << "]:  " << vertices[i2] << endl;
+			array_output_count++;
 		};
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
+	};
+	out << "  Num UV Sets 2:  " << numUvSets2 << endl;
+	out << "  Unknown Byte 1:  " << unknownByte1 << endl;
+	out << "  Has Normals:  " << hasNormals << endl;
+	if ( (hasNormals != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < normals.size(); 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 << "      Normals[" << i2 << "]:  " << normals[i2] << endl;
+			array_output_count++;
+		};
+	};
+	if ( (((hasNormals != 0)) && ((unknownByte1 & 16))) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < unknownVectors1.size(); 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 Vectors 1[" << i2 << "]:  " << unknownVectors1[i2] << endl;
+			array_output_count++;
+		};
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < unknownVectors2.size(); 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 Vectors 2[" << i2 << "]:  " << unknownVectors2[i2] << endl;
+			array_output_count++;
 		};
-		out << "    Unkown Floats[" << i1 << "]:  " << unkownFloats[i1] << endl;
-		array_output_count++;
 	};
+	out << "  Center:  " << center << endl;
+	out << "  Radius:  " << radius << endl;
+	out << "  Has Vertex Colors:  " << hasVertexColors << endl;
+	if ( (hasVertexColors != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < vertexColors.size(); 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 << "      Vertex Colors[" << i2 << "]:  " << vertexColors[i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Num UV Sets:  " << numUvSets << endl;
+	out << "  Has UV:  " << hasUv << endl;
 	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 3; i1++) {
+	for (unsigned int i1 = 0; i1 < uvSets.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 < 5; i2++) {
+		for (unsigned int i2 = 0; i2 < uvSets[i1].size(); i2++) {
 			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 				break;
 			};
-			out << "      Unknown Floats 2[" << i2 << "]:  " << unknownFloats2[i1][i2] << endl;
+			out << "      UV Sets[" << i2 << "]:  " << uvSets[i1][i2] << endl;
 			array_output_count++;
 		};
 	};
-	out << "  Unknown Float:  " << unknownFloat << endl;
-	return out.str();
-}
-
-void bhkSimpleShapePhantom::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkEntity::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> bhkSimpleShapePhantom::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = bhkEntity::GetRefs();
-	return refs;
-}
-
-void bhkSPCollisionObject::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiCollisionObject::Read( in, link_stack, info );
-}
-
-void bhkSPCollisionObject::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiCollisionObject::Write( out, link_map, info );
-}
-
-std::string bhkSPCollisionObject::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiCollisionObject::asString();
-	return out.str();
-}
-
-void bhkSPCollisionObject::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiCollisionObject::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> bhkSPCollisionObject::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiCollisionObject::GetRefs();
-	return refs;
-}
-
-void bhkSphereShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkConvexShape::Read( in, link_stack, info );
-	NifStream( radius, in, info );
-}
-
-void bhkSphereShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkConvexShape::Write( out, link_map, info );
-	NifStream( radius, out, info );
-}
-
-std::string bhkSphereShape::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << bhkConvexShape::asString();
-	out << "  Radius:  " << radius << endl;
-	return out.str();
-}
-
-void bhkSphereShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkConvexShape::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> bhkSphereShape::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = bhkConvexShape::GetRefs();
-	return refs;
-}
-
-void bhkStiffSpringConstraint::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::Read( in, link_stack, info );
-	NifStream( pivotA, in, info );
-	NifStream( pivotB, in, info );
-	NifStream( length, in, info );
-}
-
-void bhkStiffSpringConstraint::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkConstraint::Write( out, link_map, info );
-	NifStream( pivotA, out, info );
-	NifStream( pivotB, out, info );
-	NifStream( length, out, info );
-}
-
-std::string bhkStiffSpringConstraint::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << AbhkConstraint::asString();
-	out << "  Pivot A:  " << pivotA << endl;
-	out << "  Pivot B:  " << pivotB << endl;
-	out << "  Length:  " << length << endl;
+	out << "  Unknown Short 2:  " << unknownShort2 << endl;
+	out << "  Unknown Link 1:  " << unknownLink1 << endl;
 	return out.str();
 }
 
-void bhkStiffSpringConstraint::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkConstraint::FixLinks( objects, link_stack, info );
+void NiGeometryData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+	if ( info.version >= 0x14000004 ) {
+		unknownLink1 = FixLink<NiObject>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> bhkStiffSpringConstraint::InternalGetRefs() const {
+std::list<NiObjectRef> NiGeometryData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkConstraint::GetRefs();
+	refs = NiObject::GetRefs();
+	if ( unknownLink1 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink1));
 	return refs;
 }
 
-void bhkTransformShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkEntity::Read( in, link_stack, info );
-	NifStream( unknownFloat1, in, info );
-	NifStream( unknownFloat2, in, info );
-	NifStream( unknownFloat3, in, info );
-	NifStream( transform, in, info );
+void NiTriBasedGeomData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiGeometryData::Read( in, link_stack, info );
+	NifStream( numTriangles, in, info );
 }
 
-void bhkTransformShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkEntity::Write( out, link_map, info );
-	NifStream( unknownFloat1, out, info );
-	NifStream( unknownFloat2, out, info );
-	NifStream( unknownFloat3, out, info );
-	NifStream( transform, out, info );
+void NiTriBasedGeomData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiGeometryData::Write( out, link_map, info );
+	NifStream( numTriangles, out, info );
 }
 
-std::string bhkTransformShape::InternalAsString( bool verbose ) const {
+std::string NiTriBasedGeomData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkEntity::asString();
-	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
-	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
-	out << "  Unknown Float 3:  " << unknownFloat3 << endl;
-	out << "  Transform:  " << transform << endl;
+	out << NiGeometryData::asString();
+	out << "  Num Triangles:  " << numTriangles << endl;
 	return out.str();
 }
 
-void bhkTransformShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkEntity::FixLinks( objects, link_stack, info );
+void NiTriBasedGeomData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiGeometryData::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkTransformShape::InternalGetRefs() const {
+std::list<NiObjectRef> NiTriBasedGeomData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkEntity::GetRefs();
+	refs = NiGeometryData::GetRefs();
 	return refs;
 }
 
-void bhkConvexTransformShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkTransformShape::Read( in, link_stack, info );
+void bhkBlendController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiTimeController::Read( in, link_stack, info );
+	NifStream( unknownInt, in, info );
 }
 
-void bhkConvexTransformShape::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	bhkTransformShape::Write( out, link_map, info );
+void bhkBlendController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiTimeController::Write( out, link_map, info );
+	NifStream( unknownInt, out, info );
 }
 
-std::string bhkConvexTransformShape::InternalAsString( bool verbose ) const {
+std::string bhkBlendController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << bhkTransformShape::asString();
+	out << NiTimeController::asString();
+	out << "  Unknown Int:  " << unknownInt << endl;
 	return out.str();
 }
 
-void bhkConvexTransformShape::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	bhkTransformShape::FixLinks( objects, link_stack, info );
+void bhkBlendController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiTimeController::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> bhkConvexTransformShape::InternalGetRefs() const {
+std::list<NiObjectRef> bhkBlendController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = bhkTransformShape::GetRefs();
+	refs = NiTimeController::GetRefs();
 	return refs;
 }
 
@@ -3946,36 +5468,36 @@ std::list<NiObjectRef> BSPSysArrayEmitter::InternalGetRefs() const {
 	return refs;
 }
 
-void BSXFlags::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiExtraData::Read( in, link_stack, info );
-	NifStream( flags, in, info );
+void BSWindModifier::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifier::Read( in, link_stack, info );
+	NifStream( unknownFloat, in, info );
 }
 
-void BSXFlags::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiExtraData::Write( out, link_map, info );
-	NifStream( flags, out, info );
+void BSWindModifier::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysModifier::Write( out, link_map, info );
+	NifStream( unknownFloat, out, info );
 }
 
-std::string BSXFlags::InternalAsString( bool verbose ) const {
+std::string BSWindModifier::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiExtraData::asString();
-	out << "  Flags:  " << flags << endl;
+	out << NiPSysModifier::asString();
+	out << "  Unknown Float:  " << unknownFloat << endl;
 	return out.str();
 }
 
-void BSXFlags::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiExtraData::FixLinks( objects, link_stack, info );
+void BSWindModifier::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysModifier::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> BSXFlags::InternalGetRefs() const {
+std::list<NiObjectRef> BSWindModifier::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiExtraData::GetRefs();
+	refs = NiPSysModifier::GetRefs();
 	return refs;
 }
 
 void hkPackedNiTriStripsData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkShapeCollection::Read( in, link_stack, info );
+	bhkShapeCollection::Read( in, link_stack, info );
 	NifStream( numTriangles, in, info );
 	triangles.resize(numTriangles);
 	for (unsigned int i1 = 0; i1 < triangles.size(); i1++) {
@@ -3991,7 +5513,7 @@ void hkPackedNiTriStripsData::InternalRead( istream& in, list<unsigned int> & li
 }
 
 void hkPackedNiTriStripsData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AbhkShapeCollection::Write( out, link_map, info );
+	bhkShapeCollection::Write( out, link_map, info );
 	numVertices = (unsigned int)(vertices.size());
 	numTriangles = (unsigned int)(triangles.size());
 	NifStream( numTriangles, out, info );
@@ -4009,7 +5531,7 @@ void hkPackedNiTriStripsData::InternalWrite( ostream& out, const map<NiObjectRef
 std::string hkPackedNiTriStripsData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AbhkShapeCollection::asString();
+	out << bhkShapeCollection::asString();
 	numVertices = (unsigned int)(vertices.size());
 	numTriangles = (unsigned int)(triangles.size());
 	out << "  Num Triangles:  " << numTriangles << endl;
@@ -4040,170 +5562,409 @@ std::string hkPackedNiTriStripsData::InternalAsString( bool verbose ) const {
 }
 
 void hkPackedNiTriStripsData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AbhkShapeCollection::FixLinks( objects, link_stack, info );
+	bhkShapeCollection::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> hkPackedNiTriStripsData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AbhkShapeCollection::GetRefs();
+	refs = bhkShapeCollection::GetRefs();
 	return refs;
 }
 
-void NiAlphaController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
+void NiAlphaProperty::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiProperty::Read( in, link_stack, info );
+	NifStream( flags, in, info );
+	NifStream( threshold, in, info );
+}
+
+void NiAlphaProperty::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( threshold, out, info );
+}
+
+std::string NiAlphaProperty::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiProperty::asString();
+	out << "  Flags:  " << flags << endl;
+	out << "  Threshold:  " << threshold << endl;
+	return out.str();
+}
+
+void NiAlphaProperty::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiProperty::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiAlphaProperty::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiProperty::GetRefs();
+	return refs;
+}
+
+void NiAmbientLight::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiLight::Read( in, link_stack, info );
+}
+
+void NiAmbientLight::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiLight::Write( out, link_map, info );
+}
+
+std::string NiAmbientLight::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiLight::asString();
+	return out.str();
+}
+
+void NiAmbientLight::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiLight::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiAmbientLight::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiLight::GetRefs();
+	return refs;
+}
+
+void NiParticlesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiGeometryData::Read( in, link_stack, info );
+	if ( info.version <= 0x04000002 ) {
+		NifStream( numParticles, in, info );
+	};
+	if ( info.version <= 0x0A000100 ) {
+		NifStream( size, in, info );
+	};
+	if ( info.version <= 0x04000002 ) {
+		NifStream( numActive, in, info );
+	};
+	if ( ( info.version >= 0x0401000C ) && ( info.version <= 0x0A000100 ) ) {
+		NifStream( unknownShort, in, info );
+	};
+	NifStream( hasSizes, in, info );
+	if ( (hasSizes != 0) ) {
+		sizes.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < sizes.size(); i2++) {
+			NifStream( sizes[i2], in, info );
+		};
+	};
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( numActive, in, info );
+		NifStream( hasUnknownFloats1, in, info );
+		if ( (hasUnknownFloats1 != 0) ) {
+			unknownFloats1.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < unknownFloats1.size(); i3++) {
+				NifStream( unknownFloats1[i3], in, info );
+			};
+		};
+	};
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( hasRotations1, in, info );
+		if ( (hasRotations1 != 0) ) {
+			rotations1.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < rotations1.size(); i3++) {
+				NifStream( rotations1[i3], in, info );
+			};
+		};
 	};
 }
 
-void NiAlphaController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::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 );
+void NiParticlesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiGeometryData::Write( out, link_map, info );
+	if ( info.version <= 0x04000002 ) {
+		NifStream( numParticles, out, info );
+	};
+	if ( info.version <= 0x0A000100 ) {
+		NifStream( size, out, info );
+	};
+	if ( info.version <= 0x04000002 ) {
+		NifStream( numActive, out, info );
+	};
+	if ( ( info.version >= 0x0401000C ) && ( info.version <= 0x0A000100 ) ) {
+		NifStream( unknownShort, out, info );
+	};
+	NifStream( hasSizes, out, info );
+	if ( (hasSizes != 0) ) {
+		for (unsigned int i2 = 0; i2 < sizes.size(); i2++) {
+			NifStream( sizes[i2], out, info );
+		};
+	};
+	if ( info.version >= 0x0A010000 ) {
+		NifStream( numActive, out, info );
+		NifStream( hasUnknownFloats1, out, info );
+		if ( (hasUnknownFloats1 != 0) ) {
+			for (unsigned int i3 = 0; i3 < unknownFloats1.size(); i3++) {
+				NifStream( unknownFloats1[i3], out, info );
+			};
+		};
+	};
+	if ( info.version >= 0x0A000100 ) {
+		NifStream( hasRotations1, out, info );
+		if ( (hasRotations1 != 0) ) {
+			for (unsigned int i3 = 0; i3 < rotations1.size(); i3++) {
+				NifStream( rotations1[i3], out, info );
+			};
+		};
 	};
 }
 
-std::string NiAlphaController::InternalAsString( bool verbose ) const {
+std::string NiParticlesData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	out << "  Data:  " << data << endl;
+	out << NiGeometryData::asString();
+	out << "  Num Particles:  " << numParticles << endl;
+	out << "  Size:  " << size << endl;
+	out << "  Num Active:  " << numActive << endl;
+	out << "  Unknown Short:  " << unknownShort << endl;
+	out << "  Has Sizes:  " << hasSizes << endl;
+	if ( (hasSizes != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < sizes.size(); 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 << "      Sizes[" << i2 << "]:  " << sizes[i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Has Unknown Floats 1:  " << hasUnknownFloats1 << endl;
+	if ( (hasUnknownFloats1 != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < unknownFloats1.size(); 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 Floats 1[" << i2 << "]:  " << unknownFloats1[i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Has Rotations 1:  " << hasRotations1 << endl;
+	if ( (hasRotations1 != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < rotations1.size(); 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 << "      Rotations 1[" << i2 << "]:  " << rotations1[i2] << endl;
+			array_output_count++;
+		};
+	};
 	return out.str();
 }
 
-void NiAlphaController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		data = FixLink<NiFloatData>( objects, link_stack, info );
-	};
+void NiParticlesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiGeometryData::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiAlphaController::InternalGetRefs() const {
+std::list<NiObjectRef> NiParticlesData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
+	refs = NiGeometryData::GetRefs();
 	return refs;
 }
 
-void NiAlphaProperty::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiProperty::Read( in, link_stack, info );
-	NifStream( flags, in, info );
-	NifStream( threshold, in, info );
+void NiRotatingParticlesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiParticlesData::Read( in, link_stack, info );
+	if ( info.version <= 0x04020200 ) {
+		NifStream( hasRotations2, in, info );
+		if ( (hasRotations2 != 0) ) {
+			rotations2.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < rotations2.size(); i3++) {
+				NifStream( rotations2[i3], in, info );
+			};
+		};
+	};
 }
 
-void NiAlphaProperty::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( threshold, out, info );
+void NiRotatingParticlesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiParticlesData::Write( out, link_map, info );
+	if ( info.version <= 0x04020200 ) {
+		NifStream( hasRotations2, out, info );
+		if ( (hasRotations2 != 0) ) {
+			for (unsigned int i3 = 0; i3 < rotations2.size(); i3++) {
+				NifStream( rotations2[i3], out, info );
+			};
+		};
+	};
 }
 
-std::string NiAlphaProperty::InternalAsString( bool verbose ) const {
+std::string NiRotatingParticlesData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiProperty::asString();
-	out << "  Flags:  " << flags << endl;
-	out << "  Threshold:  " << threshold << endl;
+	out << NiParticlesData::asString();
+	out << "  Has Rotations 2:  " << hasRotations2 << endl;
+	if ( (hasRotations2 != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < rotations2.size(); 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 << "      Rotations 2[" << i2 << "]:  " << rotations2[i2] << endl;
+			array_output_count++;
+		};
+	};
 	return out.str();
 }
 
-void NiAlphaProperty::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiProperty::FixLinks( objects, link_stack, info );
+void NiRotatingParticlesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiParticlesData::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiAlphaProperty::InternalGetRefs() const {
+std::list<NiObjectRef> NiRotatingParticlesData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiProperty::GetRefs();
+	refs = NiParticlesData::GetRefs();
 	return refs;
 }
 
-void NiAmbientLight::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiLight::Read( in, link_stack, info );
+void NiAutoNormalParticlesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiParticlesData::Read( in, link_stack, info );
 }
 
-void NiAmbientLight::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiLight::Write( out, link_map, info );
+void NiAutoNormalParticlesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiParticlesData::Write( out, link_map, info );
 }
 
-std::string NiAmbientLight::InternalAsString( bool verbose ) const {
+std::string NiAutoNormalParticlesData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiLight::asString();
+	out << NiParticlesData::asString();
 	return out.str();
 }
 
-void NiAmbientLight::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiLight::FixLinks( objects, link_stack, info );
+void NiAutoNormalParticlesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiParticlesData::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiAmbientLight::InternalGetRefs() const {
+std::list<NiObjectRef> NiAutoNormalParticlesData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiLight::GetRefs();
+	refs = NiParticlesData::GetRefs();
 	return refs;
 }
 
-void NiAutoNormalParticlesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometryData::Read( in, link_stack, info );
-	if ( info.version <= 0x04000002 ) {
-		NifStream( numParticles, in, info );
-	};
-	if ( info.version <= 0x0A000100 ) {
-		NifStream( size, in, info );
+void NiPSysData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiRotatingParticlesData::Read( in, link_stack, info );
+	if ( info.version <= 0x0A020000 ) {
+		unknownFloats2.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < unknownFloats2.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < 10; i3++) {
+				NifStream( unknownFloats2[i2][i3], in, info );
+			};
+		};
 	};
-	if ( info.version <= 0x04000002 ) {
-		NifStream( numActive, in, info );
+	if ( info.version >= 0x14000004 ) {
+		NifStream( hasUnknownFloats3, in, info );
+		if ( (hasUnknownFloats3 != 0) ) {
+			unknownFloats1.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < unknownFloats1.size(); i3++) {
+				NifStream( unknownFloats1[i3], in, info );
+			};
+		};
+		NifStream( hasUnknownFloats4, in, info );
 	};
-	if ( ( info.version >= 0x0401000C ) && ( info.version <= 0x0A000100 ) ) {
-		NifStream( unknownShort, in, info );
+	if ( (hasUnknownFloats4 != 0) ) {
+		unknownFloats4.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < unknownFloats4.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < 4; i3++) {
+				NifStream( unknownFloats4[i2][i3], in, info );
+			};
+		};
 	};
-	NifStream( hasSizes, in, info );
-	if ( (hasSizes != 0) ) {
-		sizes.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < sizes.size(); i2++) {
-			NifStream( sizes[i2], in, info );
+	if ( info.version >= 0x14000004 ) {
+		unknownFloats5.resize(numVertices);
+		for (unsigned int i2 = 0; i2 < unknownFloats5.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < 7; i3++) {
+				NifStream( unknownFloats5[i2][i3], in, info );
+			};
+		};
+		NifStream( hasUnknownFloats6, in, info );
+		if ( (hasUnknownFloats6 != 0) ) {
+			unknownFloats6.resize(numVertices);
+			for (unsigned int i3 = 0; i3 < unknownFloats6.size(); i3++) {
+				NifStream( unknownFloats6[i3], in, info );
+			};
 		};
 	};
+	NifStream( unknownInt1, in, info );
 }
 
-void NiAutoNormalParticlesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiGeometryData::Write( out, link_map, info );
-	if ( info.version <= 0x04000002 ) {
-		NifStream( numParticles, out, info );
-	};
-	if ( info.version <= 0x0A000100 ) {
-		NifStream( size, out, info );
+void NiPSysData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiRotatingParticlesData::Write( out, link_map, info );
+	if ( info.version <= 0x0A020000 ) {
+		for (unsigned int i2 = 0; i2 < unknownFloats2.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < 10; i3++) {
+				NifStream( unknownFloats2[i2][i3], out, info );
+			};
+		};
 	};
-	if ( info.version <= 0x04000002 ) {
-		NifStream( numActive, out, info );
+	if ( info.version >= 0x14000004 ) {
+		NifStream( hasUnknownFloats3, out, info );
+		if ( (hasUnknownFloats3 != 0) ) {
+			for (unsigned int i3 = 0; i3 < unknownFloats1.size(); i3++) {
+				NifStream( unknownFloats1[i3], out, info );
+			};
+		};
+		NifStream( hasUnknownFloats4, out, info );
 	};
-	if ( ( info.version >= 0x0401000C ) && ( info.version <= 0x0A000100 ) ) {
-		NifStream( unknownShort, out, info );
+	if ( (hasUnknownFloats4 != 0) ) {
+		for (unsigned int i2 = 0; i2 < unknownFloats4.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < 4; i3++) {
+				NifStream( unknownFloats4[i2][i3], out, info );
+			};
+		};
 	};
-	NifStream( hasSizes, out, info );
-	if ( (hasSizes != 0) ) {
-		for (unsigned int i2 = 0; i2 < sizes.size(); i2++) {
-			NifStream( sizes[i2], out, info );
+	if ( info.version >= 0x14000004 ) {
+		for (unsigned int i2 = 0; i2 < unknownFloats5.size(); i2++) {
+			for (unsigned int i3 = 0; i3 < 7; i3++) {
+				NifStream( unknownFloats5[i2][i3], out, info );
+			};
+		};
+		NifStream( hasUnknownFloats6, out, info );
+		if ( (hasUnknownFloats6 != 0) ) {
+			for (unsigned int i3 = 0; i3 < unknownFloats6.size(); i3++) {
+				NifStream( unknownFloats6[i3], out, info );
+			};
 		};
 	};
+	NifStream( unknownInt1, out, info );
 }
 
-std::string NiAutoNormalParticlesData::InternalAsString( bool verbose ) const {
+std::string NiPSysData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiGeometryData::asString();
-	out << "  Num Particles:  " << numParticles << endl;
-	out << "  Size:  " << size << endl;
-	out << "  Num Active:  " << numActive << endl;
-	out << "  Unknown Short:  " << unknownShort << endl;
-	out << "  Has Sizes:  " << hasSizes << endl;
-	if ( (hasSizes != 0) ) {
+	out << NiRotatingParticlesData::asString();
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < unknownFloats2.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 < 10; i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				break;
+			};
+			out << "      Unknown Floats 2[" << i2 << "]:  " << unknownFloats2[i1][i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Has Unknown Floats 3:  " << hasUnknownFloats3 << endl;
+	if ( (hasUnknownFloats3 != 0) ) {
 		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < sizes.size(); i2++) {
+		for (unsigned int i2 = 0; i2 < unknownFloats1.size(); i2++) {
 			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
 				break;
@@ -4211,20 +5972,185 @@ std::string NiAutoNormalParticlesData::InternalAsString( bool verbose ) const {
 			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
 				break;
 			};
-			out << "      Sizes[" << i2 << "]:  " << sizes[i2] << endl;
+			out << "      Unknown Floats 1[" << i2 << "]:  " << unknownFloats1[i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Has Unknown Floats 4:  " << hasUnknownFloats4 << endl;
+	if ( (hasUnknownFloats4 != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < unknownFloats4.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 < 4; i3++) {
+				if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+					break;
+				};
+				out << "        Unknown Floats 4[" << i3 << "]:  " << unknownFloats4[i2][i3] << endl;
+				array_output_count++;
+			};
+		};
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < unknownFloats5.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 < 7; i2++) {
+			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
+				break;
+			};
+			out << "      Unknown Floats 5[" << i2 << "]:  " << unknownFloats5[i1][i2] << endl;
+			array_output_count++;
+		};
+	};
+	out << "  Has Unknown Floats 6:  " << hasUnknownFloats6 << endl;
+	if ( (hasUnknownFloats6 != 0) ) {
+		array_output_count = 0;
+		for (unsigned int i2 = 0; i2 < unknownFloats6.size(); 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 Floats 6[" << i2 << "]:  " << unknownFloats6[i2] << endl;
 			array_output_count++;
 		};
 	};
+	out << "  Unknown Int 1:  " << unknownInt1 << endl;
+	return out.str();
+}
+
+void NiPSysData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiRotatingParticlesData::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiPSysData::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiRotatingParticlesData::GetRefs();
+	return refs;
+}
+
+void NiMeshPSysData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	unsigned int block_num;
+	NiPSysData::Read( in, link_stack, info );
+	if ( info.version <= 0x14000004 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
+		NifStream( unknownByte2, in, info );
+		NifStream( numUnknownLinks, in, info );
+		unknownLinks.resize(numUnknownLinks);
+		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
+			NifStream( block_num, in, info );
+			link_stack.push_back( block_num );
+		};
+	};
+	if ( info.version >= 0x14000005 ) {
+		NifStream( numVertices2, in, info );
+		NifStream( unknownByte3, in, info );
+		NifStream( unknownInt2, in, info );
+		NifStream( numVertices3, in, info );
+	};
+	if ( info.version >= 0x0A020000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
+}
+
+void NiMeshPSysData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiPSysData::Write( out, link_map, info );
+	numUnknownLinks = (unsigned int)(unknownLinks.size());
+	if ( info.version <= 0x14000004 ) {
+		if ( modifier != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(modifier) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
+		NifStream( unknownByte2, out, info );
+		NifStream( numUnknownLinks, out, info );
+		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
+			if ( unknownLinks[i2] != NULL )
+				NifStream( link_map.find( StaticCast<NiObject>(unknownLinks[i2]) )->second, out, info );
+			else
+				NifStream( 0xffffffff, out, info );
+		};
+	};
+	if ( info.version >= 0x14000005 ) {
+		NifStream( numVertices2, out, info );
+		NifStream( unknownByte3, out, info );
+		NifStream( unknownInt2, out, info );
+		NifStream( numVertices3, out, info );
+	};
+	if ( info.version >= 0x0A020000 ) {
+		if ( unknownLink2 != NULL )
+			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
+		else
+			NifStream( 0xffffffff, out, info );
+	};
+}
+
+std::string NiMeshPSysData::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiPSysData::asString();
+	numUnknownLinks = (unsigned int)(unknownLinks.size());
+	out << "  Modifier:  " << modifier << endl;
+	out << "  Unknown Byte 2:  " << unknownByte2 << endl;
+	out << "  Num Unknown Links:  " << numUnknownLinks << endl;
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < unknownLinks.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 Links[" << i1 << "]:  " << unknownLinks[i1] << endl;
+		array_output_count++;
+	};
+	out << "  Num Vertices 2:  " << numVertices2 << endl;
+	out << "  Unknown Byte 3:  " << unknownByte3 << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Num Vertices 3:  " << numVertices3 << endl;
+	out << "  Unknown Link 2:  " << unknownLink2 << endl;
 	return out.str();
 }
 
-void NiAutoNormalParticlesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiGeometryData::FixLinks( objects, link_stack, info );
+void NiMeshPSysData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiPSysData::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x14000004 ) {
+		modifier = FixLink<NiObject>( objects, link_stack, info );
+	};
+	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
+		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
+			unknownLinks[i2] = FixLink<NiObject>( objects, link_stack, info );
+		};
+	};
+	if ( info.version >= 0x0A020000 ) {
+		unknownLink2 = FixLink<NiNode>( objects, link_stack, info );
+	};
 }
 
-std::list<NiObjectRef> NiAutoNormalParticlesData::InternalGetRefs() const {
+std::list<NiObjectRef> NiMeshPSysData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiGeometryData::GetRefs();
+	refs = NiPSysData::GetRefs();
+	if ( modifier != NULL )
+		refs.push_back(StaticCast<NiObject>(modifier));
+	for (unsigned int i1 = 0; i1 < unknownLinks.size(); i1++) {
+		if ( unknownLinks[i1] != NULL )
+			refs.push_back(StaticCast<NiObject>(unknownLinks[i1]));
+	};
+	if ( unknownLink2 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink2));
 	return refs;
 }
 
@@ -4567,131 +6493,8 @@ std::list<NiObjectRef> NiBlendTransformInterpolator::InternalGetRefs() const {
 	return refs;
 }
 
-void NiBoneLODController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	ABoneLODController::Read( in, link_stack, info );
-	NifStream( numShapeGroups, in, info );
-	shapeGroups1.resize(numShapeGroups);
-	for (unsigned int i1 = 0; i1 < shapeGroups1.size(); i1++) {
-		NifStream( shapeGroups1[i1].numLinkPairs, in, info );
-		shapeGroups1[i1].linkPairs.resize(shapeGroups1[i1].numLinkPairs);
-		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
-	NifStream( numShapeGroups2, in, info );
-	shapeGroups2.resize(numShapeGroups2);
-	for (unsigned int i1 = 0; i1 < shapeGroups2.size(); i1++) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiBoneLODController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	ABoneLODController::Write( out, link_map, info );
-	numShapeGroups2 = (unsigned int)(shapeGroups2.size());
-	numShapeGroups = (unsigned int)(shapeGroups1.size());
-	NifStream( numShapeGroups, out, info );
-	for (unsigned int i1 = 0; i1 < shapeGroups1.size(); i1++) {
-		shapeGroups1[i1].numLinkPairs = (unsigned int)(shapeGroups1[i1].linkPairs.size());
-		NifStream( shapeGroups1[i1].numLinkPairs, out, info );
-		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
-			if ( shapeGroups1[i1].linkPairs[i2].shape != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i1].linkPairs[i2].shape) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-			if ( shapeGroups1[i1].linkPairs[i2].skinInstance != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(shapeGroups1[i1].linkPairs[i2].skinInstance) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
-	NifStream( numShapeGroups2, out, info );
-	for (unsigned int i1 = 0; i1 < shapeGroups2.size(); i1++) {
-		if ( shapeGroups2[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(shapeGroups2[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiBoneLODController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << ABoneLODController::asString();
-	numShapeGroups2 = (unsigned int)(shapeGroups2.size());
-	numShapeGroups = (unsigned int)(shapeGroups1.size());
-	out << "  Num Shape Groups:  " << numShapeGroups << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < shapeGroups1.size(); i1++) {
-		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-			break;
-		};
-		shapeGroups1[i1].numLinkPairs = (unsigned int)(shapeGroups1[i1].linkPairs.size());
-		out << "    Num Link Pairs:  " << shapeGroups1[i1].numLinkPairs << endl;
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-				break;
-			};
-			out << "      Shape:  " << shapeGroups1[i1].linkPairs[i2].shape << endl;
-			out << "      Skin Instance:  " << shapeGroups1[i1].linkPairs[i2].skinInstance << endl;
-		};
-	};
-	out << "  Num Shape Groups 2:  " << numShapeGroups2 << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < shapeGroups2.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 << "    Shape Groups 2[" << i1 << "]:  " << shapeGroups2[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void NiBoneLODController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	ABoneLODController::FixLinks( objects, link_stack, info );
-	for (unsigned int i1 = 0; i1 < shapeGroups1.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
-			shapeGroups1[i1].linkPairs[i2].shape = FixLink<NiTriShape>( objects, link_stack, info );
-			shapeGroups1[i1].linkPairs[i2].skinInstance = FixLink<NiSkinInstance>( objects, link_stack, info );
-		};
-	};
-	for (unsigned int i1 = 0; i1 < shapeGroups2.size(); i1++) {
-		shapeGroups2[i1] = FixLink<NiTriShape>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiBoneLODController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = ABoneLODController::GetRefs();
-	for (unsigned int i1 = 0; i1 < shapeGroups1.size(); i1++) {
-		for (unsigned int i2 = 0; i2 < shapeGroups1[i1].linkPairs.size(); i2++) {
-			if ( shapeGroups1[i1].linkPairs[i2].shape != NULL )
-				refs.push_back(StaticCast<NiObject>(shapeGroups1[i1].linkPairs[i2].shape));
-			if ( shapeGroups1[i1].linkPairs[i2].skinInstance != NULL )
-				refs.push_back(StaticCast<NiObject>(shapeGroups1[i1].linkPairs[i2].skinInstance));
-		};
-	};
-	for (unsigned int i1 = 0; i1 < shapeGroups2.size(); i1++) {
-		if ( shapeGroups2[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(shapeGroups2[i1]));
-	};
-	return refs;
-}
-
 void NiBoolData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
 	NifStream( data.numKeys, in, info );
 	if ( (data.numKeys != 0) ) {
 		NifStream( data.interpolation, in, info );
@@ -4703,7 +6506,7 @@ void NiBoolData::InternalRead( istream& in, list<unsigned int> & link_stack, con
 }
 
 void NiBoolData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AKeyedData::Write( out, link_map, info );
+	NiObject::Write( out, link_map, info );
 	data.numKeys = (unsigned int)(data.keys.size());
 	NifStream( data.numKeys, out, info );
 	if ( (data.numKeys != 0) ) {
@@ -4714,168 +6517,65 @@ void NiBoolData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int
 	};
 }
 
-std::string NiBoolData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << AKeyedData::asString();
-	data.numKeys = (unsigned int)(data.keys.size());
-	out << "  Num Keys:  " << data.numKeys << endl;
-	if ( (data.numKeys != 0) ) {
-		out << "    Interpolation:  " << data.interpolation << endl;
-	};
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < data.keys.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 << "    Keys[" << i1 << "]:  " << data.keys[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void NiBoolData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiBoolData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = AKeyedData::GetRefs();
-	return refs;
-}
-
-void NiBooleanExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiExtraData::Read( in, link_stack, info );
-	NifStream( booleanData, in, info );
-}
-
-void NiBooleanExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiExtraData::Write( out, link_map, info );
-	NifStream( booleanData, out, info );
-}
-
-std::string NiBooleanExtraData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiExtraData::asString();
-	out << "  Boolean Data:  " << booleanData << endl;
-	return out.str();
-}
-
-void NiBooleanExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiExtraData::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiBooleanExtraData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiExtraData::GetRefs();
-	return refs;
-}
-
-void NiBoolInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( boolValue, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiBoolInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( boolValue, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiBoolInterpolator::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Bool Value:  " << boolValue << endl;
-	out << "  Data:  " << data << endl;
-	return out.str();
-}
-
-void NiBoolInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
-	data = FixLink<NiBoolData>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiBoolInterpolator::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	return refs;
-}
-
-void NiBoolTimelineInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( boolValue, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiBoolTimelineInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( boolValue, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiBoolTimelineInterpolator::InternalAsString( bool verbose ) const {
+std::string NiBoolData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Bool Value:  " << boolValue << endl;
-	out << "  Data:  " << data << endl;
+	out << NiObject::asString();
+	data.numKeys = (unsigned int)(data.keys.size());
+	out << "  Num Keys:  " << data.numKeys << endl;
+	if ( (data.numKeys != 0) ) {
+		out << "    Interpolation:  " << data.interpolation << endl;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < data.keys.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 << "    Keys[" << i1 << "]:  " << data.keys[i1] << endl;
+		array_output_count++;
+	};
 	return out.str();
 }
 
-void NiBoolTimelineInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
-	data = FixLink<NiBoolData>( objects, link_stack, info );
+void NiBoolData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiBoolTimelineInterpolator::InternalGetRefs() const {
+std::list<NiObjectRef> NiBoolData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
+	refs = NiObject::GetRefs();
 	return refs;
 }
 
-void NiBSBoneLODController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	ABoneLODController::Read( in, link_stack, info );
+void NiBooleanExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiExtraData::Read( in, link_stack, info );
+	NifStream( booleanData, in, info );
 }
 
-void NiBSBoneLODController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	ABoneLODController::Write( out, link_map, info );
+void NiBooleanExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiExtraData::Write( out, link_map, info );
+	NifStream( booleanData, out, info );
 }
 
-std::string NiBSBoneLODController::InternalAsString( bool verbose ) const {
+std::string NiBooleanExtraData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << ABoneLODController::asString();
+	out << NiExtraData::asString();
+	out << "  Boolean Data:  " << booleanData << endl;
 	return out.str();
 }
 
-void NiBSBoneLODController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	ABoneLODController::FixLinks( objects, link_stack, info );
+void NiBooleanExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiExtraData::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiBSBoneLODController::InternalGetRefs() const {
+std::list<NiObjectRef> NiBooleanExtraData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = ABoneLODController::GetRefs();
+	refs = NiExtraData::GetRefs();
 	return refs;
 }
 
@@ -4907,15 +6607,40 @@ std::list<NiObjectRef> NiBSplineBasisData::InternalGetRefs() const {
 	return refs;
 }
 
-void NiBSplineCompFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiBSplineFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiBSplineInterpolator::Read( in, link_stack, info );
+}
+
+void NiBSplineFloatInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBSplineInterpolator::Write( out, link_map, info );
+}
+
+std::string NiBSplineFloatInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiBSplineInterpolator::asString();
+	return out.str();
+}
+
+void NiBSplineFloatInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBSplineInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBSplineFloatInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiBSplineInterpolator::GetRefs();
+	return refs;
+}
+
+void NiBSplineCompFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBSplineFloatInterpolator::Read( in, link_stack, info );
 	for (unsigned int i1 = 0; i1 < 4; i1++) {
 		NifStream( unknownFloats[i1], in, info );
 	};
 }
 
 void NiBSplineCompFloatInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBSplineInterpolator::Write( out, link_map, info );
+	NiBSplineFloatInterpolator::Write( out, link_map, info );
 	for (unsigned int i1 = 0; i1 < 4; i1++) {
 		NifStream( unknownFloats[i1], out, info );
 	};
@@ -4924,7 +6649,7 @@ void NiBSplineCompFloatInterpolator::InternalWrite( ostream& out, const map<NiOb
 std::string NiBSplineCompFloatInterpolator::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiBSplineInterpolator::asString();
+	out << NiBSplineFloatInterpolator::asString();
 	array_output_count = 0;
 	for (unsigned int i1 = 0; i1 < 4; i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
@@ -4941,24 +6666,67 @@ std::string NiBSplineCompFloatInterpolator::InternalAsString( bool verbose ) con
 }
 
 void NiBSplineCompFloatInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBSplineInterpolator::FixLinks( objects, link_stack, info );
+	NiBSplineFloatInterpolator::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiBSplineCompFloatInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiBSplineFloatInterpolator::GetRefs();
+	return refs;
+}
+
+void NiBSplinePoint3Interpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBSplineInterpolator::Read( in, link_stack, info );
+	for (unsigned int i1 = 0; i1 < 6; i1++) {
+		NifStream( unknownFloats[i1], in, info );
+	};
+}
+
+void NiBSplinePoint3Interpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBSplineInterpolator::Write( out, link_map, info );
+	for (unsigned int i1 = 0; i1 < 6; i1++) {
+		NifStream( unknownFloats[i1], out, info );
+	};
+}
+
+std::string NiBSplinePoint3Interpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiBSplineInterpolator::asString();
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < 6; 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 Floats[" << i1 << "]:  " << unknownFloats[i1] << endl;
+		array_output_count++;
+	};
+	return out.str();
+}
+
+void NiBSplinePoint3Interpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBSplineInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBSplinePoint3Interpolator::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = NiBSplineInterpolator::GetRefs();
 	return refs;
 }
 
 void NiBSplineCompPoint3Interpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBSplineInterpolator::Read( in, link_stack, info );
+	NiBSplinePoint3Interpolator::Read( in, link_stack, info );
 	for (unsigned int i1 = 0; i1 < 6; i1++) {
 		NifStream( unknownFloats[i1], in, info );
 	};
 }
 
 void NiBSplineCompPoint3Interpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBSplineInterpolator::Write( out, link_map, info );
+	NiBSplinePoint3Interpolator::Write( out, link_map, info );
 	for (unsigned int i1 = 0; i1 < 6; i1++) {
 		NifStream( unknownFloats[i1], out, info );
 	};
@@ -4967,7 +6735,7 @@ void NiBSplineCompPoint3Interpolator::InternalWrite( ostream& out, const map<NiO
 std::string NiBSplineCompPoint3Interpolator::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiBSplineInterpolator::asString();
+	out << NiBSplinePoint3Interpolator::asString();
 	array_output_count = 0;
 	for (unsigned int i1 = 0; i1 < 6; i1++) {
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
@@ -4984,17 +6752,42 @@ std::string NiBSplineCompPoint3Interpolator::InternalAsString( bool verbose ) co
 }
 
 void NiBSplineCompPoint3Interpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBSplineInterpolator::FixLinks( objects, link_stack, info );
+	NiBSplinePoint3Interpolator::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiBSplineCompPoint3Interpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiBSplinePoint3Interpolator::GetRefs();
+	return refs;
+}
+
+void NiBSplineTransformInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBSplineInterpolator::Read( in, link_stack, info );
+}
+
+void NiBSplineTransformInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiBSplineInterpolator::Write( out, link_map, info );
+}
+
+std::string NiBSplineTransformInterpolator::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiBSplineInterpolator::asString();
+	return out.str();
+}
+
+void NiBSplineTransformInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiBSplineInterpolator::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiBSplineTransformInterpolator::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
 	refs = NiBSplineInterpolator::GetRefs();
 	return refs;
 }
 
 void NiBSplineCompTransformInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBSplineInterpolator::Read( in, link_stack, info );
+	NiBSplineTransformInterpolator::Read( in, link_stack, info );
 	NifStream( translation, in, info );
 	NifStream( rotation, in, info );
 	NifStream( scale, in, info );
@@ -5010,7 +6803,7 @@ void NiBSplineCompTransformInterpolator::InternalRead( istream& in, list<unsigne
 }
 
 void NiBSplineCompTransformInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBSplineInterpolator::Write( out, link_map, info );
+	NiBSplineTransformInterpolator::Write( out, link_map, info );
 	NifStream( translation, out, info );
 	NifStream( rotation, out, info );
 	NifStream( scale, out, info );
@@ -5028,7 +6821,7 @@ void NiBSplineCompTransformInterpolator::InternalWrite( ostream& out, const map<
 std::string NiBSplineCompTransformInterpolator::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiBSplineInterpolator::asString();
+	out << NiBSplineTransformInterpolator::asString();
 	out << "  Translation:  " << translation << endl;
 	out << "  Rotation:  " << rotation << endl;
 	out << "  Scale:  " << scale << endl;
@@ -5045,12 +6838,12 @@ std::string NiBSplineCompTransformInterpolator::InternalAsString( bool verbose )
 }
 
 void NiBSplineCompTransformInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBSplineInterpolator::FixLinks( objects, link_stack, info );
+	NiBSplineTransformInterpolator::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiBSplineCompTransformInterpolator::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiBSplineInterpolator::GetRefs();
+	refs = NiBSplineTransformInterpolator::GetRefs();
 	return refs;
 }
 
@@ -5182,141 +6975,32 @@ std::string NiCamera::InternalAsString( bool verbose ) const {
 	out << "  Frustum Far:  " << frustumFar << endl;
 	out << "  Use Orthographic Projection:  " << useOrthographicProjection << endl;
 	out << "  Viewport Left:  " << viewportLeft << endl;
-	out << "  Viewport Right:  " << viewportRight << endl;
-	out << "  Viewport Top:  " << viewportTop << endl;
-	out << "  Viewport Bottom:  " << viewportBottom << endl;
-	out << "  LOD Adjust:  " << lodAdjust << endl;
-	out << "  Unknown Link?:  " << unknownLink_ << endl;
-	out << "  Unknown Int:  " << unknownInt << endl;
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Unknown Int 3:  " << unknownInt3 << endl;
-	return out.str();
-}
-
-void NiCamera::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiAVObject::FixLinks( objects, link_stack, info );
-	unknownLink_ = FixLink<NiObject>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiCamera::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiAVObject::GetRefs();
-	if ( unknownLink_ != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink_));
-	return refs;
-}
-
-void NiCollisionData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( unknownInt1, in, info );
-	if ( ( info.version >= 0x0A010000 ) && ( info.version <= 0x0A010000 ) ) {
-		NifStream( unknownInt2, in, info );
-	};
-	NifStream( unknownByte, in, info );
-	NifStream( collisionType, in, info );
-	if ( (collisionType == 0) ) {
-		NifStream( unknownInt2, in, info );
-		NifStream( unknownVector, in, info );
-	};
-	if ( (collisionType == 2) ) {
-		for (unsigned int i2 = 0; i2 < 8; i2++) {
-			NifStream( unknownFloat1[i2], in, info );
-		};
-	};
-	if ( (collisionType == 1) ) {
-		for (unsigned int i2 = 0; i2 < 15; i2++) {
-			NifStream( unknownFloat2[i2], in, info );
-		};
-	};
-}
-
-void NiCollisionData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
-	if ( targetNode != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(targetNode) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( unknownInt1, out, info );
-	if ( ( info.version >= 0x0A010000 ) && ( info.version <= 0x0A010000 ) ) {
-		NifStream( unknownInt2, out, info );
-	};
-	NifStream( unknownByte, out, info );
-	NifStream( collisionType, out, info );
-	if ( (collisionType == 0) ) {
-		NifStream( unknownInt2, out, info );
-		NifStream( unknownVector, out, info );
-	};
-	if ( (collisionType == 2) ) {
-		for (unsigned int i2 = 0; i2 < 8; i2++) {
-			NifStream( unknownFloat1[i2], out, info );
-		};
-	};
-	if ( (collisionType == 1) ) {
-		for (unsigned int i2 = 0; i2 < 15; i2++) {
-			NifStream( unknownFloat2[i2], out, info );
-		};
-	};
-}
-
-std::string NiCollisionData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiObject::asString();
-	out << "  Target Node:  " << targetNode << endl;
-	out << "  Unknown Int 1:  " << unknownInt1 << endl;
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Unknown Byte:  " << unknownByte << endl;
-	out << "  Collision Type:  " << collisionType << endl;
-	if ( (collisionType == 0) ) {
-		out << "    Unknown Vector:  " << unknownVector << endl;
-	};
-	if ( (collisionType == 2) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < 8; 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 Float 1[" << i2 << "]:  " << unknownFloat1[i2] << endl;
-			array_output_count++;
-		};
-	};
-	if ( (collisionType == 1) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < 15; 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 Float 2[" << i2 << "]:  " << unknownFloat2[i2] << endl;
-			array_output_count++;
-		};
-	};
+	out << "  Viewport Right:  " << viewportRight << endl;
+	out << "  Viewport Top:  " << viewportTop << endl;
+	out << "  Viewport Bottom:  " << viewportBottom << endl;
+	out << "  LOD Adjust:  " << lodAdjust << endl;
+	out << "  Unknown Link?:  " << unknownLink_ << endl;
+	out << "  Unknown Int:  " << unknownInt << endl;
+	out << "  Unknown Int 2:  " << unknownInt2 << endl;
+	out << "  Unknown Int 3:  " << unknownInt3 << endl;
 	return out.str();
 }
 
-void NiCollisionData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
-	targetNode = FixLink<NiNode>( objects, link_stack, info );
+void NiCamera::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiAVObject::FixLinks( objects, link_stack, info );
+	unknownLink_ = FixLink<NiObject>( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiCollisionData::InternalGetRefs() const {
+std::list<NiObjectRef> NiCamera::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
+	refs = NiAVObject::GetRefs();
+	if ( unknownLink_ != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink_));
 	return refs;
 }
 
 void NiColorData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
 	NifStream( data.numKeys, in, info );
 	if ( (data.numKeys != 0) ) {
 		NifStream( data.interpolation, in, info );
@@ -5328,7 +7012,7 @@ void NiColorData::InternalRead( istream& in, list<unsigned int> & link_stack, co
 }
 
 void NiColorData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AKeyedData::Write( out, link_map, info );
+	NiObject::Write( out, link_map, info );
 	data.numKeys = (unsigned int)(data.keys.size());
 	NifStream( data.numKeys, out, info );
 	if ( (data.numKeys != 0) ) {
@@ -5342,7 +7026,7 @@ void NiColorData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned in
 std::string NiColorData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AKeyedData::asString();
+	out << NiObject::asString();
 	data.numKeys = (unsigned int)(data.keys.size());
 	out << "  Num Keys:  " << data.numKeys << endl;
 	if ( (data.numKeys != 0) ) {
@@ -5364,12 +7048,12 @@ std::string NiColorData::InternalAsString( bool verbose ) const {
 }
 
 void NiColorData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::FixLinks( objects, link_stack, info );
+	NiObject::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiColorData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AKeyedData::GetRefs();
+	refs = NiObject::GetRefs();
 	return refs;
 }
 
@@ -5824,9 +7508,34 @@ std::list<NiObjectRef> NiControllerSequence::InternalGetRefs() const {
 	return refs;
 }
 
+void NiAVObjectPalette::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::Read( in, link_stack, info );
+}
+
+void NiAVObjectPalette::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObject::Write( out, link_map, info );
+}
+
+std::string NiAVObjectPalette::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiObject::asString();
+	return out.str();
+}
+
+void NiAVObjectPalette::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiAVObjectPalette::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObject::GetRefs();
+	return refs;
+}
+
 void NiDefaultAVObjectPalette::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiObject::Read( in, link_stack, info );
+	NiAVObjectPalette::Read( in, link_stack, info );
 	NifStream( unknownInt, in, info );
 	NifStream( numObjs, in, info );
 	objs.resize(numObjs);
@@ -5838,7 +7547,7 @@ void NiDefaultAVObjectPalette::InternalRead( istream& in, list<unsigned int> & l
 }
 
 void NiDefaultAVObjectPalette::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObject::Write( out, link_map, info );
+	NiAVObjectPalette::Write( out, link_map, info );
 	numObjs = (unsigned int)(objs.size());
 	NifStream( unknownInt, out, info );
 	NifStream( numObjs, out, info );
@@ -5854,7 +7563,7 @@ void NiDefaultAVObjectPalette::InternalWrite( ostream& out, const map<NiObjectRe
 std::string NiDefaultAVObjectPalette::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiObject::asString();
+	out << NiAVObjectPalette::asString();
 	numObjs = (unsigned int)(objs.size());
 	out << "  Unknown Int:  " << unknownInt << endl;
 	out << "  Num Objs:  " << numObjs << endl;
@@ -5871,7 +7580,7 @@ std::string NiDefaultAVObjectPalette::InternalAsString( bool verbose ) const {
 }
 
 void NiDefaultAVObjectPalette::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObject::FixLinks( objects, link_stack, info );
+	NiAVObjectPalette::FixLinks( objects, link_stack, info );
 	for (unsigned int i1 = 0; i1 < objs.size(); i1++) {
 		objs[i1].avObject = FixLink<NiAVObject>( objects, link_stack, info );
 	};
@@ -5879,7 +7588,7 @@ void NiDefaultAVObjectPalette::InternalFixLinks( const map<unsigned int,NiObject
 
 std::list<NiObjectRef> NiDefaultAVObjectPalette::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObject::GetRefs();
+	refs = NiAVObjectPalette::GetRefs();
 	for (unsigned int i1 = 0; i1 < objs.size(); i1++) {
 	};
 	return refs;
@@ -5938,135 +7647,15 @@ std::list<NiObjectRef> NiDitherProperty::InternalGetRefs() const {
 	return refs;
 }
 
-void NiFlipController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-	NifStream( textureSlot, in, info );
-	if ( ( info.version >= 0x04000000 ) && ( info.version <= 0x0A010000 ) ) {
-		NifStream( unknownInt2, in, info );
-	};
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( delta, in, info );
-	};
-	NifStream( numSources, in, info );
-	if ( info.version >= 0x04000000 ) {
-		sources.resize(numSources);
-		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
-	if ( info.version <= 0x03010000 ) {
-		image.resize(numSources);
-		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
-}
-
-void NiFlipController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::Write( out, link_map, info );
-	numSources = (unsigned int)(sources.size());
-	NifStream( textureSlot, out, info );
-	if ( ( info.version >= 0x04000000 ) && ( info.version <= 0x0A010000 ) ) {
-		NifStream( unknownInt2, out, info );
-	};
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( delta, out, info );
-	};
-	NifStream( numSources, out, info );
-	if ( info.version >= 0x04000000 ) {
-		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
-			if ( sources[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(sources[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
-	if ( info.version <= 0x03010000 ) {
-		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
-			if ( image[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(image[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
-}
-
-std::string NiFlipController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	numSources = (unsigned int)(sources.size());
-	out << "  Texture Slot:  " << textureSlot << endl;
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Delta:  " << delta << endl;
-	out << "  Num Sources:  " << numSources << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < sources.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 << "    Sources[" << i1 << "]:  " << sources[i1] << endl;
-		array_output_count++;
-	};
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < image.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 << "    Image[" << i1 << "]:  " << image[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void NiFlipController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
-	if ( info.version >= 0x04000000 ) {
-		for (unsigned int i2 = 0; i2 < sources.size(); i2++) {
-			sources[i2] = FixLink<NiSourceTexture>( objects, link_stack, info );
-		};
-	};
-	if ( info.version <= 0x03010000 ) {
-		for (unsigned int i2 = 0; i2 < image.size(); i2++) {
-			image[i2] = FixLink<NiImage>( objects, link_stack, info );
-		};
-	};
-}
-
-std::list<NiObjectRef> NiFlipController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
-	for (unsigned int i1 = 0; i1 < sources.size(); i1++) {
-		if ( sources[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(sources[i1]));
-	};
-	for (unsigned int i1 = 0; i1 < image.size(); i1++) {
-		if ( image[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(image[i1]));
-	};
-	return refs;
-}
-
 void NiRollController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiSingleInterpolatorController::Read( in, link_stack, info );
+	NiSingleInterpController::Read( in, link_stack, info );
 	NifStream( block_num, in, info );
 	link_stack.push_back( block_num );
 }
 
 void NiRollController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::Write( out, link_map, info );
+	NiSingleInterpController::Write( out, link_map, info );
 	if ( data != NULL )
 		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
 	else
@@ -6076,26 +7665,26 @@ void NiRollController::InternalWrite( ostream& out, const map<NiObjectRef,unsign
 std::string NiRollController::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
+	out << NiSingleInterpController::asString();
 	out << "  Data:  " << data << endl;
 	return out.str();
 }
 
 void NiRollController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
 	data = FixLink<NiFloatData>( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiRollController::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
+	refs = NiSingleInterpController::GetRefs();
 	if ( data != NULL )
 		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
 }
 
 void NiFloatData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
 	NifStream( data.numKeys, in, info );
 	if ( (data.numKeys != 0) ) {
 		NifStream( data.interpolation, in, info );
@@ -6107,7 +7696,7 @@ void NiFloatData::InternalRead( istream& in, list<unsigned int> & link_stack, co
 }
 
 void NiFloatData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AKeyedData::Write( out, link_map, info );
+	NiObject::Write( out, link_map, info );
 	data.numKeys = (unsigned int)(data.keys.size());
 	NifStream( data.numKeys, out, info );
 	if ( (data.numKeys != 0) ) {
@@ -6121,7 +7710,7 @@ void NiFloatData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned in
 std::string NiFloatData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AKeyedData::asString();
+	out << NiObject::asString();
 	data.numKeys = (unsigned int)(data.keys.size());
 	out << "  Num Keys:  " << data.numKeys << endl;
 	if ( (data.numKeys != 0) ) {
@@ -6143,124 +7732,40 @@ std::string NiFloatData::InternalAsString( bool verbose ) const {
 }
 
 void NiFloatData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::FixLinks( objects, link_stack, info );
+	NiObject::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiFloatData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AKeyedData::GetRefs();
-	return refs;
-}
-
-void NiFloatExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiExtraData::Read( in, link_stack, info );
-	NifStream( floatData, in, info );
-}
-
-void NiFloatExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiExtraData::Write( out, link_map, info );
-	NifStream( floatData, out, info );
-}
-
-std::string NiFloatExtraData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiExtraData::asString();
-	out << "  Float Data:  " << floatData << endl;
-	return out.str();
-}
-
-void NiFloatExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiExtraData::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiFloatExtraData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiExtraData::GetRefs();
-	return refs;
-}
-
-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 >= 0x0A020000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-		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 >= 0x0A020000 ) {
-		if ( unknownLink != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-		NifStream( controllerData, out, info );
-	};
-}
-
-std::string NiFloatExtraDataController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	out << "  Unknown Link:  " << unknownLink << 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 >= 0x0A020000 ) {
-		unknownLink = FixLink<NiObject>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiFloatExtraDataController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
+	refs = NiObject::GetRefs();
 	return refs;
 }
-
-void NiFloatInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( floatValue, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiFloatInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( floatValue, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
+
+void NiFloatExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiExtraData::Read( in, link_stack, info );
+	NifStream( floatData, in, info );
 }
 
-std::string NiFloatInterpolator::InternalAsString( bool verbose ) const {
+void NiFloatExtraData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiExtraData::Write( out, link_map, info );
+	NifStream( floatData, out, info );
+}
+
+std::string NiFloatExtraData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Float Value:  " << floatValue << endl;
-	out << "  Data:  " << data << endl;
+	out << NiExtraData::asString();
+	out << "  Float Data:  " << floatData << endl;
 	return out.str();
 }
 
-void NiFloatInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
-	data = FixLink<NiFloatData>( objects, link_stack, info );
+void NiFloatExtraData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiExtraData::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiFloatInterpolator::InternalGetRefs() const {
+std::list<NiObjectRef> NiFloatExtraData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
+	refs = NiExtraData::GetRefs();
 	return refs;
 }
 
@@ -6347,128 +7852,6 @@ std::list<NiObjectRef> NiFogProperty::InternalGetRefs() const {
 	return refs;
 }
 
-void NiGeomMorpherController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( unknown, in, info );
-	};
-	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
-		NifStream( unknown2, in, info );
-	};
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( unknownByte, in, info );
-	if ( info.version >= 0x0A01006A ) {
-		NifStream( numInterpolators, in, info );
-		interpolators.resize(numInterpolators);
-		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( numUnknownInts, in, info );
-		unknownInts.resize(numUnknownInts);
-		for (unsigned int i2 = 0; i2 < unknownInts.size(); i2++) {
-			NifStream( unknownInts[i2], in, info );
-		};
-	};
-}
-
-void NiGeomMorpherController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	numUnknownInts = (unsigned int)(unknownInts.size());
-	numInterpolators = (unsigned int)(interpolators.size());
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( unknown, out, info );
-	};
-	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
-		NifStream( unknown2, out, info );
-	};
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	NifStream( unknownByte, out, info );
-	if ( info.version >= 0x0A01006A ) {
-		NifStream( numInterpolators, out, info );
-		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
-			if ( interpolators[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(interpolators[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( numUnknownInts, out, info );
-		for (unsigned int i2 = 0; i2 < unknownInts.size(); i2++) {
-			NifStream( unknownInts[i2], out, info );
-		};
-	};
-}
-
-std::string NiGeomMorpherController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	numUnknownInts = (unsigned int)(unknownInts.size());
-	numInterpolators = (unsigned int)(interpolators.size());
-	out << "  Unknown:  " << unknown << endl;
-	out << "  Unknown 2:  " << unknown2 << endl;
-	out << "  Data:  " << data << endl;
-	out << "  Unknown Byte:  " << unknownByte << endl;
-	out << "  Num Interpolators:  " << numInterpolators << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < interpolators.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 << "    Interpolators[" << i1 << "]:  " << interpolators[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Num Unknown Ints:  " << numUnknownInts << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownInts.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 Ints[" << i1 << "]:  " << unknownInts[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void NiGeomMorpherController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiTimeController::FixLinks( objects, link_stack, info );
-	data = FixLink<NiMorphData>( objects, link_stack, info );
-	if ( info.version >= 0x0A01006A ) {
-		for (unsigned int i2 = 0; i2 < interpolators.size(); i2++) {
-			interpolators[i2] = FixLink<NiInterpolator>( objects, link_stack, info );
-		};
-	};
-}
-
-std::list<NiObjectRef> NiGeomMorpherController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	for (unsigned int i1 = 0; i1 < interpolators.size(); i1++) {
-		if ( interpolators[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(interpolators[i1]));
-	};
-	return refs;
-}
-
 void NiGravity::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	AParticleModifier::Read( in, link_stack, info );
 	if ( info.version >= 0x04000002 ) {
@@ -6541,6 +7924,31 @@ std::list<NiObjectRef> NiIntegerExtraData::InternalGetRefs() const {
 	return refs;
 }
 
+void BSXFlags::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiIntegerExtraData::Read( in, link_stack, info );
+}
+
+void BSXFlags::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiIntegerExtraData::Write( out, link_map, info );
+}
+
+std::string BSXFlags::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiIntegerExtraData::asString();
+	return out.str();
+}
+
+void BSXFlags::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiIntegerExtraData::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> BSXFlags::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiIntegerExtraData::GetRefs();
+	return refs;
+}
+
 void NiIntegersExtraData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiExtraData::Read( in, link_stack, info );
 	NifStream( numIntegers, in, info );
@@ -6663,7 +8071,7 @@ std::list<NiObjectRef> BSKeyframeController::InternalGetRefs() const {
 }
 
 void NiKeyframeData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
 	NifStream( numRotationKeys, in, info );
 	if ( (numRotationKeys != 0) ) {
 		NifStream( rotationType, in, info );
@@ -6710,7 +8118,7 @@ void NiKeyframeData::InternalRead( istream& in, list<unsigned int> & link_stack,
 }
 
 void NiKeyframeData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AKeyedData::Write( out, link_map, info );
+	NiObject::Write( out, link_map, info );
 	NifStream( numRotationKeys, out, info );
 	if ( (numRotationKeys != 0) ) {
 		NifStream( rotationType, out, info );
@@ -6758,7 +8166,7 @@ void NiKeyframeData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned
 std::string NiKeyframeData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AKeyedData::asString();
+	out << NiObject::asString();
 	out << "  Num Rotation Keys:  " << numRotationKeys << endl;
 	if ( (numRotationKeys != 0) ) {
 		out << "    Rotation Type:  " << rotationType << endl;
@@ -6816,141 +8224,38 @@ std::string NiKeyframeData::InternalAsString( bool verbose ) const {
 			break;
 		};
 		if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-			break;
-		};
-		out << "    Keys[" << i1 << "]:  " << translations.keys[i1] << endl;
-		array_output_count++;
-	};
-	scales.numKeys = (unsigned int)(scales.keys.size());
-	out << "  Num Keys:  " << scales.numKeys << endl;
-	if ( (scales.numKeys != 0) ) {
-		out << "    Interpolation:  " << scales.interpolation << endl;
-	};
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < scales.keys.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 << "    Keys[" << i1 << "]:  " << scales.keys[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void NiKeyframeData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiKeyframeData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = AKeyedData::GetRefs();
-	return refs;
-}
-
-void NiLightColorController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	if ( ( info.version >= 0x0A010000 ) && ( info.version <= 0x0A010000 ) ) {
-		NifStream( unknownShort, in, info );
-	};
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-		NifStream( unknownShort, in, info );
-	};
-}
-
-void NiLightColorController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	if ( ( info.version >= 0x0A010000 ) && ( info.version <= 0x0A010000 ) ) {
-		NifStream( unknownShort, out, info );
-	};
-	if ( info.version <= 0x0A010000 ) {
-		if ( data != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-	if ( info.version >= 0x0A020000 ) {
-		if ( interpolator != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(interpolator) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-		NifStream( unknownShort, out, info );
-	};
-}
-
-std::string NiLightColorController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	out << "  Unknown Short:  " << unknownShort << endl;
-	out << "  Data:  " << data << endl;
-	out << "  Interpolator:  " << interpolator << endl;
-	return out.str();
-}
-
-void NiLightColorController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiTimeController::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		data = FixLink<NiPosData>( objects, link_stack, info );
+			break;
+		};
+		out << "    Keys[" << i1 << "]:  " << translations.keys[i1] << endl;
+		array_output_count++;
 	};
-	if ( info.version >= 0x0A020000 ) {
-		interpolator = FixLink<NiPoint3Interpolator>( objects, link_stack, info );
+	scales.numKeys = (unsigned int)(scales.keys.size());
+	out << "  Num Keys:  " << scales.numKeys << endl;
+	if ( (scales.numKeys != 0) ) {
+		out << "    Interpolation:  " << scales.interpolation << endl;
+	};
+	array_output_count = 0;
+	for (unsigned int i1 = 0; i1 < scales.keys.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 << "    Keys[" << i1 << "]:  " << scales.keys[i1] << endl;
+		array_output_count++;
 	};
-}
-
-std::list<NiObjectRef> NiLightColorController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	if ( interpolator != NULL )
-		refs.push_back(StaticCast<NiObject>(interpolator));
-	return refs;
-}
-
-void NiLightDimmerController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiLightDimmerController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	if ( unknownLink != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiLightDimmerController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	out << "  Unknown Link:  " << unknownLink << endl;
 	return out.str();
 }
 
-void NiLightDimmerController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiTimeController::FixLinks( objects, link_stack, info );
-	unknownLink = FixLink<NiInterpolator>( objects, link_stack, info );
+void NiKeyframeData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObject::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiLightDimmerController::InternalGetRefs() const {
+std::list<NiObjectRef> NiKeyframeData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
+	refs = NiObject::GetRefs();
 	return refs;
 }
 
@@ -7059,310 +8364,72 @@ std::string NiLookAtInterpolator::InternalAsString( bool verbose ) const {
 void NiLookAtInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiInterpolator::FixLinks( objects, link_stack, info );
 	lookAt = FixLink<NiNode>( objects, link_stack, info );
-	unknownLink1 = FixLink<NiPoint3Interpolator>( objects, link_stack, info );
-	unknownLink2 = FixLink<NiFloatInterpolator>( objects, link_stack, info );
-	unknownLink3 = FixLink<NiFloatInterpolator>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiLookAtInterpolator::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( lookAt != NULL )
-		refs.push_back(StaticCast<NiObject>(lookAt));
-	if ( unknownLink1 != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink1));
-	if ( unknownLink2 != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink2));
-	if ( unknownLink3 != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink3));
-	return refs;
-}
-
-void NiMaterialColorController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( targetColor, in, info );
-	};
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiMaterialColorController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::Write( out, link_map, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( targetColor, out, 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 NiMaterialColorController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	out << "  Target Color:  " << targetColor << endl;
-	out << "  Data:  " << data << endl;
-	return out.str();
-}
-
-void NiMaterialColorController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		data = FixLink<NiPosData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiMaterialColorController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	return refs;
-}
-
-void NiMaterialProperty::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiProperty::Read( in, link_stack, info );
-	if ( info.version <= 0x0A000102 ) {
-		NifStream( flags, in, info );
-	};
-	NifStream( ambientColor, in, info );
-	NifStream( diffuseColor, in, info );
-	NifStream( specularColor, in, info );
-	NifStream( emissiveColor, in, info );
-	NifStream( glossiness, in, info );
-	NifStream( alpha, in, info );
-}
-
-void NiMaterialProperty::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiProperty::Write( out, link_map, info );
-	if ( info.version <= 0x0A000102 ) {
-		NifStream( flags, out, info );
-	};
-	NifStream( ambientColor, out, info );
-	NifStream( diffuseColor, out, info );
-	NifStream( specularColor, out, info );
-	NifStream( emissiveColor, out, info );
-	NifStream( glossiness, out, info );
-	NifStream( alpha, out, info );
-}
-
-std::string NiMaterialProperty::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiProperty::asString();
-	out << "  Flags:  " << flags << endl;
-	out << "  Ambient Color:  " << ambientColor << endl;
-	out << "  Diffuse Color:  " << diffuseColor << endl;
-	out << "  Specular Color:  " << specularColor << endl;
-	out << "  Emissive Color:  " << emissiveColor << endl;
-	out << "  Glossiness:  " << glossiness << endl;
-	out << "  Alpha:  " << alpha << endl;
-	return out.str();
-}
-
-void NiMaterialProperty::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiProperty::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiMaterialProperty::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiProperty::GetRefs();
-	return refs;
-}
-
-void NiMeshPSysData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	APSysData::Read( in, link_stack, info );
-	if ( info.version >= 0x14000005 ) {
-		NifStream( unknownByte11, in, info );
-	};
-	if ( info.version <= 0x14000004 ) {
-		unknownFloats4.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < unknownFloats4.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 10; i3++) {
-				NifStream( unknownFloats4[i2][i3], in, info );
-			};
-		};
-	};
-	if ( info.version >= 0x14000005 ) {
-		unknownFloats5.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < unknownFloats5.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 12; i3++) {
-				NifStream( unknownFloats5[i2][i3], in, info );
-			};
-		};
-	};
-	NifStream( unknownInt1, in, info );
-	if ( info.version <= 0x14000004 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
-		NifStream( unknownByte2, in, info );
-		NifStream( numUnknownLinks, in, info );
-		unknownLinks.resize(numUnknownLinks);
-		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
-			NifStream( block_num, in, info );
-			link_stack.push_back( block_num );
-		};
-	};
-	if ( info.version >= 0x14000005 ) {
-		NifStream( unknownShort4, in, info );
-		NifStream( unknownInt2, in, info );
-		NifStream( unknownByte12, in, info );
-		NifStream( unknownInt3, in, info );
-		NifStream( unknownInt4, in, info );
-	};
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiMeshPSysData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	APSysData::Write( out, link_map, info );
-	numUnknownLinks = (unsigned int)(unknownLinks.size());
-	if ( info.version >= 0x14000005 ) {
-		NifStream( unknownByte11, out, info );
-	};
-	if ( info.version <= 0x14000004 ) {
-		for (unsigned int i2 = 0; i2 < unknownFloats4.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 10; i3++) {
-				NifStream( unknownFloats4[i2][i3], out, info );
-			};
-		};
-	};
-	if ( info.version >= 0x14000005 ) {
-		for (unsigned int i2 = 0; i2 < unknownFloats5.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 12; i3++) {
-				NifStream( unknownFloats5[i2][i3], out, info );
-			};
-		};
-	};
-	NifStream( unknownInt1, out, info );
-	if ( info.version <= 0x14000004 ) {
-		if ( modifier != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(modifier) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
-		NifStream( unknownByte2, out, info );
-		NifStream( numUnknownLinks, out, info );
-		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
-			if ( unknownLinks[i2] != NULL )
-				NifStream( link_map.find( StaticCast<NiObject>(unknownLinks[i2]) )->second, out, info );
-			else
-				NifStream( 0xffffffff, out, info );
-		};
-	};
-	if ( info.version >= 0x14000005 ) {
-		NifStream( unknownShort4, out, info );
-		NifStream( unknownInt2, out, info );
-		NifStream( unknownByte12, out, info );
-		NifStream( unknownInt3, out, info );
-		NifStream( unknownInt4, out, info );
+	unknownLink1 = FixLink<NiPoint3Interpolator>( objects, link_stack, info );
+	unknownLink2 = FixLink<NiFloatInterpolator>( objects, link_stack, info );
+	unknownLink3 = FixLink<NiFloatInterpolator>( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiLookAtInterpolator::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiInterpolator::GetRefs();
+	if ( lookAt != NULL )
+		refs.push_back(StaticCast<NiObject>(lookAt));
+	if ( unknownLink1 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink1));
+	if ( unknownLink2 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink2));
+	if ( unknownLink3 != NULL )
+		refs.push_back(StaticCast<NiObject>(unknownLink3));
+	return refs;
+}
+
+void NiMaterialProperty::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiProperty::Read( in, link_stack, info );
+	if ( info.version <= 0x0A000102 ) {
+		NifStream( flags, in, info );
 	};
-	if ( info.version >= 0x0A020000 ) {
-		if ( unknownLink2 != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
+	NifStream( ambientColor, in, info );
+	NifStream( diffuseColor, in, info );
+	NifStream( specularColor, in, info );
+	NifStream( emissiveColor, in, info );
+	NifStream( glossiness, in, info );
+	NifStream( alpha, in, info );
+}
+
+void NiMaterialProperty::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiProperty::Write( out, link_map, info );
+	if ( info.version <= 0x0A000102 ) {
+		NifStream( flags, out, info );
 	};
+	NifStream( ambientColor, out, info );
+	NifStream( diffuseColor, out, info );
+	NifStream( specularColor, out, info );
+	NifStream( emissiveColor, out, info );
+	NifStream( glossiness, out, info );
+	NifStream( alpha, out, info );
 }
 
-std::string NiMeshPSysData::InternalAsString( bool verbose ) const {
+std::string NiMaterialProperty::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << APSysData::asString();
-	numUnknownLinks = (unsigned int)(unknownLinks.size());
-	out << "  Unknown Byte 11:  " << unknownByte11 << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownFloats4.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 < 10; i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				break;
-			};
-			out << "      Unknown Floats 4[" << i2 << "]:  " << unknownFloats4[i1][i2] << endl;
-			array_output_count++;
-		};
-	};
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownFloats5.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 < 12; i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				break;
-			};
-			out << "      Unknown Floats 5[" << i2 << "]:  " << unknownFloats5[i1][i2] << endl;
-			array_output_count++;
-		};
-	};
-	out << "  Unknown Int 1:  " << unknownInt1 << endl;
-	out << "  Modifier:  " << modifier << endl;
-	out << "  Unknown Byte 2:  " << unknownByte2 << endl;
-	out << "  Num Unknown Links:  " << numUnknownLinks << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownLinks.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 Links[" << i1 << "]:  " << unknownLinks[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Unknown Short 4:  " << unknownShort4 << endl;
-	out << "  Unknown Int 2:  " << unknownInt2 << endl;
-	out << "  Unknown Byte 12:  " << unknownByte12 << endl;
-	out << "  Unknown Int 3:  " << unknownInt3 << endl;
-	out << "  Unknown Int 4:  " << unknownInt4 << endl;
-	out << "  Unknown Link 2:  " << unknownLink2 << endl;
+	out << NiProperty::asString();
+	out << "  Flags:  " << flags << endl;
+	out << "  Ambient Color:  " << ambientColor << endl;
+	out << "  Diffuse Color:  " << diffuseColor << endl;
+	out << "  Specular Color:  " << specularColor << endl;
+	out << "  Emissive Color:  " << emissiveColor << endl;
+	out << "  Glossiness:  " << glossiness << endl;
+	out << "  Alpha:  " << alpha << endl;
 	return out.str();
 }
 
-void NiMeshPSysData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysData::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x14000004 ) {
-		modifier = FixLink<NiObject>( objects, link_stack, info );
-	};
-	if ( ( info.version >= 0x0A020000 ) && ( info.version <= 0x14000004 ) ) {
-		for (unsigned int i2 = 0; i2 < unknownLinks.size(); i2++) {
-			unknownLinks[i2] = FixLink<NiObject>( objects, link_stack, info );
-		};
-	};
-	if ( info.version >= 0x0A020000 ) {
-		unknownLink2 = FixLink<NiNode>( objects, link_stack, info );
-	};
+void NiMaterialProperty::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiProperty::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiMeshPSysData::InternalGetRefs() const {
+std::list<NiObjectRef> NiMaterialProperty::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = APSysData::GetRefs();
-	if ( modifier != NULL )
-		refs.push_back(StaticCast<NiObject>(modifier));
-	for (unsigned int i1 = 0; i1 < unknownLinks.size(); i1++) {
-		if ( unknownLinks[i1] != NULL )
-			refs.push_back(StaticCast<NiObject>(unknownLinks[i1]));
-	};
-	if ( unknownLink2 != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink2));
+	refs = NiProperty::GetRefs();
 	return refs;
 }
 
@@ -7478,65 +8545,6 @@ std::list<NiObjectRef> NiMorphData::InternalGetRefs() const {
 	return refs;
 }
 
-void NiMultiTargetTransformController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	NifStream( numExtraTargets, in, info );
-	extraTargets.resize(numExtraTargets);
-	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiMultiTargetTransformController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiTimeController::Write( out, link_map, info );
-	numExtraTargets = (unsigned short)(extraTargets.size());
-	NifStream( numExtraTargets, out, info );
-	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
-		if ( extraTargets[i1] != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(extraTargets[i1]) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiMultiTargetTransformController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
-	numExtraTargets = (unsigned short)(extraTargets.size());
-	out << "  Num Extra Targets:  " << numExtraTargets << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < extraTargets.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 << "    Extra Targets[" << i1 << "]:  " << extraTargets[i1] << endl;
-		array_output_count++;
-	};
-	return out.str();
-}
-
-void NiMultiTargetTransformController::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 < extraTargets.size(); i1++) {
-		extraTargets[i1] = FixLink<NiNode>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiMultiTargetTransformController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
-	for (unsigned int i1 = 0; i1 < extraTargets.size(); i1++) {
-	};
-	return refs;
-}
-
 void NiNode::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	NiAVObject::Read( in, link_stack, info );
@@ -7904,9 +8912,34 @@ std::list<NiObjectRef> NiBSParticleNode::InternalGetRefs() const {
 	return refs;
 }
 
+void NiSwitchNode::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiNode::Read( in, link_stack, info );
+}
+
+void NiSwitchNode::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiNode::Write( out, link_map, info );
+}
+
+std::string NiSwitchNode::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiNode::asString();
+	return out.str();
+}
+
+void NiSwitchNode::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiNode::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiSwitchNode::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiNode::GetRefs();
+	return refs;
+}
+
 void NiLODNode::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiNode::Read( in, link_stack, info );
+	NiSwitchNode::Read( in, link_stack, info );
 	for (unsigned int i1 = 0; i1 < 4; i1++) {
 		NifStream( unknown4Bytes[i1], in, info );
 	};
@@ -7934,7 +8967,7 @@ void NiLODNode::InternalRead( istream& in, list<unsigned int> & link_stack, cons
 }
 
 void NiLODNode::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiNode::Write( out, link_map, info );
+	NiSwitchNode::Write( out, link_map, info );
 	numLodLevels = (unsigned int)(lodLevels.size());
 	for (unsigned int i1 = 0; i1 < 4; i1++) {
 		NifStream( unknown4Bytes[i1], out, info );
@@ -7966,7 +8999,7 @@ void NiLODNode::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int>
 std::string NiLODNode::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiNode::asString();
+	out << NiSwitchNode::asString();
 	numLodLevels = (unsigned int)(lodLevels.size());
 	array_output_count = 0;
 	for (unsigned int i1 = 0; i1 < 4; i1++) {
@@ -8009,7 +9042,7 @@ std::string NiLODNode::InternalAsString( bool verbose ) const {
 }
 
 void NiLODNode::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiNode::FixLinks( objects, link_stack, info );
+	NiSwitchNode::FixLinks( objects, link_stack, info );
 	if ( info.version >= 0x0A010000 ) {
 		lodLevelData = FixLink<NiLODData>( objects, link_stack, info );
 	};
@@ -8017,7 +9050,7 @@ void NiLODNode::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects,
 
 std::list<NiObjectRef> NiLODNode::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiNode::GetRefs();
+	refs = NiSwitchNode::GetRefs();
 	if ( lodLevelData != NULL )
 		refs.push_back(StaticCast<NiObject>(lodLevelData));
 	return refs;
@@ -8356,129 +9389,41 @@ std::list<NiObjectRef> NiAutoNormalParticles::InternalGetRefs() const {
 	refs = NiParticles::GetRefs();
 	return refs;
 }
-
-void NiParticleMeshes::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiParticles::Read( in, link_stack, info );
-}
-
-void NiParticleMeshes::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiParticles::Write( out, link_map, info );
-}
-
-std::string NiParticleMeshes::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiParticles::asString();
-	return out.str();
-}
-
-void NiParticleMeshes::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiParticles::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiParticleMeshes::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiParticles::GetRefs();
-	return refs;
-}
-
-void NiParticlesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiAutoNormalParticlesData::Read( in, link_stack, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( numActive, in, info );
-		NifStream( hasUnknownFloats, in, info );
-		if ( (hasUnknownFloats != 0) ) {
-			unknownFloats.resize(numVertices);
-			for (unsigned int i3 = 0; i3 < unknownFloats.size(); i3++) {
-				NifStream( unknownFloats[i3], in, info );
-			};
-		};
-	};
-	NifStream( hasRotations, in, info );
-	if ( (hasRotations != 0) ) {
-		rotations.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < rotations.size(); i2++) {
-			NifStream( rotations[i2], in, info );
-		};
-	};
-}
-
-void NiParticlesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiAutoNormalParticlesData::Write( out, link_map, info );
-	if ( info.version >= 0x0A010000 ) {
-		NifStream( numActive, out, info );
-		NifStream( hasUnknownFloats, out, info );
-		if ( (hasUnknownFloats != 0) ) {
-			for (unsigned int i3 = 0; i3 < unknownFloats.size(); i3++) {
-				NifStream( unknownFloats[i3], out, info );
-			};
-		};
-	};
-	NifStream( hasRotations, out, info );
-	if ( (hasRotations != 0) ) {
-		for (unsigned int i2 = 0; i2 < rotations.size(); i2++) {
-			NifStream( rotations[i2], out, info );
-		};
-	};
+
+void NiParticleMeshes::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiParticles::Read( in, link_stack, info );
 }
 
-std::string NiParticlesData::InternalAsString( bool verbose ) const {
+void NiParticleMeshes::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiParticles::Write( out, link_map, info );
+}
+
+std::string NiParticleMeshes::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiAutoNormalParticlesData::asString();
-	out << "  Num Active:  " << numActive << endl;
-	out << "  Has Unknown Floats:  " << hasUnknownFloats << endl;
-	if ( (hasUnknownFloats != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownFloats.size(); 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 Floats[" << i2 << "]:  " << unknownFloats[i2] << endl;
-			array_output_count++;
-		};
-	};
-	out << "  Has Rotations:  " << hasRotations << endl;
-	if ( (hasRotations != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < rotations.size(); 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 << "      Rotations[" << i2 << "]:  " << rotations[i2] << endl;
-			array_output_count++;
-		};
-	};
+	out << NiParticles::asString();
 	return out.str();
 }
 
-void NiParticlesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiAutoNormalParticlesData::FixLinks( objects, link_stack, info );
+void NiParticleMeshes::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiParticles::FixLinks( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiParticlesData::InternalGetRefs() const {
+std::list<NiObjectRef> NiParticleMeshes::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiAutoNormalParticlesData::GetRefs();
+	refs = NiParticles::GetRefs();
 	return refs;
 }
 
 void NiParticleMeshesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiParticlesData::Read( in, link_stack, info );
+	NiRotatingParticlesData::Read( in, link_stack, info );
 	NifStream( block_num, in, info );
 	link_stack.push_back( block_num );
 }
 
 void NiParticleMeshesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiParticlesData::Write( out, link_map, info );
+	NiRotatingParticlesData::Write( out, link_map, info );
 	if ( unknownLink2 != NULL )
 		NifStream( link_map.find( StaticCast<NiObject>(unknownLink2) )->second, out, info );
 	else
@@ -8488,19 +9433,19 @@ void NiParticleMeshesData::InternalWrite( ostream& out, const map<NiObjectRef,un
 std::string NiParticleMeshesData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiParticlesData::asString();
+	out << NiRotatingParticlesData::asString();
 	out << "  Unknown Link 2:  " << unknownLink2 << endl;
 	return out.str();
 }
 
 void NiParticleMeshesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiParticlesData::FixLinks( objects, link_stack, info );
+	NiRotatingParticlesData::FixLinks( objects, link_stack, info );
 	unknownLink2 = FixLink<NiAVObject>( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiParticleMeshesData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiParticlesData::GetRefs();
+	refs = NiRotatingParticlesData::GetRefs();
 	if ( unknownLink2 != NULL )
 		refs.push_back(StaticCast<NiObject>(unknownLink2));
 	return refs;
@@ -8961,61 +9906,6 @@ std::list<NiObjectRef> NiPathController::InternalGetRefs() const {
 	return refs;
 }
 
-void NiPathInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiBlendInterpolator::Read( in, link_stack, info );
-	NifStream( unknownFloat1, in, info );
-	NifStream( unknownFloat2, in, info );
-	NifStream( unknownShort2, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiPathInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiBlendInterpolator::Write( out, link_map, info );
-	NifStream( unknownFloat1, out, info );
-	NifStream( unknownFloat2, out, info );
-	NifStream( unknownShort2, out, info );
-	if ( posData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(posData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-	if ( floatData != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(floatData) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiPathInterpolator::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiBlendInterpolator::asString();
-	out << "  Unknown Float 1:  " << unknownFloat1 << endl;
-	out << "  Unknown Float 2:  " << unknownFloat2 << endl;
-	out << "  Unknown Short 2:  " << unknownShort2 << endl;
-	out << "  Pos Data:  " << posData << endl;
-	out << "  Float Data:  " << floatData << endl;
-	return out.str();
-}
-
-void NiPathInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiBlendInterpolator::FixLinks( objects, link_stack, info );
-	posData = FixLink<NiPosData>( objects, link_stack, info );
-	floatData = FixLink<NiFloatData>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiPathInterpolator::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiBlendInterpolator::GetRefs();
-	if ( posData != NULL )
-		refs.push_back(StaticCast<NiObject>(posData));
-	if ( floatData != NULL )
-		refs.push_back(StaticCast<NiObject>(floatData));
-	return refs;
-}
-
 void NiPixelData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	NiObject::Read( in, link_stack, info );
@@ -9268,45 +10158,6 @@ std::list<NiObjectRef> NiPlanarCollider::InternalGetRefs() const {
 	return refs;
 }
 
-void NiPoint3Interpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( point3Value, in, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiPoint3Interpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( point3Value, out, info );
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiPoint3Interpolator::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Point 3 Value:  " << point3Value << endl;
-	out << "  Data:  " << data << endl;
-	return out.str();
-}
-
-void NiPoint3Interpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
-	data = FixLink<NiPosData>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiPoint3Interpolator::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	return refs;
-}
-
 void NiPointLight::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiLight::Read( in, link_stack, info );
 	NifStream( constantAttenuation, in, info );
@@ -9342,7 +10193,7 @@ std::list<NiObjectRef> NiPointLight::InternalGetRefs() const {
 }
 
 void NiPosData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
 	NifStream( data.numKeys, in, info );
 	if ( (data.numKeys != 0) ) {
 		NifStream( data.interpolation, in, info );
@@ -9354,7 +10205,7 @@ void NiPosData::InternalRead( istream& in, list<unsigned int> & link_stack, cons
 }
 
 void NiPosData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AKeyedData::Write( out, link_map, info );
+	NiObject::Write( out, link_map, info );
 	data.numKeys = (unsigned int)(data.keys.size());
 	NifStream( data.numKeys, out, info );
 	if ( (data.numKeys != 0) ) {
@@ -9368,7 +10219,7 @@ void NiPosData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int>
 std::string NiPosData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AKeyedData::asString();
+	out << NiObject::asString();
 	data.numKeys = (unsigned int)(data.keys.size());
 	out << "  Num Keys:  " << data.numKeys << endl;
 	if ( (data.numKeys != 0) ) {
@@ -9390,12 +10241,12 @@ std::string NiPosData::InternalAsString( bool verbose ) const {
 }
 
 void NiPosData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::FixLinks( objects, link_stack, info );
+	NiObject::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiPosData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AKeyedData::GetRefs();
+	refs = NiObject::GetRefs();
 	return refs;
 }
 
@@ -9687,170 +10538,7 @@ void NiPSysCylinderEmitter::InternalFixLinks( const map<unsigned int,NiObjectRef
 
 std::list<NiObjectRef> NiPSysCylinderEmitter::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiPSysVolumeEmitter::GetRefs();
-	return refs;
-}
-
-void NiPSysData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysData::Read( in, link_stack, info );
-	if ( info.version <= 0x0A020000 ) {
-		unknownFloats4.resize(numVertices);
-		for (unsigned int i2 = 0; i2 < unknownFloats4.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 10; i3++) {
-				NifStream( unknownFloats4[i2][i3], in, info );
-			};
-		};
-	};
-	if ( info.version >= 0x14000004 ) {
-		NifStream( unknownBool1, in, info );
-		if ( (unknownBool1 != 0) ) {
-			unknownBytes.resize(numVertices);
-			for (unsigned int i3 = 0; i3 < unknownBytes.size(); i3++) {
-				for (unsigned int i4 = 0; i4 < 32; i4++) {
-					NifStream( unknownBytes[i3][i4], in, info );
-				};
-			};
-		};
-		if ( (unknownBool1 == 0) ) {
-			unknownBytesAlt.resize(numVertices);
-			for (unsigned int i3 = 0; i3 < unknownBytesAlt.size(); i3++) {
-				for (unsigned int i4 = 0; i4 < 28; i4++) {
-					NifStream( unknownBytesAlt[i3][i4], in, info );
-				};
-			};
-		};
-		NifStream( unknownByte3, in, info );
-		NifStream( unknownBool2, in, info );
-		if ( (unknownBool2 != 0) ) {
-			unknownBytes2.resize(numVertices);
-			for (unsigned int i3 = 0; i3 < unknownBytes2.size(); i3++) {
-				for (unsigned int i4 = 0; i4 < 4; i4++) {
-					NifStream( unknownBytes2[i3][i4], in, info );
-				};
-			};
-		};
-	};
-	NifStream( unknownInt1, in, info );
-}
-
-void NiPSysData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	APSysData::Write( out, link_map, info );
-	if ( info.version <= 0x0A020000 ) {
-		for (unsigned int i2 = 0; i2 < unknownFloats4.size(); i2++) {
-			for (unsigned int i3 = 0; i3 < 10; i3++) {
-				NifStream( unknownFloats4[i2][i3], out, info );
-			};
-		};
-	};
-	if ( info.version >= 0x14000004 ) {
-		NifStream( unknownBool1, out, info );
-		if ( (unknownBool1 != 0) ) {
-			for (unsigned int i3 = 0; i3 < unknownBytes.size(); i3++) {
-				for (unsigned int i4 = 0; i4 < 32; i4++) {
-					NifStream( unknownBytes[i3][i4], out, info );
-				};
-			};
-		};
-		if ( (unknownBool1 == 0) ) {
-			for (unsigned int i3 = 0; i3 < unknownBytesAlt.size(); i3++) {
-				for (unsigned int i4 = 0; i4 < 28; i4++) {
-					NifStream( unknownBytesAlt[i3][i4], out, info );
-				};
-			};
-		};
-		NifStream( unknownByte3, out, info );
-		NifStream( unknownBool2, out, info );
-		if ( (unknownBool2 != 0) ) {
-			for (unsigned int i3 = 0; i3 < unknownBytes2.size(); i3++) {
-				for (unsigned int i4 = 0; i4 < 4; i4++) {
-					NifStream( unknownBytes2[i3][i4], out, info );
-				};
-			};
-		};
-	};
-	NifStream( unknownInt1, out, info );
-}
-
-std::string NiPSysData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysData::asString();
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < unknownFloats4.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 < 10; i2++) {
-			if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-				break;
-			};
-			out << "      Unknown Floats 4[" << i2 << "]:  " << unknownFloats4[i1][i2] << endl;
-			array_output_count++;
-		};
-	};
-	out << "  Unknown Bool 1:  " << unknownBool1 << endl;
-	if ( (unknownBool1 != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownBytes.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 < 32; i3++) {
-				if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-					break;
-				};
-				out << "        Unknown Bytes[" << i3 << "]:  " << unknownBytes[i2][i3] << endl;
-				array_output_count++;
-			};
-		};
-	};
-	if ( (unknownBool1 == 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownBytesAlt.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 < 28; i3++) {
-				if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-					break;
-				};
-				out << "        Unknown Bytes Alt[" << i3 << "]:  " << unknownBytesAlt[i2][i3] << endl;
-				array_output_count++;
-			};
-		};
-	};
-	out << "  Unknown Byte 3:  " << unknownByte3 << endl;
-	out << "  Unknown Bool 2:  " << unknownBool2 << endl;
-	if ( (unknownBool2 != 0) ) {
-		array_output_count = 0;
-		for (unsigned int i2 = 0; i2 < unknownBytes2.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 < 4; i3++) {
-				if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) {
-					break;
-				};
-				out << "        Unknown Bytes 2[" << i3 << "]:  " << unknownBytes2[i2][i3] << endl;
-				array_output_count++;
-			};
-		};
-	};
-	out << "  Unknown Int 1:  " << unknownInt1 << endl;
-	return out.str();
-}
-
-void NiPSysData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysData::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiPSysData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = APSysData::GetRefs();
+	refs = NiPSysVolumeEmitter::GetRefs();
 	return refs;
 }
 
@@ -9900,64 +10588,6 @@ std::list<NiObjectRef> NiPSysDragModifier::InternalGetRefs() const {
 	return refs;
 }
 
-void NiPSysEmitterCtlr::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 );
-	};
-	if ( info.version >= 0x0A020000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiPSysEmitterCtlr::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 );
-	};
-	if ( info.version >= 0x0A020000 ) {
-		if ( visibilityInterpolator != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(visibilityInterpolator) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiPSysEmitterCtlr::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysCtlr::asString();
-	out << "  Data:  " << data << endl;
-	out << "  Visibility Interpolator:  " << visibilityInterpolator << endl;
-	return out.str();
-}
-
-void NiPSysEmitterCtlr::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<NiPSysEmitterCtlrData>( objects, link_stack, info );
-	};
-	if ( info.version >= 0x0A020000 ) {
-		visibilityInterpolator = FixLink<NiInterpolator>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiPSysEmitterCtlr::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = APSysCtlr::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	if ( visibilityInterpolator != NULL )
-		refs.push_back(StaticCast<NiObject>(visibilityInterpolator));
-	return refs;
-}
-
 void NiPSysEmitterCtlrData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiObject::Read( in, link_stack, info );
 	NifStream( floatKeys_.numKeys, in, info );
@@ -10040,199 +10670,6 @@ std::list<NiObjectRef> NiPSysEmitterCtlrData::InternalGetRefs() const {
 	return refs;
 }
 
-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;
-}
-
-void NiPSysEmitterDeclinationVarCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysCtlr::Read( in, link_stack, info );
-}
-
-void NiPSysEmitterDeclinationVarCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	APSysCtlr::Write( out, link_map, info );
-}
-
-std::string NiPSysEmitterDeclinationVarCtlr::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysCtlr::asString();
-	return out.str();
-}
-
-void NiPSysEmitterDeclinationVarCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysCtlr::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiPSysEmitterDeclinationVarCtlr::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = APSysCtlr::GetRefs();
-	return refs;
-}
-
-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;
-}
-
-void NiPSysEmitterLifeSpanCtlr::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 NiPSysEmitterLifeSpanCtlr::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 ( unknownLink != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiPSysEmitterLifeSpanCtlr::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysCtlr::asString();
-	out << "  Unknown Link:  " << unknownLink << endl;
-	return out.str();
-}
-
-void NiPSysEmitterLifeSpanCtlr::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 ) {
-		unknownLink = FixLink<NiFloatData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiPSysEmitterLifeSpanCtlr::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = APSysCtlr::GetRefs();
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
-	return refs;
-}
-
-void NiPSysEmitterSpeedCtlr::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 NiPSysEmitterSpeedCtlr::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 ( unknownLink != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiPSysEmitterSpeedCtlr::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysCtlr::asString();
-	out << "  Unknown Link:  " << unknownLink << endl;
-	return out.str();
-}
-
-void NiPSysEmitterSpeedCtlr::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 ) {
-		unknownLink = FixLink<NiFloatData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiPSysEmitterSpeedCtlr::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = APSysCtlr::GetRefs();
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
-	return refs;
-}
-
 void NiPSysGravityModifier::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
 	NiPSysModifier::Read( in, link_stack, info );
@@ -10279,51 +10716,9 @@ void NiPSysGravityModifier::InternalFixLinks( const map<unsigned int,NiObjectRef
 	gravityObject = FixLink<NiNode>( objects, link_stack, info );
 }
 
-std::list<NiObjectRef> NiPSysGravityModifier::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiPSysModifier::GetRefs();
-	return refs;
-}
-
-void NiPSysGravityStrengthCtlr::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 NiPSysGravityStrengthCtlr::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 ( unknownLink != NULL )
-			NifStream( link_map.find( StaticCast<NiObject>(unknownLink) )->second, out, info );
-		else
-			NifStream( 0xffffffff, out, info );
-	};
-}
-
-std::string NiPSysGravityStrengthCtlr::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysCtlr::asString();
-	out << "  Unknown Link:  " << unknownLink << endl;
-	return out.str();
-}
-
-void NiPSysGravityStrengthCtlr::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 ) {
-		unknownLink = FixLink<NiFloatData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiPSysGravityStrengthCtlr::InternalGetRefs() const {
+std::list<NiObjectRef> NiPSysGravityModifier::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = APSysCtlr::GetRefs();
-	if ( unknownLink != NULL )
-		refs.push_back(StaticCast<NiObject>(unknownLink));
+	refs = NiPSysModifier::GetRefs();
 	return refs;
 }
 
@@ -10495,38 +10890,6 @@ std::list<NiObjectRef> NiPSysMeshUpdateModifier::InternalGetRefs() const {
 	return refs;
 }
 
-void NiPSysModifierActiveCtlr::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysCtlr::Read( in, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( unknownInt, in, info );
-	};
-}
-
-void NiPSysModifierActiveCtlr::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	APSysCtlr::Write( out, link_map, info );
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( unknownInt, out, info );
-	};
-}
-
-std::string NiPSysModifierActiveCtlr::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << APSysCtlr::asString();
-	out << "  Unknown Int:  " << unknownInt << endl;
-	return out.str();
-}
-
-void NiPSysModifierActiveCtlr::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	APSysCtlr::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiPSysModifierActiveCtlr::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = APSysCtlr::GetRefs();
-	return refs;
-}
-
 void NiPSysPlanarCollider::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiPSysCollider::Read( in, link_stack, info );
 	NifStream( width, in, info );
@@ -10978,31 +11341,6 @@ std::list<NiObjectRef> NiRotatingParticles::InternalGetRefs() const {
 	return refs;
 }
 
-void NiRotatingParticlesData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiParticlesData::Read( in, link_stack, info );
-}
-
-void NiRotatingParticlesData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiParticlesData::Write( out, link_map, info );
-}
-
-std::string NiRotatingParticlesData::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiParticlesData::asString();
-	return out.str();
-}
-
-void NiRotatingParticlesData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiParticlesData::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiRotatingParticlesData::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiParticlesData::GetRefs();
-	return refs;
-}
-
 void NiSequenceStreamHelper::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiObjectNET::Read( in, link_stack, info );
 }
@@ -11742,9 +12080,34 @@ std::list<NiObjectRef> NiSkinPartition::InternalGetRefs() const {
 	return refs;
 }
 
+void NiTexture::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObjectNET::Read( in, link_stack, info );
+}
+
+void NiTexture::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	NiObjectNET::Write( out, link_map, info );
+}
+
+std::string NiTexture::InternalAsString( bool verbose ) const {
+	stringstream out;
+	unsigned int array_output_count = 0;
+	out << NiObjectNET::asString();
+	return out.str();
+}
+
+void NiTexture::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	NiObjectNET::FixLinks( objects, link_stack, info );
+}
+
+std::list<NiObjectRef> NiTexture::InternalGetRefs() const {
+	list<Ref<NiObject> > refs;
+	refs = NiObjectNET::GetRefs();
+	return refs;
+}
+
 void NiSourceTexture::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	unsigned int block_num;
-	NiObjectNET::Read( in, link_stack, info );
+	NiTexture::Read( in, link_stack, info );
 	NifStream( useExternal, in, info );
 	if ( (useExternal == 1) ) {
 		NifStream( fileName, in, info );
@@ -11779,7 +12142,7 @@ void NiSourceTexture::InternalRead( istream& in, list<unsigned int> & link_stack
 }
 
 void NiSourceTexture::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiObjectNET::Write( out, link_map, info );
+	NiTexture::Write( out, link_map, info );
 	NifStream( useExternal, out, info );
 	if ( (useExternal == 1) ) {
 		NifStream( fileName, out, info );
@@ -11820,7 +12183,7 @@ void NiSourceTexture::InternalWrite( ostream& out, const map<NiObjectRef,unsigne
 std::string NiSourceTexture::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiObjectNET::asString();
+	out << NiTexture::asString();
 	out << "  Use External:  " << useExternal << endl;
 	if ( (useExternal == 1) ) {
 		out << "    File Name:  " << fileName << endl;
@@ -11839,7 +12202,7 @@ std::string NiSourceTexture::InternalAsString( bool verbose ) const {
 }
 
 void NiSourceTexture::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiObjectNET::FixLinks( objects, link_stack, info );
+	NiTexture::FixLinks( objects, link_stack, info );
 	if ( info.version >= 0x0A010000 ) {
 		if ( (useExternal == 1) ) {
 			unknownLink = FixLink<NiObject>( objects, link_stack, info );
@@ -11852,7 +12215,7 @@ void NiSourceTexture::InternalFixLinks( const map<unsigned int,NiObjectRef> & ob
 
 std::list<NiObjectRef> NiSourceTexture::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiObjectNET::GetRefs();
+	refs = NiTexture::GetRefs();
 	if ( unknownLink != NULL )
 		refs.push_back(StaticCast<NiObject>(unknownLink));
 	if ( pixelData != NULL )
@@ -12280,57 +12643,6 @@ std::list<NiObjectRef> NiTextureEffect::InternalGetRefs() const {
 	return refs;
 }
 
-void NiTextureTransformController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-	NifStream( unknown2, in, info );
-	NifStream( textureSlot, in, info );
-	NifStream( operation, in, info );
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiTextureTransformController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::Write( out, link_map, info );
-	NifStream( unknown2, out, info );
-	NifStream( textureSlot, out, info );
-	NifStream( operation, out, 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 NiTextureTransformController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	out << "  Unknown2:  " << unknown2 << endl;
-	out << "  Texture Slot:  " << textureSlot << endl;
-	out << "  Operation:  " << operation << endl;
-	out << "  Data:  " << data << endl;
-	return out.str();
-}
-
-void NiTextureTransformController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		data = FixLink<NiFloatData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiTextureTransformController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	return refs;
-}
-
 void NiTextureModeProperty::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiProperty::Read( in, link_stack, info );
 	NifStream( unknownShort, in, info );
@@ -13503,31 +13815,6 @@ std::list<NiObjectRef> NiTexturingProperty::InternalGetRefs() const {
 	return refs;
 }
 
-void NiTransformController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-}
-
-void NiTransformController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::Write( out, link_map, info );
-}
-
-std::string NiTransformController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	return out.str();
-}
-
-void NiTransformController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiTransformController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
-	return refs;
-}
-
 void NiTransformData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiKeyframeData::Read( in, link_stack, info );
 }
@@ -13553,73 +13840,6 @@ std::list<NiObjectRef> NiTransformData::InternalGetRefs() const {
 	return refs;
 }
 
-void NiTransformInterpolator::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiInterpolator::Read( in, link_stack, info );
-	NifStream( translation, in, info );
-	NifStream( rotation, in, info );
-	NifStream( scale, in, info );
-	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
-		for (unsigned int i2 = 0; i2 < 3; i2++) {
-			NifStream( unknownBytes[i2], in, info );
-		};
-	};
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
-}
-
-void NiTransformInterpolator::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiInterpolator::Write( out, link_map, info );
-	NifStream( translation, out, info );
-	NifStream( rotation, out, info );
-	NifStream( scale, out, info );
-	if ( ( info.version >= 0x0A01006A ) && ( info.version <= 0x0A01006A ) ) {
-		for (unsigned int i2 = 0; i2 < 3; i2++) {
-			NifStream( unknownBytes[i2], out, info );
-		};
-	};
-	if ( data != NULL )
-		NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
-	else
-		NifStream( 0xffffffff, out, info );
-}
-
-std::string NiTransformInterpolator::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiInterpolator::asString();
-	out << "  Translation:  " << translation << endl;
-	out << "  Rotation:  " << rotation << endl;
-	out << "  Scale:  " << scale << endl;
-	array_output_count = 0;
-	for (unsigned int i1 = 0; i1 < 3; 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[" << i1 << "]:  " << unknownBytes[i1] << endl;
-		array_output_count++;
-	};
-	out << "  Data:  " << data << endl;
-	return out.str();
-}
-
-void NiTransformInterpolator::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiInterpolator::FixLinks( objects, link_stack, info );
-	data = FixLink<NiTransformData>( objects, link_stack, info );
-}
-
-std::list<NiObjectRef> NiTransformInterpolator::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiInterpolator::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	return refs;
-}
-
 void NiTriShape::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	NiTriBasedGeom::Read( in, link_stack, info );
 }
@@ -14266,50 +14486,8 @@ std::list<NiObjectRef> NiVertWeightsExtraData::InternalGetRefs() const {
 	return refs;
 }
 
-void NiVisController::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	unsigned int block_num;
-	NiSingleInterpolatorController::Read( in, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		NifStream( block_num, in, info );
-		link_stack.push_back( block_num );
-	};
-}
-
-void NiVisController::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	NiSingleInterpolatorController::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 NiVisController::InternalAsString( bool verbose ) const {
-	stringstream out;
-	unsigned int array_output_count = 0;
-	out << NiSingleInterpolatorController::asString();
-	out << "  Data:  " << data << endl;
-	return out.str();
-}
-
-void NiVisController::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	NiSingleInterpolatorController::FixLinks( objects, link_stack, info );
-	if ( info.version <= 0x0A010000 ) {
-		data = FixLink<NiVisData>( objects, link_stack, info );
-	};
-}
-
-std::list<NiObjectRef> NiVisController::InternalGetRefs() const {
-	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpolatorController::GetRefs();
-	if ( data != NULL )
-		refs.push_back(StaticCast<NiObject>(data));
-	return refs;
-}
-
 void NiVisData::InternalRead( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::Read( in, link_stack, info );
+	NiObject::Read( in, link_stack, info );
 	NifStream( numVisKeys, in, info );
 	visKeys.resize(numVisKeys);
 	for (unsigned int i1 = 0; i1 < visKeys.size(); i1++) {
@@ -14318,7 +14496,7 @@ void NiVisData::InternalRead( istream& in, list<unsigned int> & link_stack, cons
 }
 
 void NiVisData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	AKeyedData::Write( out, link_map, info );
+	NiObject::Write( out, link_map, info );
 	numVisKeys = (unsigned int)(visKeys.size());
 	NifStream( numVisKeys, out, info );
 	for (unsigned int i1 = 0; i1 < visKeys.size(); i1++) {
@@ -14329,7 +14507,7 @@ void NiVisData::InternalWrite( ostream& out, const map<NiObjectRef,unsigned int>
 std::string NiVisData::InternalAsString( bool verbose ) const {
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << AKeyedData::asString();
+	out << NiObject::asString();
 	numVisKeys = (unsigned int)(visKeys.size());
 	out << "  Num Vis Keys:  " << numVisKeys << endl;
 	array_output_count = 0;
@@ -14348,12 +14526,12 @@ std::string NiVisData::InternalAsString( bool verbose ) const {
 }
 
 void NiVisData::InternalFixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	AKeyedData::FixLinks( objects, link_stack, info );
+	NiObject::FixLinks( objects, link_stack, info );
 }
 
 std::list<NiObjectRef> NiVisData::InternalGetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = AKeyedData::GetRefs();
+	refs = NiObject::GetRefs();
 	return refs;
 }
 
diff --git a/src/niflib.cpp b/src/niflib.cpp
index bc17c2aa..5a434a0b 100644
--- a/src/niflib.cpp
+++ b/src/niflib.cpp
@@ -20,7 +20,7 @@ All rights reserved.  Please see niflib.h for license. */
 #include "../include/obj/NiStringPalette.h"
 #include "../include/obj/NiSkinPartition.h"
 #include "../include/obj/NiTimeController.h"
-#include "../include/obj/NiSingleInterpolatorController.h"
+#include "../include/obj/NiSingleInterpController.h"
 #include "../include/obj/NiInterpolator.h"
 #include "../include/obj/NiKeyframeController.h"
 #include "../include/obj/NiKeyframeData.h"
@@ -923,10 +923,10 @@ void MergeNifTrees( NiNode * target, NiControllerSequence * right, unsigned vers
 				//connected to the named node
 				NiNodeRef node = name_map[node_name];
 				list<NiTimeControllerRef> ctlrs = node->GetControllers();
-				NiSingleInterpolatorControllerRef ctlr;
+				NiSingleInterpControllerRef ctlr;
 				for ( list<NiTimeControllerRef>::iterator it = ctlrs.begin(); it != ctlrs.end(); ++it ) {
 					if ( *it != NULL && (*it)->GetType().GetTypeName() == ctlr_type ) {
-						ctlr = DynamicCast<NiSingleInterpolatorController>(*it);
+						ctlr = DynamicCast<NiSingleInterpController>(*it);
 						if ( ctlr != NULL ) {
 							break;
 						}
@@ -936,9 +936,9 @@ void MergeNifTrees( NiNode * target, NiControllerSequence * right, unsigned vers
 				//If the controller wasn't found, create one of the right type and attach it
 				if ( ctlr == NULL ) {
 					NiObjectRef new_ctlr = CreateObject( ctlr_type );
-					ctlr = DynamicCast<NiSingleInterpolatorController>( new_ctlr );
+					ctlr = DynamicCast<NiSingleInterpController>( new_ctlr );
 					if ( ctlr == NULL ) {
-						throw runtime_error ("Non-NiSingleInterpolatorController controller found in KF file.");
+						throw runtime_error ("Non-NiSingleInterpController controller found in KF file.");
 					}
 					node->AddController( StaticCast<NiTimeController>(ctlr) );
 				}
diff --git a/src/obj/ABoneLODController.cpp b/src/obj/ABoneLODController.cpp
deleted file mode 100644
index 6f71fe89..00000000
--- a/src/obj/ABoneLODController.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Copyright (c) 2006, NIF File Format Library and Tools
-All rights reserved.  Please see niflib.h for license. */
-
-#include "../../include/obj/ABoneLODController.h"
-#include "../../include/gen/NodeGroup.h"
-#include "../../include/obj/NiNode.h"
-#include <algorithm>
-using namespace Niflib;
-
-//Definition of TYPE constant
-const Type ABoneLODController::TYPE("ABoneLODController", &A_BONE_L_O_D_CONTROLLER_PARENT::TYPE );
-
-ABoneLODController::ABoneLODController() A_BONE_L_O_D_CONTROLLER_CONSTRUCT {}
-
-ABoneLODController::~ABoneLODController() {}
-
-void ABoneLODController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	InternalRead( in, link_stack, info );
-}
-
-void ABoneLODController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	InternalWrite( out, link_map, info );
-}
-
-string ABoneLODController::asString( bool verbose ) const {
-	return InternalAsString( verbose );
-}
-
-void ABoneLODController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	InternalFixLinks( objects, link_stack, info );
-}
-
-list<NiObjectRef> ABoneLODController::GetRefs() const {
-	return InternalGetRefs();
-}
-
-const Type & ABoneLODController::GetType() const {
-	return TYPE;
-};
-
-/*!
- * A list of node groups (each group a sequence of bones?).
- */
-int ABoneLODController::GetNodeGroupCount() const {
-   return int(nodeGroups.size());
-}
-
-vector<Ref<NiNode> > ABoneLODController::GetNodeGroup( int index ) const {
-   if (index < 0 || index >= int(nodeGroups.size()) ) {
-      throw runtime_error("Invalid index referenced.");
-   }
-   vector<NiNodeRef> value;
-   const vector<NiNode*>& nodes = nodeGroups[index].nodes;
-   for (vector<NiNode*>::const_iterator itr = nodes.begin(); itr != nodes.end(); ++itr)
-      value.push_back(*itr);
-   return value;
-}
-
-void ABoneLODController::AddNodeToGroup( int index, NiNode * node ) {
-   while (index >= int(nodeGroups.size()))
-      nodeGroups.insert(nodeGroups.end(), NodeGroup() );
-   numNodeGroups2 = nodeGroups.size();
-
-   vector<NiNode*>& nodes = nodeGroups[index].nodes;
-   vector<NiNode*>::iterator itr = std::find(nodes.begin(), nodes.end(), node);
-   if (itr == nodes.end())
-      nodes.push_back(node);
-}
-
-void ABoneLODController::RemoveNodeFromGroup( int index, NiNode * node ) {
-   if (index < 0 || index >= int(nodeGroups.size()) ) {
-      throw runtime_error("Invalid index referenced.");
-   }
-   vector<NiNode*>& nodes = nodeGroups[index].nodes;
-   vector<NiNode*>::iterator itr = std::find(nodes.begin(), nodes.end(), node);
-   if (itr == nodes.end())
-      return;
-   nodes.erase(itr);
-}
-
-void ABoneLODController::SetNodeGroup( int index, const vector<Ref<NiNode> >& group ) {
-   while (index >= int(nodeGroups.size()))
-      nodeGroups.insert(nodeGroups.end(), NodeGroup() );
-   numNodeGroups2 = nodeGroups.size();
-   nodeGroups[index].nodes.assign(group.begin(), group.end());
-}
-
-void ABoneLODController::RemoveNodeGroup( int index ) {
-   if (index < 0 || index >= int(nodeGroups.size()) ) {
-      throw runtime_error("Invalid index referenced.");
-   }
-   vector<NodeGroup>::iterator itr = nodeGroups.begin();
-   std::advance(itr, index);
-   nodeGroups.erase(itr);
-   numNodeGroups2 = nodeGroups.size();
-}
-
-void ABoneLODController::ClearNodeGroups() {
-   nodeGroups.clear();
-   numNodeGroups2 = nodeGroups.size();
-}
-
-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["ABoneLODController"] = ABoneLODController::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 * ABoneLODController::Create() {
-	return new ABoneLODController;
-}
diff --git a/src/obj/APSysCtlr.cpp b/src/obj/APSysCtlr.cpp
deleted file mode 100644
index 06e422ad..00000000
--- a/src/obj/APSysCtlr.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2006, NIF File Format Library and Tools
-All rights reserved.  Please see niflib.h for license. */
-
-#include "../../include/obj/APSysCtlr.h"
-using namespace Niflib;
-
-//Definition of TYPE constant
-const Type APSysCtlr::TYPE("APSysCtlr", &A_P_SYS_CTLR_PARENT::TYPE );
-
-APSysCtlr::APSysCtlr() A_P_SYS_CTLR_CONSTRUCT {}
-
-APSysCtlr::~APSysCtlr() {}
-
-void APSysCtlr::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	InternalRead( in, link_stack, info );
-}
-
-void APSysCtlr::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	InternalWrite( out, link_map, info );
-}
-
-string APSysCtlr::asString( bool verbose ) const {
-	return InternalAsString( verbose );
-}
-
-void APSysCtlr::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	InternalFixLinks( objects, link_stack, info );
-}
-
-list<NiObjectRef> APSysCtlr::GetRefs() const {
-	return InternalGetRefs();
-}
-
-const Type & APSysCtlr::GetType() const {
-	return TYPE;
-};
-
-string APSysCtlr::GetModifierName() const {
-	return modifierName;
-}
-
-void APSysCtlr::SetModifierName( string value ) {
-	modifierName = value;
-}
-
-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["APSysCtlr"] = APSysCtlr::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 * APSysCtlr::Create() {
-	return new APSysCtlr;
-}
diff --git a/src/obj/AbhkConstraint.cpp b/src/obj/BSWindModifier.cpp
similarity index 58%
rename from src/obj/AbhkConstraint.cpp
rename to src/obj/BSWindModifier.cpp
index ab8e0aa8..5dd34590 100644
--- a/src/obj/AbhkConstraint.cpp
+++ b/src/obj/BSWindModifier.cpp
@@ -1,42 +1,41 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#include "../../include/obj/AbhkConstraint.h"
-#include "../../include/obj/bhkShape.h"
+#include "../../include/obj/BSWindModifier.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type AbhkConstraint::TYPE("AbhkConstraint", &ABHK_CONSTRAINT_PARENT::TYPE );
+const Type BSWindModifier::TYPE("BSWindModifier", &B_S_WIND_MODIFIER_PARENT::TYPE );
 
-AbhkConstraint::AbhkConstraint() ABHK_CONSTRAINT_CONSTRUCT {}
+BSWindModifier::BSWindModifier() B_S_WIND_MODIFIER_CONSTRUCT {}
 
-AbhkConstraint::~AbhkConstraint() {}
+BSWindModifier::~BSWindModifier() {}
 
-void AbhkConstraint::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void BSWindModifier::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalRead( in, link_stack, info );
 }
 
-void AbhkConstraint::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void BSWindModifier::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	InternalWrite( out, link_map, info );
 }
 
-string AbhkConstraint::asString( bool verbose ) const {
+string BSWindModifier::asString( bool verbose ) const {
 	return InternalAsString( verbose );
 }
 
-void AbhkConstraint::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void BSWindModifier::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalFixLinks( objects, link_stack, info );
 }
 
-list<NiObjectRef> AbhkConstraint::GetRefs() const {
+list<NiObjectRef> BSWindModifier::GetRefs() const {
 	return InternalGetRefs();
 }
 
-const Type & AbhkConstraint::GetType() const {
+const Type & BSWindModifier::GetType() const {
 	return TYPE;
-};
+}
 
-namespace Niflib { 
+namespace Niflib {
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
 
@@ -48,7 +47,7 @@ namespace Niflib {
 
 	static bool Initialization() {
 		//Add the function to the global object map
-		global_object_map["AbhkConstraint"] = AbhkConstraint::Create;
+		global_object_map["BSWindModifier"] = BSWindModifier::Create;
 
 		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
 		obj_initialized = true;
@@ -56,6 +55,7 @@ namespace Niflib {
 	}
 }
 
-NiObject * AbhkConstraint::Create() {
-	return new AbhkConstraint;
+NiObject * BSWindModifier::Create() {
+	return new BSWindModifier;
 }
+
diff --git a/src/obj/BSXFlags.cpp b/src/obj/BSXFlags.cpp
index 772adfbc..d43fe8d1 100644
--- a/src/obj/BSXFlags.cpp
+++ b/src/obj/BSXFlags.cpp
@@ -35,14 +35,6 @@ const Type & BSXFlags::GetType() const {
 	return TYPE;
 };
 
-unsigned int BSXFlags::GetFlags() const {
-	return flags;
-}
-
-void BSXFlags::SetFlags( unsigned int value ) {
-	flags = value;
-}
-
 namespace Niflib { 
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
diff --git a/src/obj/NiAVObject.cpp b/src/obj/NiAVObject.cpp
index 44efd770..58828993 100644
--- a/src/obj/NiAVObject.cpp
+++ b/src/obj/NiAVObject.cpp
@@ -19,7 +19,7 @@ NiAVObject::~NiAVObject() {
 
 	//Clear Collision Object Link
 	if ( collisionObject != NULL ) {
-		collisionObject->SetParent(NULL);
+		collisionObject->SetTarget(NULL);
 	}
 }
 
@@ -172,28 +172,19 @@ void NiAVObject::SetCollisionMode( CollisionType value ) {
 	flags = flags | temp;
 }
 
-Ref<NiCollisionData > NiAVObject::GetCollisionData() const {
-   return collisionData;
-}
-
-void NiAVObject::SetCollisionData( NiCollisionData * value ) {
-   collisionData = value;
-}
-
-
 Ref<NiCollisionObject > NiAVObject::GetCollisionObject() const {
   return collisionObject;
 }
 
 void NiAVObject::SetCollisionObject( NiCollisionObject * value ) {
-	if ( value->GetParent() != NULL ) {
-		throw runtime_error( "You have attempted to add a collision object to a NiNode which is already attached to another NiNode." );
+	if ( value->GetTarget() != NULL ) {
+		throw runtime_error( "You have attempted to add a collision object to a NiAVObject which is already attached to another NiAVObject." );
 	}
-	value->SetParent( this );
+	value->SetTarget( this );
 
 	if ( collisionObject !=NULL ) {
 		//Remove unlink previous collision object from this node
-		collisionObject->SetParent(NULL);
+		collisionObject->SetTarget(NULL);
 	}
 
 	collisionObject = value;
diff --git a/src/obj/NiAVObjectPalette.cpp b/src/obj/NiAVObjectPalette.cpp
new file mode 100644
index 00000000..d05d4149
--- /dev/null
+++ b/src/obj/NiAVObjectPalette.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/NiAVObjectPalette.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiAVObjectPalette::TYPE("NiAVObjectPalette", &NI_A_V_OBJECT_PALETTE_PARENT::TYPE );
+
+NiAVObjectPalette::NiAVObjectPalette() NI_A_V_OBJECT_PALETTE_CONSTRUCT {}
+
+NiAVObjectPalette::~NiAVObjectPalette() {}
+
+void NiAVObjectPalette::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiAVObjectPalette::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiAVObjectPalette::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiAVObjectPalette::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiAVObjectPalette::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiAVObjectPalette::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["NiAVObjectPalette"] = NiAVObjectPalette::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 * NiAVObjectPalette::Create() {
+	return new NiAVObjectPalette;
+}
+
diff --git a/src/obj/NiBSplineFloatInterpolator.cpp b/src/obj/NiBSplineFloatInterpolator.cpp
new file mode 100644
index 00000000..ccf62f1b
--- /dev/null
+++ b/src/obj/NiBSplineFloatInterpolator.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/NiBSplineFloatInterpolator.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiBSplineFloatInterpolator::TYPE("NiBSplineFloatInterpolator", &NI_B_SPLINE_FLOAT_INTERPOLATOR_PARENT::TYPE );
+
+NiBSplineFloatInterpolator::NiBSplineFloatInterpolator() NI_B_SPLINE_FLOAT_INTERPOLATOR_CONSTRUCT {}
+
+NiBSplineFloatInterpolator::~NiBSplineFloatInterpolator() {}
+
+void NiBSplineFloatInterpolator::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiBSplineFloatInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiBSplineFloatInterpolator::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiBSplineFloatInterpolator::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiBSplineFloatInterpolator::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiBSplineFloatInterpolator::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["NiBSplineFloatInterpolator"] = NiBSplineFloatInterpolator::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 * NiBSplineFloatInterpolator::Create() {
+	return new NiBSplineFloatInterpolator;
+}
+
diff --git a/src/obj/NiBSplinePoint3Interpolator.cpp b/src/obj/NiBSplinePoint3Interpolator.cpp
new file mode 100644
index 00000000..669e3fc0
--- /dev/null
+++ b/src/obj/NiBSplinePoint3Interpolator.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/NiBSplinePoint3Interpolator.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiBSplinePoint3Interpolator::TYPE("NiBSplinePoint3Interpolator", &NI_B_SPLINE_POINT3_INTERPOLATOR_PARENT::TYPE );
+
+NiBSplinePoint3Interpolator::NiBSplinePoint3Interpolator() NI_B_SPLINE_POINT3_INTERPOLATOR_CONSTRUCT {}
+
+NiBSplinePoint3Interpolator::~NiBSplinePoint3Interpolator() {}
+
+void NiBSplinePoint3Interpolator::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiBSplinePoint3Interpolator::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiBSplinePoint3Interpolator::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiBSplinePoint3Interpolator::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiBSplinePoint3Interpolator::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiBSplinePoint3Interpolator::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["NiBSplinePoint3Interpolator"] = NiBSplinePoint3Interpolator::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 * NiBSplinePoint3Interpolator::Create() {
+	return new NiBSplinePoint3Interpolator;
+}
+
diff --git a/src/obj/NiBSplineTransformInterpolator.cpp b/src/obj/NiBSplineTransformInterpolator.cpp
new file mode 100644
index 00000000..7564327e
--- /dev/null
+++ b/src/obj/NiBSplineTransformInterpolator.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/NiBSplineTransformInterpolator.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiBSplineTransformInterpolator::TYPE("NiBSplineTransformInterpolator", &NI_B_SPLINE_TRANSFORM_INTERPOLATOR_PARENT::TYPE );
+
+NiBSplineTransformInterpolator::NiBSplineTransformInterpolator() NI_B_SPLINE_TRANSFORM_INTERPOLATOR_CONSTRUCT {}
+
+NiBSplineTransformInterpolator::~NiBSplineTransformInterpolator() {}
+
+void NiBSplineTransformInterpolator::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiBSplineTransformInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiBSplineTransformInterpolator::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiBSplineTransformInterpolator::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiBSplineTransformInterpolator::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiBSplineTransformInterpolator::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["NiBSplineTransformInterpolator"] = NiBSplineTransformInterpolator::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 * NiBSplineTransformInterpolator::Create() {
+	return new NiBSplineTransformInterpolator;
+}
+
diff --git a/src/obj/NiBoolInterpController.cpp b/src/obj/NiBoolInterpController.cpp
new file mode 100644
index 00000000..891d1012
--- /dev/null
+++ b/src/obj/NiBoolInterpController.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/NiBoolInterpController.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiBoolInterpController::TYPE("NiBoolInterpController", &NI_BOOL_INTERP_CONTROLLER_PARENT::TYPE );
+
+NiBoolInterpController::NiBoolInterpController() NI_BOOL_INTERP_CONTROLLER_CONSTRUCT {}
+
+NiBoolInterpController::~NiBoolInterpController() {}
+
+void NiBoolInterpController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiBoolInterpController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiBoolInterpController::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiBoolInterpController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiBoolInterpController::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiBoolInterpController::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["NiBoolInterpController"] = NiBoolInterpController::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 * NiBoolInterpController::Create() {
+	return new NiBoolInterpController;
+}
+
diff --git a/src/obj/NiCollisionObject.cpp b/src/obj/NiCollisionObject.cpp
index 1bd5cf63..0fc5672e 100644
--- a/src/obj/NiCollisionObject.cpp
+++ b/src/obj/NiCollisionObject.cpp
@@ -4,6 +4,7 @@ All rights reserved.  Please see niflib.h for license. */
 #include "../../include/obj/NiCollisionObject.h"
 #include "../../include/obj/NiAVObject.h"
 #include "../../include/obj/NiObject.h"
+#include "../../include/obj/NiNode.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
@@ -37,12 +38,12 @@ const Type & NiCollisionObject::GetType() const {
 	return TYPE;
 };
 
-Ref<NiAVObject> NiCollisionObject::GetParent() const {
-	return Ref<NiAVObject>(parent);
+Ref<NiAVObject> NiCollisionObject::GetTarget() const {
+	return target;
 }
 
-void NiCollisionObject::SetParent( NiAVObject * value ) {
-	parent = value;
+void NiCollisionObject::SetTarget( NiAVObject * value ) {
+	target = value;
 }
 
 Ref<NiObject > NiCollisionObject::GetBody() const {
diff --git a/src/obj/NiControllerSequence.cpp b/src/obj/NiControllerSequence.cpp
index 29550ae6..6ffb7d5e 100644
--- a/src/obj/NiControllerSequence.cpp
+++ b/src/obj/NiControllerSequence.cpp
@@ -10,7 +10,7 @@ All rights reserved.  Please see niflib.h for license. */
 #include "../../include/obj/NiTextKeyExtraData.h"
 #include "../../include/obj/NiControllerManager.h"
 #include "../../include/obj/NiTimeController.h"
-#include "../../include/obj/NiSingleInterpolatorController.h"
+#include "../../include/obj/NiSingleInterpController.h"
 #include "../../include/obj/NiObjectNET.h"
 #include "../../include/obj/NiProperty.h"
 
@@ -90,7 +90,7 @@ void NiControllerSequence::AddController( NiTimeController * obj ) {
 	controlledBlocks.push_back( cl );
 }
 
-void NiControllerSequence::AddInterpolator( NiSingleInterpolatorController * obj, byte priority ) {
+void NiControllerSequence::AddInterpolator( NiSingleInterpController * obj, byte priority ) {
 	//Make sure the link isn't null
 	if ( obj == NULL ) {
 		throw runtime_error("Attempted to add a null controller to NiControllerSequence block.");
diff --git a/src/obj/AbhkRagdollConstraint.cpp b/src/obj/NiExtraDataController.cpp
similarity index 56%
rename from src/obj/AbhkRagdollConstraint.cpp
rename to src/obj/NiExtraDataController.cpp
index 1a648c33..4e047685 100644
--- a/src/obj/AbhkRagdollConstraint.cpp
+++ b/src/obj/NiExtraDataController.cpp
@@ -1,42 +1,41 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#include "../../include/obj/AbhkRagdollConstraint.h"
+#include "../../include/obj/NiExtraDataController.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type AbhkRagdollConstraint::TYPE("AbhkRagdollConstraint", &ABHK_RAGDOLL_CONSTRAINT_PARENT::TYPE );
+const Type NiExtraDataController::TYPE("NiExtraDataController", &NI_EXTRA_DATA_CONTROLLER_PARENT::TYPE );
 
-AbhkRagdollConstraint::AbhkRagdollConstraint() ABHK_RAGDOLL_CONSTRAINT_CONSTRUCT {}
+NiExtraDataController::NiExtraDataController() NI_EXTRA_DATA_CONTROLLER_CONSTRUCT {}
 
-AbhkRagdollConstraint::~AbhkRagdollConstraint() {}
+NiExtraDataController::~NiExtraDataController() {}
 
-void AbhkRagdollConstraint::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiExtraDataController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalRead( in, link_stack, info );
 }
 
-void AbhkRagdollConstraint::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void NiExtraDataController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	InternalWrite( out, link_map, info );
 }
 
-string AbhkRagdollConstraint::asString( bool verbose ) const {
+string NiExtraDataController::asString( bool verbose ) const {
 	return InternalAsString( verbose );
 }
 
-void AbhkRagdollConstraint::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiExtraDataController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalFixLinks( objects, link_stack, info );
 }
 
-list<NiObjectRef> AbhkRagdollConstraint::GetRefs() const {
+list<NiObjectRef> NiExtraDataController::GetRefs() const {
 	return InternalGetRefs();
 }
 
-const Type & AbhkRagdollConstraint::GetType() const {
+const Type & NiExtraDataController::GetType() const {
 	return TYPE;
-};
-
+}
 
-namespace Niflib { 
+namespace Niflib {
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
 
@@ -48,7 +47,7 @@ namespace Niflib {
 
 	static bool Initialization() {
 		//Add the function to the global object map
-		global_object_map["AbhkRagdollConstraint"] = AbhkRagdollConstraint::Create;
+		global_object_map["NiExtraDataController"] = NiExtraDataController::Create;
 
 		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
 		obj_initialized = true;
@@ -56,6 +55,7 @@ namespace Niflib {
 	}
 }
 
-NiObject * AbhkRagdollConstraint::Create() {
-	return new AbhkRagdollConstraint;
+NiObject * NiExtraDataController::Create() {
+	return new NiExtraDataController;
 }
+
diff --git a/src/obj/NiFloatInterpController.cpp b/src/obj/NiFloatInterpController.cpp
new file mode 100644
index 00000000..6a56dcfa
--- /dev/null
+++ b/src/obj/NiFloatInterpController.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/NiFloatInterpController.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiFloatInterpController::TYPE("NiFloatInterpController", &NI_FLOAT_INTERP_CONTROLLER_PARENT::TYPE );
+
+NiFloatInterpController::NiFloatInterpController() NI_FLOAT_INTERP_CONTROLLER_CONSTRUCT {}
+
+NiFloatInterpController::~NiFloatInterpController() {}
+
+void NiFloatInterpController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiFloatInterpController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiFloatInterpController::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiFloatInterpController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiFloatInterpController::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiFloatInterpController::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["NiFloatInterpController"] = NiFloatInterpController::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 * NiFloatInterpController::Create() {
+	return new NiFloatInterpController;
+}
+
diff --git a/src/obj/NiInterpController.cpp b/src/obj/NiInterpController.cpp
new file mode 100644
index 00000000..fb9a84e7
--- /dev/null
+++ b/src/obj/NiInterpController.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/NiInterpController.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiInterpController::TYPE("NiInterpController", &NI_INTERP_CONTROLLER_PARENT::TYPE );
+
+NiInterpController::NiInterpController() NI_INTERP_CONTROLLER_CONSTRUCT {}
+
+NiInterpController::~NiInterpController() {}
+
+void NiInterpController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiInterpController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiInterpController::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiInterpController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiInterpController::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiInterpController::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["NiInterpController"] = NiInterpController::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 * NiInterpController::Create() {
+	return new NiInterpController;
+}
+
diff --git a/src/obj/NiKeyBasedInterpolator.cpp b/src/obj/NiKeyBasedInterpolator.cpp
new file mode 100644
index 00000000..6a78177f
--- /dev/null
+++ b/src/obj/NiKeyBasedInterpolator.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/NiKeyBasedInterpolator.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiKeyBasedInterpolator::TYPE("NiKeyBasedInterpolator", &NI_KEY_BASED_INTERPOLATOR_PARENT::TYPE );
+
+NiKeyBasedInterpolator::NiKeyBasedInterpolator() NI_KEY_BASED_INTERPOLATOR_CONSTRUCT {}
+
+NiKeyBasedInterpolator::~NiKeyBasedInterpolator() {}
+
+void NiKeyBasedInterpolator::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiKeyBasedInterpolator::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiKeyBasedInterpolator::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiKeyBasedInterpolator::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiKeyBasedInterpolator::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiKeyBasedInterpolator::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["NiKeyBasedInterpolator"] = NiKeyBasedInterpolator::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 * NiKeyBasedInterpolator::Create() {
+	return new NiKeyBasedInterpolator;
+}
+
diff --git a/src/obj/NiLightColorController.cpp b/src/obj/NiLightColorController.cpp
index d46e8d21..79670926 100644
--- a/src/obj/NiLightColorController.cpp
+++ b/src/obj/NiLightColorController.cpp
@@ -37,22 +37,6 @@ const Type & NiLightColorController::GetType() const {
 	return TYPE;
 };
 
-Ref<NiPosData > NiLightColorController::GetData() const {
-	return data;
-}
-
-void NiLightColorController::SetData( NiPosData * value ) {
-	data = value;
-}
-
-Ref<NiPoint3Interpolator > NiLightColorController::GetInterpolator() const {
-	return interpolator;
-}
-
-void NiLightColorController::SetInterpolator( NiPoint3Interpolator * value ) {
-	interpolator = value;
-}
-
 namespace Niflib { 
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
diff --git a/src/obj/NiPSysModifierActiveCtlr.cpp b/src/obj/NiPSysModifierActiveCtlr.cpp
index 40ac0c46..ebc8d406 100644
--- a/src/obj/NiPSysModifierActiveCtlr.cpp
+++ b/src/obj/NiPSysModifierActiveCtlr.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for license. */
 
 #include "../../include/obj/NiPSysModifierActiveCtlr.h"
+#include "../../include/obj/NiVisData.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
diff --git a/src/obj/NiPSysModifierBoolCtlr.cpp b/src/obj/NiPSysModifierBoolCtlr.cpp
new file mode 100644
index 00000000..2321c7ef
--- /dev/null
+++ b/src/obj/NiPSysModifierBoolCtlr.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/NiPSysModifierBoolCtlr.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiPSysModifierBoolCtlr::TYPE("NiPSysModifierBoolCtlr", &NI_P_SYS_MODIFIER_BOOL_CTLR_PARENT::TYPE );
+
+NiPSysModifierBoolCtlr::NiPSysModifierBoolCtlr() NI_P_SYS_MODIFIER_BOOL_CTLR_CONSTRUCT {}
+
+NiPSysModifierBoolCtlr::~NiPSysModifierBoolCtlr() {}
+
+void NiPSysModifierBoolCtlr::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiPSysModifierBoolCtlr::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiPSysModifierBoolCtlr::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiPSysModifierBoolCtlr::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiPSysModifierBoolCtlr::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiPSysModifierBoolCtlr::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["NiPSysModifierBoolCtlr"] = NiPSysModifierBoolCtlr::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 * NiPSysModifierBoolCtlr::Create() {
+	return new NiPSysModifierBoolCtlr;
+}
+
diff --git a/src/obj/NiPSysModifierCtlr.cpp b/src/obj/NiPSysModifierCtlr.cpp
new file mode 100644
index 00000000..6c7c19a4
--- /dev/null
+++ b/src/obj/NiPSysModifierCtlr.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/NiPSysModifierCtlr.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiPSysModifierCtlr::TYPE("NiPSysModifierCtlr", &NI_P_SYS_MODIFIER_CTLR_PARENT::TYPE );
+
+NiPSysModifierCtlr::NiPSysModifierCtlr() NI_P_SYS_MODIFIER_CTLR_CONSTRUCT {}
+
+NiPSysModifierCtlr::~NiPSysModifierCtlr() {}
+
+void NiPSysModifierCtlr::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiPSysModifierCtlr::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiPSysModifierCtlr::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiPSysModifierCtlr::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiPSysModifierCtlr::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiPSysModifierCtlr::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["NiPSysModifierCtlr"] = NiPSysModifierCtlr::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 * NiPSysModifierCtlr::Create() {
+	return new NiPSysModifierCtlr;
+}
+
diff --git a/src/obj/NiPSysModifierFloatCtlr.cpp b/src/obj/NiPSysModifierFloatCtlr.cpp
new file mode 100644
index 00000000..c17ced27
--- /dev/null
+++ b/src/obj/NiPSysModifierFloatCtlr.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/NiPSysModifierFloatCtlr.h"
+#include "../../include/obj/NiFloatData.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiPSysModifierFloatCtlr::TYPE("NiPSysModifierFloatCtlr", &NI_P_SYS_MODIFIER_FLOAT_CTLR_PARENT::TYPE );
+
+NiPSysModifierFloatCtlr::NiPSysModifierFloatCtlr() NI_P_SYS_MODIFIER_FLOAT_CTLR_CONSTRUCT {}
+
+NiPSysModifierFloatCtlr::~NiPSysModifierFloatCtlr() {}
+
+void NiPSysModifierFloatCtlr::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiPSysModifierFloatCtlr::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiPSysModifierFloatCtlr::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiPSysModifierFloatCtlr::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiPSysModifierFloatCtlr::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiPSysModifierFloatCtlr::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["NiPSysModifierFloatCtlr"] = NiPSysModifierFloatCtlr::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 * NiPSysModifierFloatCtlr::Create() {
+	return new NiPSysModifierFloatCtlr;
+}
+
diff --git a/src/obj/NiPoint3InterpController.cpp b/src/obj/NiPoint3InterpController.cpp
new file mode 100644
index 00000000..7f579c0c
--- /dev/null
+++ b/src/obj/NiPoint3InterpController.cpp
@@ -0,0 +1,69 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiPoint3InterpController.h"
+#include "../../include/obj/NiPosData.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiPoint3InterpController::TYPE("NiPoint3InterpController", &NI_POINT3_INTERP_CONTROLLER_PARENT::TYPE );
+
+NiPoint3InterpController::NiPoint3InterpController() NI_POINT3_INTERP_CONTROLLER_CONSTRUCT {}
+
+NiPoint3InterpController::~NiPoint3InterpController() {}
+
+void NiPoint3InterpController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiPoint3InterpController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiPoint3InterpController::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiPoint3InterpController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiPoint3InterpController::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiPoint3InterpController::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["NiPoint3InterpController"] = NiPoint3InterpController::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 * NiPoint3InterpController::Create() {
+	return new NiPoint3InterpController;
+}
+
+Ref<NiPosData > NiPoint3InterpController::GetData() const {
+	return data;
+}
+
+void NiPoint3InterpController::SetData( NiPosData * value ) {
+	data = value;
+}
\ No newline at end of file
diff --git a/src/obj/NiSingleInterpController.cpp b/src/obj/NiSingleInterpController.cpp
new file mode 100644
index 00000000..a4d7e5b1
--- /dev/null
+++ b/src/obj/NiSingleInterpController.cpp
@@ -0,0 +1,69 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for license. */
+
+#include "../../include/obj/NiSingleInterpController.h"
+#include "../../include/obj/NiInterpolator.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiSingleInterpController::TYPE("NiSingleInterpController", &NI_SINGLE_INTERP_CONTROLLER_PARENT::TYPE );
+
+NiSingleInterpController::NiSingleInterpController() NI_SINGLE_INTERP_CONTROLLER_CONSTRUCT {}
+
+NiSingleInterpController::~NiSingleInterpController() {}
+
+void NiSingleInterpController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiSingleInterpController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiSingleInterpController::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiSingleInterpController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiSingleInterpController::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiSingleInterpController::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["NiSingleInterpController"] = NiSingleInterpController::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 * NiSingleInterpController::Create() {
+	return new NiSingleInterpController;
+}
+
+Ref<NiInterpolator > NiSingleInterpController::GetInterpolator() const {
+	return interpolator;
+}
+
+void NiSingleInterpController::SetInterpolator( NiInterpolator * value ) {
+	interpolator = value;
+}
\ No newline at end of file
diff --git a/src/obj/NiSingleInterpolatorController.cpp b/src/obj/NiSingleInterpolatorController.cpp
deleted file mode 100644
index 7d85dbf8..00000000
--- a/src/obj/NiSingleInterpolatorController.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (c) 2006, NIF File Format Library and Tools
-All rights reserved.  Please see niflib.h for license. */
-
-#include "../../include/obj/NiSingleInterpolatorController.h"
-#include "../../include/obj/NiInterpolator.h"
-using namespace Niflib;
-
-//Definition of TYPE constant
-const Type NiSingleInterpolatorController::TYPE("NiSingleInterpolatorController", &NI_SINGLE_INTERPOLATOR_CONTROLLER_PARENT::TYPE );
-
-NiSingleInterpolatorController::NiSingleInterpolatorController() NI_SINGLE_INTERPOLATOR_CONTROLLER_CONSTRUCT {}
-
-NiSingleInterpolatorController::~NiSingleInterpolatorController() {}
-
-void NiSingleInterpolatorController::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
-	InternalRead( in, link_stack, info );
-}
-
-void NiSingleInterpolatorController::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
-	InternalWrite( out, link_map, info );
-}
-
-string NiSingleInterpolatorController::asString( bool verbose ) const {
-	return InternalAsString( verbose );
-}
-
-void NiSingleInterpolatorController::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
-	InternalFixLinks( objects, link_stack, info );
-}
-
-list<NiObjectRef> NiSingleInterpolatorController::GetRefs() const {
-	return InternalGetRefs();
-}
-
-const Type & NiSingleInterpolatorController::GetType() const {
-	return TYPE;
-};
-
-Ref<NiInterpolator > NiSingleInterpolatorController::GetInterpolator() const {
-	return interpolator;
-}
-
-void NiSingleInterpolatorController::SetInterpolator( NiInterpolator * value ) {
-	interpolator = value;
-}
-
-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["NiSingleInterpolatorController"] = NiSingleInterpolatorController::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 * NiSingleInterpolatorController::Create() {
-	return new NiSingleInterpolatorController;
-}
diff --git a/src/obj/NiSwitchNode.cpp b/src/obj/NiSwitchNode.cpp
new file mode 100644
index 00000000..9603a2f8
--- /dev/null
+++ b/src/obj/NiSwitchNode.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/NiSwitchNode.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type NiSwitchNode::TYPE("NiSwitchNode", &NI_SWITCH_NODE_PARENT::TYPE );
+
+NiSwitchNode::NiSwitchNode() NI_SWITCH_NODE_CONSTRUCT {}
+
+NiSwitchNode::~NiSwitchNode() {}
+
+void NiSwitchNode::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void NiSwitchNode::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string NiSwitchNode::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void NiSwitchNode::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> NiSwitchNode::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & NiSwitchNode::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["NiSwitchNode"] = NiSwitchNode::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 * NiSwitchNode::Create() {
+	return new NiSwitchNode;
+}
+
diff --git a/src/obj/APSysData.cpp b/src/obj/NiTexture.cpp
similarity index 61%
rename from src/obj/APSysData.cpp
rename to src/obj/NiTexture.cpp
index 16901793..b088b7f4 100644
--- a/src/obj/APSysData.cpp
+++ b/src/obj/NiTexture.cpp
@@ -1,41 +1,41 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#include "../../include/obj/APSysData.h"
+#include "../../include/obj/NiTexture.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type APSysData::TYPE("APSysData", &A_P_SYS_DATA_PARENT::TYPE );
+const Type NiTexture::TYPE("NiTexture", &NI_TEXTURE_PARENT::TYPE );
 
-APSysData::APSysData() A_P_SYS_DATA_CONSTRUCT {}
+NiTexture::NiTexture() NI_TEXTURE_CONSTRUCT {}
 
-APSysData::~APSysData() {}
+NiTexture::~NiTexture() {}
 
-void APSysData::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiTexture::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalRead( in, link_stack, info );
 }
 
-void APSysData::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void NiTexture::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	InternalWrite( out, link_map, info );
 }
 
-string APSysData::asString( bool verbose ) const {
+string NiTexture::asString( bool verbose ) const {
 	return InternalAsString( verbose );
 }
 
-void APSysData::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void NiTexture::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalFixLinks( objects, link_stack, info );
 }
 
-list<NiObjectRef> APSysData::GetRefs() const {
+list<NiObjectRef> NiTexture::GetRefs() const {
 	return InternalGetRefs();
 }
 
-const Type & APSysData::GetType() const {
+const Type & NiTexture::GetType() const {
 	return TYPE;
-};
+}
 
-namespace Niflib { 
+namespace Niflib {
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
 
@@ -47,7 +47,7 @@ namespace Niflib {
 
 	static bool Initialization() {
 		//Add the function to the global object map
-		global_object_map["APSysData"] = APSysData::Create;
+		global_object_map["NiTexture"] = NiTexture::Create;
 
 		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
 		obj_initialized = true;
@@ -55,6 +55,7 @@ namespace Niflib {
 	}
 }
 
-NiObject * APSysData::Create() {
-	return new APSysData;
+NiObject * NiTexture::Create() {
+	return new NiTexture;
 }
+
diff --git a/src/obj/bhkBvTreeShape.cpp b/src/obj/bhkBvTreeShape.cpp
new file mode 100644
index 00000000..82061d38
--- /dev/null
+++ b/src/obj/bhkBvTreeShape.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/bhkBvTreeShape.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type bhkBvTreeShape::TYPE("bhkBvTreeShape", &BHK_BV_TREE_SHAPE_PARENT::TYPE );
+
+bhkBvTreeShape::bhkBvTreeShape() BHK_BV_TREE_SHAPE_CONSTRUCT {}
+
+bhkBvTreeShape::~bhkBvTreeShape() {}
+
+void bhkBvTreeShape::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void bhkBvTreeShape::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string bhkBvTreeShape::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void bhkBvTreeShape::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> bhkBvTreeShape::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & bhkBvTreeShape::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["bhkBvTreeShape"] = bhkBvTreeShape::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 * bhkBvTreeShape::Create() {
+	return new bhkBvTreeShape;
+}
+
diff --git a/src/obj/bhkConstraint.cpp b/src/obj/bhkConstraint.cpp
new file mode 100644
index 00000000..5666ceb5
--- /dev/null
+++ b/src/obj/bhkConstraint.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/bhkConstraint.h"
+#include "../../include/obj/bhkEntity.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type bhkConstraint::TYPE("bhkConstraint", &BHK_CONSTRAINT_PARENT::TYPE );
+
+bhkConstraint::bhkConstraint() BHK_CONSTRAINT_CONSTRUCT {}
+
+bhkConstraint::~bhkConstraint() {}
+
+void bhkConstraint::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void bhkConstraint::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string bhkConstraint::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void bhkConstraint::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> bhkConstraint::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & bhkConstraint::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["bhkConstraint"] = bhkConstraint::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 * bhkConstraint::Create() {
+	return new bhkConstraint;
+}
+
diff --git a/src/obj/bhkNiCollisionObject.cpp b/src/obj/bhkNiCollisionObject.cpp
new file mode 100644
index 00000000..f10f1b02
--- /dev/null
+++ b/src/obj/bhkNiCollisionObject.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/bhkNiCollisionObject.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type bhkNiCollisionObject::TYPE("bhkNiCollisionObject", &BHK_NI_COLLISION_OBJECT_PARENT::TYPE );
+
+bhkNiCollisionObject::bhkNiCollisionObject() BHK_NI_COLLISION_OBJECT_CONSTRUCT {}
+
+bhkNiCollisionObject::~bhkNiCollisionObject() {}
+
+void bhkNiCollisionObject::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void bhkNiCollisionObject::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string bhkNiCollisionObject::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void bhkNiCollisionObject::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> bhkNiCollisionObject::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & bhkNiCollisionObject::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["bhkNiCollisionObject"] = bhkNiCollisionObject::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 * bhkNiCollisionObject::Create() {
+	return new bhkNiCollisionObject;
+}
+
diff --git a/src/obj/AbhkShapeCollection.cpp b/src/obj/bhkPCollisionObject.cpp
similarity index 57%
rename from src/obj/AbhkShapeCollection.cpp
rename to src/obj/bhkPCollisionObject.cpp
index ee55a29d..ec49877a 100644
--- a/src/obj/AbhkShapeCollection.cpp
+++ b/src/obj/bhkPCollisionObject.cpp
@@ -1,42 +1,41 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#include "../../include/obj/AbhkShapeCollection.h"
+#include "../../include/obj/bhkPCollisionObject.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type AbhkShapeCollection::TYPE("AbhkShapeCollection", &ABHK_SHAPE_COLLECTION_PARENT::TYPE );
+const Type bhkPCollisionObject::TYPE("bhkPCollisionObject", &BHK_P_COLLISION_OBJECT_PARENT::TYPE );
 
-AbhkShapeCollection::AbhkShapeCollection() ABHK_SHAPE_COLLECTION_CONSTRUCT {}
+bhkPCollisionObject::bhkPCollisionObject() BHK_P_COLLISION_OBJECT_CONSTRUCT {}
 
-AbhkShapeCollection::~AbhkShapeCollection() {}
+bhkPCollisionObject::~bhkPCollisionObject() {}
 
-void AbhkShapeCollection::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkPCollisionObject::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalRead( in, link_stack, info );
 }
 
-void AbhkShapeCollection::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void bhkPCollisionObject::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	InternalWrite( out, link_map, info );
 }
 
-string AbhkShapeCollection::asString( bool verbose ) const {
+string bhkPCollisionObject::asString( bool verbose ) const {
 	return InternalAsString( verbose );
 }
 
-void AbhkShapeCollection::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkPCollisionObject::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalFixLinks( objects, link_stack, info );
 }
 
-list<NiObjectRef> AbhkShapeCollection::GetRefs() const {
+list<NiObjectRef> bhkPCollisionObject::GetRefs() const {
 	return InternalGetRefs();
 }
 
-const Type & AbhkShapeCollection::GetType() const {
+const Type & bhkPCollisionObject::GetType() const {
 	return TYPE;
-};
-
+}
 
-namespace Niflib { 
+namespace Niflib {
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
 
@@ -48,7 +47,7 @@ namespace Niflib {
 
 	static bool Initialization() {
 		//Add the function to the global object map
-		global_object_map["AbhkShapeCollection"] = AbhkShapeCollection::Create;
+		global_object_map["bhkPCollisionObject"] = bhkPCollisionObject::Create;
 
 		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
 		obj_initialized = true;
@@ -56,6 +55,7 @@ namespace Niflib {
 	}
 }
 
-NiObject * AbhkShapeCollection::Create() {
-	return new AbhkShapeCollection;
+NiObject * bhkPCollisionObject::Create() {
+	return new bhkPCollisionObject;
 }
+
diff --git a/src/obj/AKeyedData.cpp b/src/obj/bhkPhantom.cpp
similarity index 61%
rename from src/obj/AKeyedData.cpp
rename to src/obj/bhkPhantom.cpp
index 67ce400b..8ef2f0e6 100644
--- a/src/obj/AKeyedData.cpp
+++ b/src/obj/bhkPhantom.cpp
@@ -1,41 +1,41 @@
 /* Copyright (c) 2006, NIF File Format Library and Tools
 All rights reserved.  Please see niflib.h for license. */
 
-#include "../../include/obj/AKeyedData.h"
+#include "../../include/obj/bhkPhantom.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type AKeyedData::TYPE("AKeyedData", &A_KEYED_DATA_PARENT::TYPE );
+const Type bhkPhantom::TYPE("bhkPhantom", &BHK_PHANTOM_PARENT::TYPE );
 
-AKeyedData::AKeyedData() A_KEYED_DATA_CONSTRUCT {}
+bhkPhantom::bhkPhantom() BHK_PHANTOM_CONSTRUCT {}
 
-AKeyedData::~AKeyedData() {}
+bhkPhantom::~bhkPhantom() {}
 
-void AKeyedData::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkPhantom::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalRead( in, link_stack, info );
 }
 
-void AKeyedData::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+void bhkPhantom::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
 	InternalWrite( out, link_map, info );
 }
 
-string AKeyedData::asString( bool verbose ) const {
+string bhkPhantom::asString( bool verbose ) const {
 	return InternalAsString( verbose );
 }
 
-void AKeyedData::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+void bhkPhantom::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
 	InternalFixLinks( objects, link_stack, info );
 }
 
-list<NiObjectRef> AKeyedData::GetRefs() const {
+list<NiObjectRef> bhkPhantom::GetRefs() const {
 	return InternalGetRefs();
 }
 
-const Type & AKeyedData::GetType() const {
+const Type & bhkPhantom::GetType() const {
 	return TYPE;
-};
+}
 
-namespace Niflib { 
+namespace Niflib {
 	typedef NiObject*(*obj_factory_func)();
 	extern map<string, obj_factory_func> global_object_map;
 
@@ -47,7 +47,7 @@ namespace Niflib {
 
 	static bool Initialization() {
 		//Add the function to the global object map
-		global_object_map["AKeyedData"] = AKeyedData::Create;
+		global_object_map["bhkPhantom"] = bhkPhantom::Create;
 
 		//Do this stuff just to make sure the compiler doesn't optimize this function and the static bool away.
 		obj_initialized = true;
@@ -55,6 +55,7 @@ namespace Niflib {
 	}
 }
 
-NiObject * AKeyedData::Create() {
-	return new AKeyedData;
+NiObject * bhkPhantom::Create() {
+	return new bhkPhantom;
 }
+
diff --git a/src/obj/bhkRigidBody.cpp b/src/obj/bhkRigidBody.cpp
index 14de5416..db7ed3a2 100644
--- a/src/obj/bhkRigidBody.cpp
+++ b/src/obj/bhkRigidBody.cpp
@@ -3,7 +3,7 @@ All rights reserved.  Please see niflib.h for license. */
 
 #include "../../include/obj/bhkRigidBody.h"
 #include "../../include/gen/QuaternionXYZW.h"
-#include "../../include/obj/AbhkConstraint.h"
+#include "../../include/obj/bhkConstraint.h"
 using namespace Niflib;
 
 //Definition of TYPE constant
diff --git a/src/obj/bhkShapeCollection.cpp b/src/obj/bhkShapeCollection.cpp
new file mode 100644
index 00000000..96e5246e
--- /dev/null
+++ b/src/obj/bhkShapeCollection.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/bhkShapeCollection.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type bhkShapeCollection::TYPE("bhkShapeCollection", &BHK_SHAPE_COLLECTION_PARENT::TYPE );
+
+bhkShapeCollection::bhkShapeCollection() BHK_SHAPE_COLLECTION_CONSTRUCT {}
+
+bhkShapeCollection::~bhkShapeCollection() {}
+
+void bhkShapeCollection::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void bhkShapeCollection::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string bhkShapeCollection::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void bhkShapeCollection::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> bhkShapeCollection::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & bhkShapeCollection::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["bhkShapeCollection"] = bhkShapeCollection::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 * bhkShapeCollection::Create() {
+	return new bhkShapeCollection;
+}
+
diff --git a/src/obj/bhkShapePhantom.cpp b/src/obj/bhkShapePhantom.cpp
new file mode 100644
index 00000000..71d199e5
--- /dev/null
+++ b/src/obj/bhkShapePhantom.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/bhkShapePhantom.h"
+using namespace Niflib;
+
+//Definition of TYPE constant
+const Type bhkShapePhantom::TYPE("bhkShapePhantom", &BHK_SHAPE_PHANTOM_PARENT::TYPE );
+
+bhkShapePhantom::bhkShapePhantom() BHK_SHAPE_PHANTOM_CONSTRUCT {}
+
+bhkShapePhantom::~bhkShapePhantom() {}
+
+void bhkShapePhantom::Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalRead( in, link_stack, info );
+}
+
+void bhkShapePhantom::Write( ostream& out, const map<NiObjectRef,unsigned int> & link_map, const NifInfo & info ) const {
+	InternalWrite( out, link_map, info );
+}
+
+string bhkShapePhantom::asString( bool verbose ) const {
+	return InternalAsString( verbose );
+}
+
+void bhkShapePhantom::FixLinks( const map<unsigned int,NiObjectRef> & objects, list<unsigned int> & link_stack, const NifInfo & info ) {
+	InternalFixLinks( objects, link_stack, info );
+}
+
+list<NiObjectRef> bhkShapePhantom::GetRefs() const {
+	return InternalGetRefs();
+}
+
+const Type & bhkShapePhantom::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["bhkShapePhantom"] = bhkShapePhantom::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 * bhkShapePhantom::Create() {
+	return new bhkShapePhantom;
+}
+
-- 
GitLab