diff --git a/NIF_IO.cpp b/NIF_IO.cpp
index 9b03afa780b55b9a9176dbb0d69bf5f0a83f5185..5403d712e2abe9c93ba7717d57ce9a7b457991bb 100644
--- a/NIF_IO.cpp
+++ b/NIF_IO.cpp
@@ -460,154 +460,6 @@ void NifStream( Quaternion const & val, ostream& out, uint version ) {
 	WriteFloat( val.z, out );
 };
 
-//--Enums--//
-
-//TexType
-void NifStream( TexType & val, istream& in, uint version ) { val = TexType(ReadUInt( in )); };
-void NifStream( TexType const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, TexType const & val ) {
-	switch ( val ) {
-		case BASE_MAP: return out << "BASE_MAP";
-		case DARK_MAP: return out << "DARK_MAP";
-		case DETAIL_MAP: return out << "DETAIL_MAP";
-		case GLOSS_MAP: return out << "GLOSS_MAP";
-		case GLOW_MAP: return out << "GLOW_MAP";
-		case BUMP_MAP: return out << "BUMP_MAP";
-		case DECAL_0_MAP: return out << "DECAL_0_MAP";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//ApplyMode
-void NifStream( ApplyMode & val, istream& in, uint version ) { val = ApplyMode(ReadUInt( in )); };
-void NifStream( ApplyMode const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, ApplyMode const & val ) {
-	switch ( val ) {
-		case APPLY_REPLACE: return out << "APPLY_REPLACE";
-		case APPLY_DECAL: return out << "APPLY_DECAL";
-		case APPLY_MODULATE: return out << "APPLY_MODULATE";
-		case APPLY_HILIGHT: return out << "APPLY_HILIGHT";
-		case APPLY_HILIGHT2: return out << "APPLY_HILIGHT2";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//TexClampMode
-void NifStream( TexClampMode & val, istream& in, uint version ) { val = TexClampMode(ReadUInt( in )); };
-void NifStream( TexClampMode const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, TexClampMode const & val ) {
-	switch ( val ) {
-		case CLAMP_S_CLAMP_T: return out << "CLAMP_S_CLAMP_T";
-		case CLAMP_S_WRAP_T: return out << "CLAMP_S_WRAP_T";
-		case WRAP_S_CLAMP_T: return out << "WRAP_S_CLAMP_T";
-		case WRAP_S_WRAP_T: return out << "WRAP_S_WRAP_T";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//TexFilterMode
-void NifStream( TexFilterMode & val, istream& in, uint version ) { val = TexFilterMode(ReadUInt( in )); };
-void NifStream( TexFilterMode const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, TexFilterMode const & val ) {
-	switch ( val ) {
-		case FILTER_NEAREST: return out << "FILTER_NEAREST";
-		case FILTER_BILERP: return out << "FILTER_BILERP";
-		case FILTER_TRILERP: return out << "FILTER_TRILERP";
-		case FILTER_NEAREST_MIPNEAREST: return out << "FILTER_NEAREST_MIPNEAREST";
-		case FILTER_NEAREST_MIPLERP: return out << "FILTER_NEAREST_MIPLERP";
-		case FILTER_BILERP_MIPNEAREST: return out << "FILTER_BILERP_MIPNEAREST";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//AlphaFormat
-void NifStream( AlphaFormat & val, istream& in, uint version ) { val = AlphaFormat(ReadUInt( in )); };
-void NifStream( AlphaFormat const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, AlphaFormat const & val ) {
-	switch ( val ) {
-		case ALPHA_NONE: return out << "ALPHA_NONE";
-		case ALPHA_BINARY: return out << "ALPHA_BINARY";
-		case ALPHA_SMOOTH: return out << "ALPHA_SMOOTH";
-		case ALPHA_DEFAULT: return out << "ALPHA_DEFAULT";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//KeyType
-void NifStream( KeyType & val, istream& in, uint version ) { val = KeyType(ReadUInt( in )); };
-void NifStream( KeyType const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, KeyType const & val ) {
-	switch ( val ) {
-		case LINEAR_KEY: return out << "LINEAR_KEY";
-		case QUADRATIC_KEY: return out << "QUADRATIC_KEY";
-		case TBC_KEY: return out << "TBC_KEY";
-		case XYZ_ROTATION_KEY: return out << "XYZ_ROTATION_KEY";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//PixelFormat
-void NifStream( PixelFormat & val, istream& in, uint version ) { val = PixelFormat(ReadUInt( in )); };
-void NifStream( PixelFormat const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, PixelFormat const & val ) {
-	switch ( val ) {
-		case PX_FMT_RGB8: return out << "PX_FMT_RGB8";
-		case PX_FMT_RGBA8: return out << "PX_FMT_RGBA8";
-		case PX_FMT_PAL8: return out << "PX_FMT_PAL8";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//MipMapFormat
-void NifStream( MipMapFormat & val, istream& in, uint version ) { val = MipMapFormat(ReadUInt( in )); };
-void NifStream( MipMapFormat const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, MipMapFormat const & val ) {
-	switch ( val ) {
-		case MIP_FMT_NO: return out << "MIP_FMT_NO";
-		case MIP_FMT_YES: return out << "MIP_FMT_YES";
-		case MIP_FMT_DEFAULT: return out << "MIP_FMT_DEFAULT";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//PixelLayout
-void NifStream( PixelLayout & val, istream& in, uint version ) { val = PixelLayout(ReadUInt( in )); };
-void NifStream( PixelLayout const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, PixelLayout const & val ) {
-	switch ( val ) {
-		case PIX_LAY_PALETTISED: return out << "PIX_LAY_PALETTISED";
-		case PIX_LAY_HIGH_COLOR_16: return out << "PIX_LAY_HIGH_COLOR_16";
-		case PIX_LAY_TRUE_COLOR_32: return out << "PIX_LAY_TRUE_COLOR_32";
-		case PIX_LAY_COMPRESSED: return out << "PIX_LAY_COMPRESSED";
-		case PIX_LAY_BUMPMAP: return out << "PIX_LAY_BUMPMAP";
-		case PIX_LAY_DEFAULT: return out << "PIX_LAY_DEFAULT";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//VertMode
-void NifStream( VertMode & val, istream& in, uint version ) { val = VertMode(ReadUInt( in )); };
-void NifStream( VertMode const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, VertMode const & val ) {
-	switch ( val ) {
-		case VERT_MODE_SRC_IGNORE: return out << "VERT_MODE_SRC_IGNORE";
-		case VERT_MODE_SRC_EMISSIVE: return out << "VERT_MODE_SRC_EMISSIVE";
-		case VERT_MODE_SRC_AMB_DIF: return out << "VERT_MODE_SRC_AMB_DIF";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
-//LightMode
-void NifStream( LightMode & val, istream& in, uint version ) { val = LightMode(ReadUInt( in )); };
-void NifStream( LightMode const & val, ostream& out, uint version ) { WriteUInt( val, out ); }
-ostream & operator<<( ostream & out, LightMode const & val ) {
-	switch ( val ) {
-		case LIGHT_MODE_EMISSIVE: return out << "LIGHT_MODE_EMISSIVE";
-		case LIGHT_MODE_EMI_AMB_DIF: return out << "LIGHT_MODE_EMI_AMB_DIF";
-		default: return out << "Invalid Value! - " << uint(val);
-	};
-}
-
 //The HexString function creates a formatted hex display of the given data for use in printing
 //a debug string for information that is not understood
 string HexString( const byte * src, uint len ) {
diff --git a/NIF_IO.h b/NIF_IO.h
index 351f06c47c2a51b462c46d0e47a96a8c4b592c6b..34162826a5b7431686e93d8a88391a91b3ed83fe 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -10,6 +10,7 @@ All rights reserved.  Please see niflib.h for licence. */
 #include <vector>
 #include "Key.h"
 #include "nif_basic_types.h"
+#include "nif_enums.h"
 #include "nif_math.h"
 #include "nif_versions.h"
 namespace Niflib {
@@ -19,12 +20,6 @@ using namespace std;
 #define NULL 0
 #endif
 
-//--Non-mathematical Basic Types--//
-
-typedef unsigned char	byte;
-typedef unsigned short	ushort;
-typedef unsigned int	uint;
-
 //! NVector Traits:  Class overridable alloc/release methods
 template<typename T>
 class array_Traits
@@ -288,63 +283,6 @@ void NifStream( Color4 const & val, ostream& out, uint version = 0  );
 void NifStream( Quaternion & val, istream& in, uint version = 0 );
 void NifStream( Quaternion const & val, ostream& out, uint version = 0  );
 
-//--Enums--//
-
-//TexType
-void NifStream( TexType & val, istream& in, uint version = 0 );
-void NifStream( TexType const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, TexType const & val );
-
-//ApplyMode
-void NifStream( ApplyMode & val, istream& in, uint version = 0 );
-void NifStream( ApplyMode const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, ApplyMode const & val );
-
-//TexClampMode
-void NifStream( TexClampMode & val, istream& in, uint version = 0 );
-void NifStream( TexClampMode const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, TexClampMode const & val );
-
-//TexFilterMode
-void NifStream( TexFilterMode & val, istream& in, uint version = 0 );
-void NifStream( TexFilterMode const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, TexFilterMode const & val );
-
-//AlphaFormat
-void NifStream( AlphaFormat & val, istream& in, uint version = 0 );
-void NifStream( AlphaFormat const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, AlphaFormat const & val );
-
-//KeyType
-void NifStream( KeyType & val, istream& in, uint version = 0 );
-void NifStream( KeyType const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, KeyType const & val );
-
-//PixelFormat
-void NifStream( PixelFormat & val, istream& in, uint version = 0 );
-void NifStream( PixelFormat const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, PixelFormat const & val );
-
-//MipMapFormat
-void NifStream( MipMapFormat & val, istream& in, uint version = 0 );
-void NifStream( MipMapFormat const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, MipMapFormat const & val );
-
-//PixelLayout
-void NifStream( PixelLayout & val, istream& in, uint version = 0 );
-void NifStream( PixelLayout const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, PixelLayout const & val );
-
-//VertMode
-void NifStream( VertMode & val, istream& in, uint version = 0 );
-void NifStream( VertMode const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, VertMode const & val );
-
-//LightMode
-void NifStream( LightMode & val, istream& in, uint version = 0 );
-void NifStream( LightMode const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, LightMode const & val );
-
 //HeaderString
 void NifStream( HeaderString & val, istream& in, uint version = 0 );
 void NifStream( HeaderString const & val, ostream& out, uint version = 0  );
@@ -358,8 +296,6 @@ ostream & operator<<( ostream & out, ShortString const & val );
 //--Templates--//
 
 void NifStream( Key<Quaternion> & key, istream& file, uint version, KeyType type );
-
-
 void NifStream( Key<Quaternion> const & key, ostream& file, uint version,  KeyType type );
 
 //Key<T>
diff --git a/gen/obj_defines.h b/gen/obj_defines.h
index d30da23f22db78bc0d729e0715bb1d1fdb7e1b5d..4ab6904d5bb5abb790d3846a10cb4122fa7a0237 100644
--- a/gen/obj_defines.h
+++ b/gen/obj_defines.h
@@ -241,14 +241,14 @@ InternalFixLinks( objects, link_stack, version, user_version ); \
 return InternalGetRefs(); \
 
 #define BHK_SPHERE_REP_SHAPE_MEMBERS \
-uint material; \
+HavokMaterial material; \
 
 #define BHK_SPHERE_REP_SHAPE_INCLUDE "bhkShape.h" \
 
 #define BHK_SPHERE_REP_SHAPE_PARENT bhkShape \
 
 #define BHK_SPHERE_REP_SHAPE_CONSTRUCT \
- : material((uint)0) \
+ : material((HavokMaterial)0) \
 
 #define BHK_SPHERE_REP_SHAPE_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -313,14 +313,14 @@ return InternalGetRefs(); \
 
 #define BHK_ENTITY_MEMBERS \
 Ref<bhkShape > shape; \
-uint layer; \
+OblivionLayer layer; \
 
 #define BHK_ENTITY_INCLUDE "bhkWorldObject.h" \
 
 #define BHK_ENTITY_PARENT bhkWorldObject \
 
 #define BHK_ENTITY_CONSTRUCT \
- : shape(NULL), layer((uint)0) \
+ : shape(NULL), layer((OblivionLayer)0) \
 
 #define BHK_ENTITY_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -1128,7 +1128,7 @@ return InternalGetRefs(); \
 #define BHK_LIST_SHAPE_MEMBERS \
 mutable uint numSubShapes; \
 vector<Ref<bhkShape > > subShapes; \
-uint material; \
+HavokMaterial material; \
 array<float,6> unknownFloats; \
 mutable uint numUnknownInts; \
 vector<uint > unknownInts; \
@@ -1138,7 +1138,7 @@ vector<uint > unknownInts; \
 #define BHK_LIST_SHAPE_PARENT AbhkShapeCollection \
 
 #define BHK_LIST_SHAPE_CONSTRUCT \
- : numSubShapes((uint)0), material((uint)0), numUnknownInts((uint)0) \
+ : numSubShapes((uint)0), material((HavokMaterial)0), numUnknownInts((uint)0) \
 
 #define BHK_LIST_SHAPE_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -1190,7 +1190,7 @@ return InternalGetRefs(); \
 
 #define BHK_MOPP_BV_TREE_SHAPE_MEMBERS \
 Ref<bhkShape > shape; \
-uint material; \
+HavokMaterial material; \
 array<byte,8> unknownBytes1; \
 float unknownFloat; \
 mutable uint numUnknownBytes2; \
@@ -1203,7 +1203,7 @@ float unknownFloat2; \
 #define BHK_MOPP_BV_TREE_SHAPE_PARENT bhkShape \
 
 #define BHK_MOPP_BV_TREE_SHAPE_CONSTRUCT \
- : shape(NULL), material((uint)0), unknownFloat(0.0f), numUnknownBytes2((uint)0), unknownFloat2(0.0f) \
+ : shape(NULL), material((HavokMaterial)0), unknownFloat(0.0f), numUnknownBytes2((uint)0), unknownFloat2(0.0f) \
 
 #define BHK_MOPP_BV_TREE_SHAPE_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -1364,7 +1364,7 @@ return InternalGetRefs(); \
 #define BHK_RIGID_BODY_MEMBERS \
 array<float,5> unknownFloats1; \
 array<ushort,4> unknownShorts1; \
-uint layerCopy; \
+OblivionLayer layerCopy; \
 array<ushort,6> unknownShorts2; \
 Vector3 translation; \
 float unknownFloat00; \
@@ -1387,7 +1387,7 @@ float penetrationDepth; \
 byte motionSystem; \
 byte unknownByte1; \
 byte unknownByte2; \
-byte qualityType; \
+MotionQuality qualityType; \
 uint unknownInt6; \
 uint unknownInt7; \
 uint unknownInt8; \
@@ -1399,7 +1399,7 @@ vector<Ref<AbhkConstraint > > constraints; \
 #define BHK_RIGID_BODY_PARENT bhkEntity \
 
 #define BHK_RIGID_BODY_CONSTRUCT \
- : layerCopy((uint)0), unknownFloat00(0.0f), unknownFloat01(0.0f), unknownFloat02(0.0f), unknownFloat03(0.0f), mass(0.0f), linearDamping(0.0f), angularDamping(0.0f), friction(0.0f), restitution(0.0f), maxLinearVelocity(0.0f), maxAngularVelocity(31.415926535f), penetrationDepth(0.0f), motionSystem((byte)0), unknownByte1((byte)0), unknownByte2((byte)0), qualityType((byte)0), unknownInt6((uint)0), unknownInt7((uint)0), unknownInt8((uint)0), numConstraints((uint)0) \
+ : layerCopy((OblivionLayer)0), unknownFloat00(0.0f), unknownFloat01(0.0f), unknownFloat02(0.0f), unknownFloat03(0.0f), mass(0.0f), linearDamping(0.0f), angularDamping(0.0f), friction(0.0f), restitution(0.0f), maxLinearVelocity(0.0f), maxAngularVelocity(31.415926535f), penetrationDepth(0.0f), motionSystem((byte)0), unknownByte1((byte)0), unknownByte2((byte)0), qualityType((MotionQuality)0), unknownInt6((uint)0), unknownInt7((uint)0), unknownInt8((uint)0), numConstraints((uint)0) \
 
 #define BHK_RIGID_BODY_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -2414,7 +2414,7 @@ mutable uint numControlledBlocks; \
 uint unknownInt1; \
 vector<ControllerLink > controlledBlocks; \
 float weight; \
-uint cycleType; \
+CycleType cycleType; \
 uint unknownInt0; \
 float frequency; \
 float startTime; \
@@ -2430,7 +2430,7 @@ Ref<NiStringPalette > stringPalette; \
 #define NI_CONTROLLER_SEQUENCE_PARENT NiObject \
 
 #define NI_CONTROLLER_SEQUENCE_CONSTRUCT \
- : textKeys(NULL), numControlledBlocks((uint)0), unknownInt1((uint)0), weight(1.0f), cycleType((uint)0), unknownInt0((uint)0), frequency(0.0f), startTime(0.0f), stopTime(0.0f), unknownFloat2(0.0f), unknownByte((byte)0), manager(NULL), stringPalette(NULL) \
+ : textKeys(NULL), numControlledBlocks((uint)0), unknownInt1((uint)0), weight(1.0f), cycleType((CycleType)0), unknownInt0((uint)0), frequency(0.0f), startTime(0.0f), stopTime(0.0f), unknownFloat2(0.0f), unknownByte((byte)0), manager(NULL), stringPalette(NULL) \
 
 #define NI_CONTROLLER_SEQUENCE_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -2740,7 +2740,7 @@ return InternalGetRefs(); \
 #define NI_GRAVITY_MEMBERS \
 float unknownFloat1; \
 float force; \
-uint type; \
+FieldType type; \
 Vector3 position; \
 Vector3 direction; \
 
@@ -2749,7 +2749,7 @@ Vector3 direction; \
 #define NI_GRAVITY_PARENT AParticleModifier \
 
 #define NI_GRAVITY_CONSTRUCT \
- : unknownFloat1(0.0f), force(0.0f), type((uint)0) \
+ : unknownFloat1(0.0f), force(0.0f), type((FieldType)0) \
 
 #define NI_GRAVITY_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -3289,14 +3289,14 @@ InternalFixLinks( objects, link_stack, version, user_version ); \
 return InternalGetRefs(); \
 
 #define NI_BILLBOARD_NODE_MEMBERS \
-ushort billboardMode; \
+BillboardMode billboardMode; \
 
 #define NI_BILLBOARD_NODE_INCLUDE "NiNode.h" \
 
 #define NI_BILLBOARD_NODE_PARENT NiNode \
 
 #define NI_BILLBOARD_NODE_CONSTRUCT \
- : billboardMode((ushort)0) \
+ : billboardMode((BillboardMode)0) \
 
 #define NI_BILLBOARD_NODE_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -4447,7 +4447,7 @@ NiNode * gravityObject; \
 Vector3 gravityAxis; \
 float decay; \
 float strength; \
-uint forceType; \
+ForceType forceType; \
 float turbulence; \
 float turbulenceScale; \
 
@@ -4456,7 +4456,7 @@ float turbulenceScale; \
 #define NI_P_SYS_GRAVITY_MODIFIER_PARENT NiPSysModifier \
 
 #define NI_P_SYS_GRAVITY_MODIFIER_CONSTRUCT \
- : gravityObject(NULL), decay(0.0f), strength(0.0f), forceType((uint)0), turbulence(0.0f), turbulenceScale(1.0f) \
+ : gravityObject(NULL), decay(0.0f), strength(0.0f), forceType((ForceType)0), turbulence(0.0f), turbulenceScale(1.0f) \
 
 #define NI_P_SYS_GRAVITY_MODIFIER_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -5283,7 +5283,7 @@ return InternalGetRefs(); \
 Matrix33 modelProjectionMatrix; \
 Vector3 modelProjectionTransform; \
 uint textureFiltering; \
-uint textureClamping; \
+TexClampMode textureClamping; \
 uint textureType; \
 uint coordinateGenerationType; \
 Ref<NiSourceTexture > sourceTexture; \
@@ -5299,7 +5299,7 @@ ushort unknownShort; \
 #define NI_TEXTURE_EFFECT_PARENT NiDynamicEffect \
 
 #define NI_TEXTURE_EFFECT_CONSTRUCT \
- : textureFiltering((uint)0), textureClamping((uint)0), textureType((uint)0), coordinateGenerationType((uint)0), sourceTexture(NULL), clippingPlane((byte)0), unknownFloat(0.0f), ps2L((ushort)0), ps2K((ushort)0), unknownShort((ushort)0) \
+ : textureFiltering((uint)0), textureClamping((TexClampMode)0), textureType((uint)0), coordinateGenerationType((uint)0), sourceTexture(NULL), clippingPlane((byte)0), unknownFloat(0.0f), ps2L((ushort)0), ps2K((ushort)0), unknownShort((ushort)0) \
 
 #define NI_TEXTURE_EFFECT_READ \
 InternalRead( in, link_stack, version, user_version ); \
@@ -5318,7 +5318,7 @@ return InternalGetRefs(); \
 
 #define NI_TEXTURE_TRANSFORM_CONTROLLER_MEMBERS \
 byte unknown2; \
-uint textureSlot; \
+TexType textureSlot; \
 uint operation; \
 Ref<NiFloatData > data; \
 
@@ -5327,7 +5327,7 @@ Ref<NiFloatData > data; \
 #define NI_TEXTURE_TRANSFORM_CONTROLLER_PARENT NiSingleInterpolatorController \
 
 #define NI_TEXTURE_TRANSFORM_CONTROLLER_CONSTRUCT \
- : unknown2((byte)0), textureSlot((uint)0), operation((uint)0), data(NULL) \
+ : unknown2((byte)0), textureSlot((TexType)0), operation((uint)0), data(NULL) \
 
 #define NI_TEXTURE_TRANSFORM_CONTROLLER_READ \
 InternalRead( in, link_stack, version, user_version ); \
diff --git a/nif_basic_types.h b/nif_basic_types.h
index 54ea8b411541fe9835bf1c9f38896f9ec63ae4ab..10b1b7c8fdfc07ad788a160884b84cace14e440c 100644
--- a/nif_basic_types.h
+++ b/nif_basic_types.h
@@ -16,112 +16,13 @@ struct ShortString {
 	string str;
 };
 
-//TODO:  This is temporary to make it compile.  Should eventually be adjusted to display 1's and 0's insted of as an int.
-typedef unsigned short Flags;
-
-/*! Lists the basic texture types availiable from the ITexturingProperty interface*/
-enum TexType {
-	BASE_MAP = 0, /*!< The basic texture used by most meshes. */ 
-	DARK_MAP = 1, /*!< Used to darken the model with false lighting. */ 
-	DETAIL_MAP = 2, /*!< Combined with base map for added detail. */ 
-	GLOSS_MAP = 3, /*!< Allows the glossyness of an object to differ across its surface. */ 
-	GLOW_MAP = 4, /*!< Creates a glowing effect. */ 
-	BUMP_MAP = 5, /*!< Used to make the object appear to have more detail than it really does. */ 
-	DECAL_0_MAP = 6, /*!< For placing images on the object like stickers. */ 
-	DECAL_1_MAP = 7 /*!< For placing images on the object like stickers. */ 
-};
+//--Non-mathematical Basic Types--//
 
-/*! Specifies the availiable texture apply modes.  Affects the way colors are composed together. */
-enum ApplyMode {
-   APPLY_REPLACE = 0, /*!< Replaces existing color */ 
-   APPLY_DECAL = 1, /*!< For placing images on the object like stickers. */ 
-   APPLY_MODULATE = 2, /*!< Modulates existing color. */ 
-   APPLY_HILIGHT = 3, /*!< PS2 Only */
-   APPLY_HILIGHT2 = 4 /*!< PS2 Only */
-};
-
-/*! Specifies the availiable texture clamp modes.  That is, the behavior of pixels outside the range of the texture.*/
-enum TexClampMode {
-	CLAMP_S_CLAMP_T = 0, /*!< Clamp in both directions. */ 
-	CLAMP_S_WRAP_T = 1, /*!< Clamp in the S direction but wrap in the T direction. */ 
-	WRAP_S_CLAMP_T = 2, /*!< Wrap in the S direction but clamp in the T direction. */ 
-	WRAP_S_WRAP_T = 3 /*!< Wrap in both directions. */ 
-};
-
-/*! Specifies the availiable texture filter modes.  That is, the way pixels within a texture are blended together when textures are displayed on the screen at a size other than their original dimentions.*/
-enum TexFilterMode {
-	FILTER_NEAREST = 0, /*!< Simply uses the nearest pixel.  Very grainy. */ 
-	FILTER_BILERP = 1, /*!< Uses bilinear filtering. */ 
-	FILTER_TRILERP = 2, /*!< Uses trilinear filtering. */ 
-	FILTER_NEAREST_MIPNEAREST = 3, /*!< Uses the nearest pixel from the mipmap that is closest to the display size. */ 
-	FILTER_NEAREST_MIPLERP = 4, /*!< Blends the two mipmaps closest to the display size linearly, and then uses the nearest pixel from the result. */ 
-	FILTER_BILERP_MIPNEAREST = 5, /*!< Uses the closest mipmap to the display size and then uses bilinear filtering on the pixels. */ 
-};
-
-/*! Specifies the availiable alpha formats.  That is, the type of alpha blending (transparency) that will be used on a particular texture.*/
-enum AlphaFormat {
-   ALPHA_NONE = 0, /*!< No alpha blending, the texture is fully opaque */ 
-   ALPHA_BINARY = 1, /*!< Texture is either fully transparent or fully opaque.  There are no partially transparent areas. */ 
-   ALPHA_SMOOTH = 2, /*!< Full range of alpha values can be used from fully transparent to fully opaque including all partially transparent values in between. */ 
-   ALPHA_DEFAULT = 3 /*!< Use default setting. */ 
-};
-
-/*!
- * This enum contains all the animation key types used by Niflib.
- */
-enum KeyType {
-	LINEAR_KEY = 1, /*!< Use linear interpolation. */ 
-	QUADRATIC_KEY = 2, /*!< Use quadratic interpolation.  Forward and back tangents will be stored.*/ 
-	TBC_KEY = 3, /*!< Use Tension Bias Continuity interpolation.  Tension, bias, and continuity will be stored.*/ 
-	XYZ_ROTATION_KEY = 4 /*!< For use only with rotation data.  Separate X, Y, and Z keys will be stored instead of using quaternions. */ 
-};
-
-/*!
- * Specifies the pixel format used by the NiPixelData object to store a texture.
- */
-enum PixelFormat {
-	PX_FMT_RGB8 = 0, /*!< 24-bit color: uses 8 bit to store each red, blue, and green component. */
-	PX_FMT_RGBA8 = 1, /*!< 32-bit color with alpha: uses 8 bits to store each red, blue, green, and alpha component. */
-	PX_FMT_PAL8 = 2 /*!< 8-bit palette index: uses 8 bits to store an index into the palette stored in a NiPallete block. */
-};
-
-/*!
- * Specifies the mip map format of a texture.
- */
-enum MipMapFormat {
-	MIP_FMT_NO = 0, /*!< Texture does not use mip maps. */
-	MIP_FMT_YES = 1,/*!< Texture uses mip maps. */
-	MIP_FMT_DEFAULT = 2, /*!< Use default setting. */
-};
-
-/*!
- * Specifies the pixel layout of a texture.  That is, the format of the image data.
- */
-enum PixelLayout {
-	PIX_LAY_PALETTISED = 0, /*!< Texture is in 8-bit paletized format. */
-	PIX_LAY_HIGH_COLOR_16 = 1, /*!< Texture is in 16-bit high color format. */
-	PIX_LAY_TRUE_COLOR_32 = 2, /*!< Texture is in 32-bit true color format. */
-	PIX_LAY_COMPRESSED = 3, /*!< Texture is compressed. */
-	PIX_LAY_BUMPMAP = 4, /*!< Texture is a grayscale bump map. */
-	PIX_LAY_DEFAULT = 5 /*!< Use default setting. */
-};
-
-/*!
- * Specifies what type of light is active on the shape.
- */
-enum VertMode {
-	VERT_MODE_SRC_IGNORE = 0, /*!< Source Ignore. */
-	VERT_MODE_SRC_EMISSIVE = 1, /*!< Source Emissive. */
-	VERT_MODE_SRC_AMB_DIF = 2, /*!< Source Ambient/Diffuse. (Default) */
-};
-
-/*!
- * Specifies the light mode.
- */
-enum LightMode {
-	LIGHT_MODE_EMISSIVE = 0, /*!< Emissive. */
-	LIGHT_MODE_EMI_AMB_DIF = 1, /*!< Emissive + Ambient + Diffuse. (Default) */
-};
+typedef unsigned char	byte;
+typedef unsigned short	ushort;
+typedef unsigned int	uint;
 
+//TODO:  This is temporary to make it compile.  Should eventually be adjusted to display 1's and 0's insted of as an int.
+typedef unsigned short Flags;
 }
 #endif
diff --git a/nif_enums.cpp b/nif_enums.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c2087e12af7d5df4beac526870bfb64728d192be
--- /dev/null
+++ b/nif_enums.cpp
@@ -0,0 +1,583 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+
+#include <string>
+#include <iostream>
+#include <strstream>
+#include "nif_enums.h"
+
+#ifndef _countof
+#  define _countof(x) (sizeof(x)/sizeof(x[0]))
+#endif
+
+namespace Niflib {
+
+typedef struct EnumLookupType {
+	uint value;
+	const char *name;
+	const char *desc;
+} EnumLookupType;
+
+static std::string EnumToString(uint value, EnumLookupType *table) {
+	for (EnumLookupType *itr = table; itr->name != NULL; ++itr) {
+		if (itr->value == value) return std::string(itr->name);
+	}
+	std::stringstream sstr;
+	sstr << value;
+	return sstr.str();
+}
+
+static uint StringToEnum(std::string value, EnumLookupType *table) {
+	for (EnumLookupType *itr = table; itr->name != NULL; ++itr) {
+		if (0 == value.compare(itr->name)) return itr->value;
+	}
+	uint retval = 0;
+	std::stringstream sstr(value);
+	sstr >> retval;
+	return retval;
+}
+
+static std::string FlagsToString(uint value, EnumLookupType *table) {
+	std::strstream sstr;
+	for (EnumLookupType *itr = table; itr->name != NULL; ++itr) {
+		if (itr->value && (itr->value & value) == itr->value) {
+			if (sstr.rdbuf()->pcount() > 0) sstr << "|";
+			sstr << itr->name;
+			value ^= itr->value;
+		}
+	}
+	if (value == 0 && sstr.rdbuf()->pcount() == 0) {
+		return EnumToString(value, table);
+	}
+	if (value != 0) sstr << value;
+	return string(sstr.str(), sstr.rdbuf()->pcount());
+}
+
+static uint StringToFlags(std::string value, EnumLookupType *table) {
+	uint retval = 0;
+	std::string::size_type start = 0;
+	while(start < value.length()) {
+		std::string::size_type end = value.find_first_of("|", start);
+		std::string::size_type len = (end == string.npos) ? end : end-start;
+		std::string subval = value.substr(start, len);
+		retval |= StringToEnum(subval, table);
+	}
+	return retval;
+}
+/* Template wrappers around Nif IO routines */
+template <typename T> inline T ReadValue(istream& in);
+template <typename T> inline void WriteValue( T val, ostream& out);
+template <> inline int    ReadValue<int>   (istream& in) { return ReadInt( in ); }
+template <> inline uint   ReadValue<uint>  (istream& in) { return ReadUInt( in ); }
+template <> inline ushort ReadValue<ushort>(istream& in) { return ReadUShort( in ); }
+template <> inline short  ReadValue<short> (istream& in) { return ReadShort( in ); }
+template <> inline byte   ReadValue<byte>  (istream& in) { return ReadByte( in ); }
+template <> inline void WriteValue<int>   ( int val,    ostream& out) { WriteInt( val, out ); }
+template <> inline void WriteValue<uint>  ( uint val,   ostream& out) { WriteUInt( val, out ); }
+template <> inline void WriteValue<ushort>( ushort val, ostream& out) { WriteUShort( val, out ); }
+template <> inline void WriteValue<short> ( short val,  ostream& out) { WriteShort( val, out ); }
+template <> inline void WriteValue<byte>  ( byte val,   ostream& out) { WriteByte( val, out ); }
+
+/*!
+ * ForceType
+ */
+static EnumLookupType ForceTypeTable[] = {
+	{0, "FORCE_PLANAR", "FORCE_PLANAR"},
+	{1, "FORCE_SPHERICAL", "FORCE_SPHERICAL"},
+	{2, "FORCE_UNKNOWN", "FORCE_UNKNOWN"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<ForceType>(ForceType value) {
+	return EnumToString(uint(value), ForceTypeTable);
+}
+
+template <> ForceType StringToEnum<ForceType>(const std::string& value) {
+	return ForceType(StringToEnum(value, ForceTypeTable));
+}
+
+void NifStream( ForceType & val, istream& in, uint version ) { val = ForceType(ReadValue<uint>( in )); }
+void NifStream( ForceType const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, ForceType const & val ) { return out << EnumToString(val); }
+
+/*!
+ * PixelLayout
+ */
+static EnumLookupType PixelLayoutTable[] = {
+	{0, "PIX_LAY_PALETTISED", "Texture is in 8-bit paletized format."},
+	{1, "PIX_LAY_HIGH_COLOR_16", "Texture is in 16-bit high color format."},
+	{2, "PIX_LAY_TRUE_COLOR_32", "Texture is in 32-bit true color format."},
+	{3, "PIX_LAY_COMPRESSED", "Texture is compressed."},
+	{4, "PIX_LAY_BUMPMAP", "Texture is a grayscale bump map."},
+	{5, "PIX_LAY_DEFAULT", "Use default setting."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<PixelLayout>(PixelLayout value) {
+	return EnumToString(uint(value), PixelLayoutTable);
+}
+
+template <> PixelLayout StringToEnum<PixelLayout>(const std::string& value) {
+	return PixelLayout(StringToEnum(value, PixelLayoutTable));
+}
+
+void NifStream( PixelLayout & val, istream& in, uint version ) { val = PixelLayout(ReadValue<uint>( in )); }
+void NifStream( PixelLayout const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, PixelLayout const & val ) { return out << EnumToString(val); }
+
+/*!
+ * LightMode
+ */
+static EnumLookupType LightModeTable[] = {
+	{0, "LIGHT_MODE_EMISSIVE", "Emissive."},
+	{1, "LIGHT_MODE_EMI_AMB_DIF", "Emissive + Ambient + Diffuse. (Default)"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<LightMode>(LightMode value) {
+	return EnumToString(uint(value), LightModeTable);
+}
+
+template <> LightMode StringToEnum<LightMode>(const std::string& value) {
+	return LightMode(StringToEnum(value, LightModeTable));
+}
+
+void NifStream( LightMode & val, istream& in, uint version ) { val = LightMode(ReadValue<uint>( in )); }
+void NifStream( LightMode const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, LightMode const & val ) { return out << EnumToString(val); }
+
+/*!
+ * MipMapFormat
+ */
+static EnumLookupType MipMapFormatTable[] = {
+	{0, "MIP_FMT_NO", "Texture does not use mip maps."},
+	{1, "MIP_FMT_YES", "Texture uses mip maps."},
+	{2, "MIP_FMT_DEFAULT", "Use default setting."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<MipMapFormat>(MipMapFormat value) {
+	return EnumToString(uint(value), MipMapFormatTable);
+}
+
+template <> MipMapFormat StringToEnum<MipMapFormat>(const std::string& value) {
+	return MipMapFormat(StringToEnum(value, MipMapFormatTable));
+}
+
+void NifStream( MipMapFormat & val, istream& in, uint version ) { val = MipMapFormat(ReadValue<uint>( in )); }
+void NifStream( MipMapFormat const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, MipMapFormat const & val ) { return out << EnumToString(val); }
+
+/*!
+ * AlphaFormat
+ */
+static EnumLookupType AlphaFormatTable[] = {
+	{0, "ALPHA_NONE", "No alpha blending; the texture is fully opaque."},
+	{1, "ALPHA_BINARY", "Texture is either fully transparent or fully opaque.  There are no partially transparent areas."},
+	{2, "ALPHA_SMOOTH", "Full range of alpha values can be used from fully transparent to fully opaque including all partially transparent values in between."},
+	{3, "ALPHA_DEFAULT", "Use default setting."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<AlphaFormat>(AlphaFormat value) {
+	return EnumToString(uint(value), AlphaFormatTable);
+}
+
+template <> AlphaFormat StringToEnum<AlphaFormat>(const std::string& value) {
+	return AlphaFormat(StringToEnum(value, AlphaFormatTable));
+}
+
+void NifStream( AlphaFormat & val, istream& in, uint version ) { val = AlphaFormat(ReadValue<uint>( in )); }
+void NifStream( AlphaFormat const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, AlphaFormat const & val ) { return out << EnumToString(val); }
+
+/*!
+ * TexFilterMode
+ */
+static EnumLookupType TexFilterModeTable[] = {
+	{0, "FILTER_NEAREST", "Simply uses the nearest pixel.  Very grainy."},
+	{1, "FILTER_BILERP", "Uses bilinear filtering."},
+	{2, "FILTER_TRILERP", "Uses trilinear filtering."},
+	{3, "FILTER_NEAREST_MIPNEAREST", "Uses the nearest pixel from the mipmap that is closest to the display size."},
+	{4, "FILTER_NEAREST_MIPLERP", "Blends the two mipmaps closest to the display size linearly, and then uses the nearest pixel from the result."},
+	{5, "FILTER_BILERP_MIPNEAREST", "Uses the closest mipmap to the display size and then uses bilinear filtering on the pixels."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<TexFilterMode>(TexFilterMode value) {
+	return EnumToString(uint(value), TexFilterModeTable);
+}
+
+template <> TexFilterMode StringToEnum<TexFilterMode>(const std::string& value) {
+	return TexFilterMode(StringToEnum(value, TexFilterModeTable));
+}
+
+void NifStream( TexFilterMode & val, istream& in, uint version ) { val = TexFilterMode(ReadValue<uint>( in )); }
+void NifStream( TexFilterMode const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, TexFilterMode const & val ) { return out << EnumToString(val); }
+
+/*!
+ * MotionQuality
+ */
+static EnumLookupType MotionQualityTable[] = {
+	{0, "MO_QUAL_MOVING", "Moving"},
+	{1, "MO_QUAL_FIXED", "Fixed"},
+	{2, "MO_QUAL_KEYFRAMED", "Keyframed"},
+	{3, "MO_QUAL_MOVING2", "Moving(?)"},
+	{4, "MO_QUAL_MOVING3", "Moving(?)"},
+	{5, "MO_QUAL_CRITICAL", "Critical"},
+	{6, "MO_QUAL_BULLET", "Bullet"},
+	{7, "MO_QUAL_USER", "User"},
+	{8, "MO_QUAL_NULL", "Null"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<MotionQuality>(MotionQuality value) {
+	return EnumToString(uint(value), MotionQualityTable);
+}
+
+template <> MotionQuality StringToEnum<MotionQuality>(const std::string& value) {
+	return MotionQuality(StringToEnum(value, MotionQualityTable));
+}
+
+void NifStream( MotionQuality & val, istream& in, uint version ) { val = MotionQuality(ReadValue<byte>( in )); }
+void NifStream( MotionQuality const & val, ostream& out, uint version ) { WriteValue<byte>( val, out ); }
+ostream & operator<<( ostream & out, MotionQuality const & val ) { return out << EnumToString(val); }
+
+/*!
+ * OblivionLayer
+ */
+static EnumLookupType OblivionLayerTable[] = {
+	{0, "OL_UNIDENTIFIED", "Unidentified (white)"},
+	{1, "OL_STATIC", "Static (red)"},
+	{2, "OL_ANIM_STATIC", "AnimStatic (magenta)"},
+	{3, "OL_TRANSPARENT", "Transparent (light pink)"},
+	{4, "OL_CLUTTER", "Clutter (light blue)"},
+	{5, "OL_WEAPON", "Weapon (orange)"},
+	{6, "OL_PROJECTILE", "Projectile (light orange)"},
+	{7, "OL_SPELL", "Spell (cyan)"},
+	{8, "OL_BIPED", "Biped (green) Seems to apply to all creatures/NPCs"},
+	{9, "OL_TREES", "Trees (light brown)"},
+	{10, "OL_PROPS", "Props (magenta)"},
+	{11, "OL_WATER", "Water (cyan)"},
+	{12, "OL_TRIGGER", "Trigger (light grey)"},
+	{13, "OL_TERRAIN", "Terrain (light yellow)"},
+	{14, "OL_TRAP", "Trap (light grey)"},
+	{15, "OL_NONCOLLIDABLE", "NonCollidable (white)"},
+	{16, "OL_CLOUD_TRAP", "CloudTrap (greenish grey)"},
+	{17, "OL_GROUND", "Ground (none)"},
+	{18, "OL_PORTAL", "Portal (green)"},
+	{19, "OL_STAIRS", "Stairs (white)"},
+	{20, "OL_CHAR_CONTROLLER", "CharController (yellow)"},
+	{21, "OL_AVOID_BOX", "AvoidBox (dark yellow)"},
+	{22, "OL_UNKNOWN1", "? (white)"},
+	{23, "OL_UNKNOWN2", "? (white)"},
+	{24, "OL_CAMERA_PICK", "CameraPick (white)"},
+	{25, "OL_ITEM_PICK", "ItemPick (white)"},
+	{26, "OL_LINE_OF_SIGHT", "LineOfSight (white)"},
+	{27, "OL_PATH_PICK", "PathPick (white)"},
+	{28, "OL_CUSTOM_PICK_1", "CustomPick1 (white)"},
+	{29, "OL_CUSTOM_PICK_2", "CustomPick2 (white)"},
+	{30, "OL_SPELL_EXPLOSION", "SpellExplosion (white)"},
+	{31, "OL_DROPPING_PICK", "DroppingPick (white)"},
+	{32, "OL_OTHER", "Other (white)"},
+	{33, "OL_HEAD", "Head"},
+	{34, "OL_BODY", "Body"},
+	{35, "OL_SPINE1", "Spine1"},
+	{36, "OL_SPINE2", "Spine2"},
+	{37, "OL_L_UPPER_ARM", "LUpperArm"},
+	{38, "OL_L_FOREARM", "LForeArm"},
+	{39, "OL_L_HAND", "LHand"},
+	{40, "OL_L_THIGH", "LThigh"},
+	{41, "OL_L_CALF", "LCalf"},
+	{42, "OL_L_FOOT", "LFoot"},
+	{43, "OL_R_UPPER_ARM", "RUpperArm"},
+	{44, "OL_R_FOREARM", "RForeArm"},
+	{45, "OL_R_HAND", "RHand"},
+	{46, "OL_R_THIGH", "RThigh"},
+	{47, "OL_R_CALF", "RCalf"},
+	{48, "OL_R_FOOT", "RFoot"},
+	{49, "OL_TAIL", "Tail"},
+	{50, "OL_SIDE_WEAPON", "SideWeapon"},
+	{51, "OL_SHEILD", "Shield"},
+	{52, "OL_QUIVER", "Quiver"},
+	{53, "OL_BACK_WEAPON", "BackWeapon"},
+	{54, "OL_BACK_WEAPON2", "BackWeapon (?)"},
+	{55, "OL_PONYTAIL", "PonyTail"},
+	{56, "OL_WING", "Wing"},
+	{57, "OL_NULL", "Null"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<OblivionLayer>(OblivionLayer value) {
+	return EnumToString(uint(value), OblivionLayerTable);
+}
+
+template <> OblivionLayer StringToEnum<OblivionLayer>(const std::string& value) {
+	return OblivionLayer(StringToEnum(value, OblivionLayerTable));
+}
+
+void NifStream( OblivionLayer & val, istream& in, uint version ) { val = OblivionLayer(ReadValue<uint>( in )); }
+void NifStream( OblivionLayer const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, OblivionLayer const & val ) { return out << EnumToString(val); }
+
+/*!
+ * KeyType
+ */
+static EnumLookupType KeyTypeTable[] = {
+	{1, "LINEAR_KEY", "Use linear interpolation."},
+	{2, "QUADRATIC_KEY", "Use quadratic interpolation.  Forward and back tangents will be stored."},
+	{3, "TBC_KEY", "Use Tension Bias Continuity interpolation.  Tension, bias, and continuity will be stored."},
+	{4, "XYZ_ROTATION_KEY", "For use only with rotation data.  Separate X, Y, and Z keys will be stored instead of using quaternions."},
+	{5, "UNKNOWN_KEY", "Unknown.  Step function?"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<KeyType>(KeyType value) {
+	return EnumToString(uint(value), KeyTypeTable);
+}
+
+template <> KeyType StringToEnum<KeyType>(const std::string& value) {
+	return KeyType(StringToEnum(value, KeyTypeTable));
+}
+
+void NifStream( KeyType & val, istream& in, uint version ) { val = KeyType(ReadValue<uint>( in )); }
+void NifStream( KeyType const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, KeyType const & val ) { return out << EnumToString(val); }
+
+/*!
+ * VertMode
+ */
+static EnumLookupType VertModeTable[] = {
+	{0, "VERT_MODE_SRC_IGNORE", "Source Ignore."},
+	{1, "VERT_MODE_SRC_EMISSIVE", "Source Emissive."},
+	{2, "VERT_MODE_SRC_AMB_DIF", "Source Ambient/Diffuse. (Default)"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<VertMode>(VertMode value) {
+	return EnumToString(uint(value), VertModeTable);
+}
+
+template <> VertMode StringToEnum<VertMode>(const std::string& value) {
+	return VertMode(StringToEnum(value, VertModeTable));
+}
+
+void NifStream( VertMode & val, istream& in, uint version ) { val = VertMode(ReadValue<uint>( in )); }
+void NifStream( VertMode const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, VertMode const & val ) { return out << EnumToString(val); }
+
+/*!
+ * HavokMaterial
+ */
+static EnumLookupType HavokMaterialTable[] = {
+	{0, "HAV_MAT_STONE", "Stone"},
+	{1, "HAV_MAT_CLOTH", "Cloth"},
+	{2, "HAV_MAT_DIRT", "Dirt"},
+	{3, "HAV_MAT_GLASS", "Glass"},
+	{4, "HAV_MAT_GRASS", "Grass"},
+	{5, "HAV_MAT_METAL", "Metal"},
+	{6, "HAV_MAT_ORGANIC", "Organic"},
+	{7, "HAV_MAT_SKIN", "Skin"},
+	{8, "HAV_MAT_WATER", "Water"},
+	{9, "HAV_MAT_WOOD", "Wood"},
+	{10, "HAV_MAT_HEAVY_STONE", "Heavy Stone"},
+	{11, "HAV_MAT_HEAVY_METAL", "Heavy Metal"},
+	{12, "HAV_MAT_HEAVY_WOOD", "Heavy Wood"},
+	{13, "HAV_MAT_CHAIN", "Chain"},
+	{14, "HAV_MAT_SNOW", "Snow"},
+	{15, "HAV_MAT_STONE_STAIRS", "Stone Stairs"},
+	{16, "HAV_MAT_CLOTH_STAIRS", "Cloth Stairs"},
+	{17, "HAV_MAT_DIRT_STAIRS", "Dirt Stairs"},
+	{18, "HAV_MAT_GLASS_STAIRS", "Glass Stairs"},
+	{19, "HAV_MAT_GRASS_STAIRS", "Grass Stairs"},
+	{20, "HAV_MAT_METAL_STAIRS", "Metal Stairs"},
+	{21, "HAV_MAT_ORGANIC_STAIRS", "Organic Stairs"},
+	{22, "HAV_MAT_SKIN_STAIRS", "Skin Stairs"},
+	{23, "HAV_MAT_WATER_STAIRS", "Water Stairs"},
+	{24, "HAV_MAT_WOOD_STAIRS", "Wood Stairs"},
+	{25, "HAV_MAT_HEAVY_STONE_STAIRS", "Heavy Stone Stairs"},
+	{26, "HAV_MAT_HEAVY_METAL_STAIRS", "Heavy Metal Stairs"},
+	{27, "HAV_MAT_HEAVY_WOOD_STAIRS", "Heavy Wood Stairs"},
+	{28, "HAV_MAT_CHAIN_STAIRS", "Chain Stairs"},
+	{29, "HAV_MAT_SNOW_STAIRS", "Snow Stairs"},
+	{30, "HAV_MAT_ELEVATOR", "Elevator"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<HavokMaterial>(HavokMaterial value) {
+	return EnumToString(uint(value), HavokMaterialTable);
+}
+
+template <> HavokMaterial StringToEnum<HavokMaterial>(const std::string& value) {
+	return HavokMaterial(StringToEnum(value, HavokMaterialTable));
+}
+
+void NifStream( HavokMaterial & val, istream& in, uint version ) { val = HavokMaterial(ReadValue<uint>( in )); }
+void NifStream( HavokMaterial const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, HavokMaterial const & val ) { return out << EnumToString(val); }
+
+/*!
+ * PixelFormat
+ */
+static EnumLookupType PixelFormatTable[] = {
+	{0, "PX_FMT_RGB8", "24-bit color: uses 8 bit to store each red, blue, and green component."},
+	{1, "PX_FMT_RGBA8", "32-bit color with alpha: uses 8 bits to store each red, blue, green, and alpha component."},
+	{2, "PX_FMT_PAL8", "8-bit palette index: uses 8 bits to store an index into the palette stored in a NiPallete object."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<PixelFormat>(PixelFormat value) {
+	return EnumToString(uint(value), PixelFormatTable);
+}
+
+template <> PixelFormat StringToEnum<PixelFormat>(const std::string& value) {
+	return PixelFormat(StringToEnum(value, PixelFormatTable));
+}
+
+void NifStream( PixelFormat & val, istream& in, uint version ) { val = PixelFormat(ReadValue<uint>( in )); }
+void NifStream( PixelFormat const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, PixelFormat const & val ) { return out << EnumToString(val); }
+
+/*!
+ * CycleType
+ */
+static EnumLookupType CycleTypeTable[] = {
+	{0, "CYCLE_LOOP", "Loop"},
+	{1, "CYCLE_REVERSE", "Reverse"},
+	{2, "CYCLE_CLAMP", "Clamp"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<CycleType>(CycleType value) {
+	return EnumToString(uint(value), CycleTypeTable);
+}
+
+template <> CycleType StringToEnum<CycleType>(const std::string& value) {
+	return CycleType(StringToEnum(value, CycleTypeTable));
+}
+
+void NifStream( CycleType & val, istream& in, uint version ) { val = CycleType(ReadValue<uint>( in )); }
+void NifStream( CycleType const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, CycleType const & val ) { return out << EnumToString(val); }
+
+/*!
+ * ApplyMode
+ */
+static EnumLookupType ApplyModeTable[] = {
+	{0, "APPLY_REPLACE", "Replaces existing color"},
+	{1, "APPLY_DECAL", "For placing images on the object like stickers."},
+	{2, "APPLY_MODULATE", "Modulates existing color. (Default)"},
+	{3, "APPLY_HILIGHT", "PS2 Only.  Function Unknown."},
+	{4, "APPLY_HILIGHT2", "PS2 Only.  Function Unknown."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<ApplyMode>(ApplyMode value) {
+	return EnumToString(uint(value), ApplyModeTable);
+}
+
+template <> ApplyMode StringToEnum<ApplyMode>(const std::string& value) {
+	return ApplyMode(StringToEnum(value, ApplyModeTable));
+}
+
+void NifStream( ApplyMode & val, istream& in, uint version ) { val = ApplyMode(ReadValue<uint>( in )); }
+void NifStream( ApplyMode const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, ApplyMode const & val ) { return out << EnumToString(val); }
+
+/*!
+ * FieldType
+ */
+static EnumLookupType FieldTypeTable[] = {
+	{0, "FIELD_WIND", "Wind (fixed direction)"},
+	{1, "FIELD_POINT", "Point (fixed origin)"},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<FieldType>(FieldType value) {
+	return EnumToString(uint(value), FieldTypeTable);
+}
+
+template <> FieldType StringToEnum<FieldType>(const std::string& value) {
+	return FieldType(StringToEnum(value, FieldTypeTable));
+}
+
+void NifStream( FieldType & val, istream& in, uint version ) { val = FieldType(ReadValue<uint>( in )); }
+void NifStream( FieldType const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, FieldType const & val ) { return out << EnumToString(val); }
+
+/*!
+ * BillboardMode
+ */
+static EnumLookupType BillboardModeTable[] = {
+	{0, "ALWAYS_FACE_CAMERA", "The billboard will always face the camera."},
+	{1, "ROTATE_ABOUT_UP", "The billboard will only rotate around the up axis."},
+	{2, "RIGID_FACE_CAMERA", "Rigid Face Camera."},
+	{3, "ALWAYS_FACE_CENTER", "Always Face Center."},
+	{4, "RIGID_FACE_CENTER", "Rigid Face Center."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<BillboardMode>(BillboardMode value) {
+	return EnumToString(uint(value), BillboardModeTable);
+}
+
+template <> BillboardMode StringToEnum<BillboardMode>(const std::string& value) {
+	return BillboardMode(StringToEnum(value, BillboardModeTable));
+}
+
+void NifStream( BillboardMode & val, istream& in, uint version ) { val = BillboardMode(ReadValue<ushort>( in )); }
+void NifStream( BillboardMode const & val, ostream& out, uint version ) { WriteValue<ushort>( val, out ); }
+ostream & operator<<( ostream & out, BillboardMode const & val ) { return out << EnumToString(val); }
+
+/*!
+ * TexType
+ */
+static EnumLookupType TexTypeTable[] = {
+	{0, "BASE_MAP", "The basic texture used by most meshes."},
+	{1, "DARK_MAP", "Used to darken the model with false lighting."},
+	{2, "DETAIL_MAP", "Combined with base map for added detail.  Usually tiled over the mesh many times for close-up view."},
+	{3, "GLOSS_MAP", "Allows the specularity (glossyness) of an object to differ across its surface."},
+	{4, "GLOW_MAP", "Creates a glowing effect.  Basically an incandescence map."},
+	{5, "BUMP_MAP", "Used to make the object appear to have more detail than it really does."},
+	{6, "DECAL_0_MAP", "For placing images on the object like stickers."},
+	{7, "DECAL_1_MAP", "For placing images on the object like stickers."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<TexType>(TexType value) {
+	return EnumToString(uint(value), TexTypeTable);
+}
+
+template <> TexType StringToEnum<TexType>(const std::string& value) {
+	return TexType(StringToEnum(value, TexTypeTable));
+}
+
+void NifStream( TexType & val, istream& in, uint version ) { val = TexType(ReadValue<uint>( in )); }
+void NifStream( TexType const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, TexType const & val ) { return out << EnumToString(val); }
+
+/*!
+ * TexClampMode
+ */
+static EnumLookupType TexClampModeTable[] = {
+	{0, "CLAMP_S_CLAMP_T", "Clamp in both directions."},
+	{1, "CLAMP_S_WRAP_T", "Clamp in the S(U) direction but wrap in the T(V) direction."},
+	{2, "WRAP_S_CLAMP_T", "Wrap in the S(U) direction but clamp in the T(V) direction."},
+	{3, "WRAP_S_WRAP_T", "Wrap in both directions."},
+	{0, NULL, NULL},
+};
+
+template <> std::string EnumToString<TexClampMode>(TexClampMode value) {
+	return EnumToString(uint(value), TexClampModeTable);
+}
+
+template <> TexClampMode StringToEnum<TexClampMode>(const std::string& value) {
+	return TexClampMode(StringToEnum(value, TexClampModeTable));
+}
+
+void NifStream( TexClampMode & val, istream& in, uint version ) { val = TexClampMode(ReadValue<uint>( in )); }
+void NifStream( TexClampMode const & val, ostream& out, uint version ) { WriteValue<uint>( val, out ); }
+ostream & operator<<( ostream & out, TexClampMode const & val ) { return out << EnumToString(val); }
+
+}
diff --git a/nif_enums.h b/nif_enums.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f7270224c7d046f9cc5a78709f72e87d35553a4
--- /dev/null
+++ b/nif_enums.h
@@ -0,0 +1,402 @@
+/* Copyright (c) 2006, NIF File Format Library and Tools
+All rights reserved.  Please see niflib.h for licence. */
+#ifndef _NIF_ENUMS_H_
+#define _NIF_ENUMS_H_
+
+#include "nif_basic_types.h"
+
+namespace Niflib {
+
+/* Template converters for Enum Data Types */
+template <typename T> std::string EnumToString(T value);
+template <typename T> T StringToEnum(const std::string& value);
+
+/*!
+ * The type of force?  May be more valid values.
+ */
+typedef enum ForceType : uint {
+	FORCE_PLANAR = 0, /*!< FORCE_PLANAR */
+	FORCE_SPHERICAL = 1, /*!< FORCE_SPHERICAL */
+	FORCE_UNKNOWN = 2, /*!< FORCE_UNKNOWN */
+} ForceType;
+
+template <> std::string EnumToString<ForceType>(ForceType value);
+template <> ForceType StringToEnum<ForceType>(const std::string& value);
+void NifStream( ForceType & val, istream& in, uint version = 0 );
+void NifStream( ForceType const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, ForceType const & val );
+
+/*!
+ * An unsigned 32-bit integer, describing the color depth of a texture.
+ */
+typedef enum PixelLayout : uint {
+	PIX_LAY_PALETTISED = 0, /*!< Texture is in 8-bit paletized format. */
+	PIX_LAY_HIGH_COLOR_16 = 1, /*!< Texture is in 16-bit high color format. */
+	PIX_LAY_TRUE_COLOR_32 = 2, /*!< Texture is in 32-bit true color format. */
+	PIX_LAY_COMPRESSED = 3, /*!< Texture is compressed. */
+	PIX_LAY_BUMPMAP = 4, /*!< Texture is a grayscale bump map. */
+	PIX_LAY_DEFAULT = 5, /*!< Use default setting. */
+} PixelLayout;
+
+template <> std::string EnumToString<PixelLayout>(PixelLayout value);
+template <> PixelLayout StringToEnum<PixelLayout>(const std::string& value);
+void NifStream( PixelLayout & val, istream& in, uint version = 0 );
+void NifStream( PixelLayout const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, PixelLayout const & val );
+
+/*!
+ * An unsigned 32-bit integer, describing how vertex colors influence
+ * lighting.
+ */
+typedef enum LightMode : uint {
+	LIGHT_MODE_EMISSIVE = 0, /*!< Emissive. */
+	LIGHT_MODE_EMI_AMB_DIF = 1, /*!< Emissive + Ambient + Diffuse. (Default) */
+} LightMode;
+
+template <> std::string EnumToString<LightMode>(LightMode value);
+template <> LightMode StringToEnum<LightMode>(const std::string& value);
+void NifStream( LightMode & val, istream& in, uint version = 0 );
+void NifStream( LightMode const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, LightMode const & val );
+
+/*!
+ * An unsigned 32-bit integer, describing how mipmaps are handled in a
+ * texture.
+ */
+typedef enum MipMapFormat : uint {
+	MIP_FMT_NO = 0, /*!< Texture does not use mip maps. */
+	MIP_FMT_YES = 1, /*!< Texture uses mip maps. */
+	MIP_FMT_DEFAULT = 2, /*!< Use default setting. */
+} MipMapFormat;
+
+template <> std::string EnumToString<MipMapFormat>(MipMapFormat value);
+template <> MipMapFormat StringToEnum<MipMapFormat>(const std::string& value);
+void NifStream( MipMapFormat & val, istream& in, uint version = 0 );
+void NifStream( MipMapFormat const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, MipMapFormat const & val );
+
+/*!
+ * An unsigned 32-bit integer, describing how transparency is handled in
+ * a texture.
+ */
+typedef enum AlphaFormat : uint {
+	ALPHA_NONE = 0, /*!< No alpha blending; the texture is fully opaque. */
+	ALPHA_BINARY = 1, /*!< Texture is either fully transparent or fully opaque.  There are no partially transparent areas. */
+	ALPHA_SMOOTH = 2, /*!< Full range of alpha values can be used from fully transparent to fully opaque including all partially transparent values in between. */
+	ALPHA_DEFAULT = 3, /*!< Use default setting. */
+} AlphaFormat;
+
+template <> std::string EnumToString<AlphaFormat>(AlphaFormat value);
+template <> AlphaFormat StringToEnum<AlphaFormat>(const std::string& value);
+void NifStream( AlphaFormat & val, istream& in, uint version = 0 );
+void NifStream( AlphaFormat const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, AlphaFormat const & val );
+
+/*!
+ * Specifies the availiable texture filter modes.  That is, the way
+ * pixels within a texture are blended together when textures are
+ * displayed on the screen at a size other than their original
+ * dimentions.
+ */
+typedef enum TexFilterMode : uint {
+	FILTER_NEAREST = 0, /*!< Simply uses the nearest pixel.  Very grainy. */
+	FILTER_BILERP = 1, /*!< Uses bilinear filtering. */
+	FILTER_TRILERP = 2, /*!< Uses trilinear filtering. */
+	FILTER_NEAREST_MIPNEAREST = 3, /*!< Uses the nearest pixel from the mipmap that is closest to the display size. */
+	FILTER_NEAREST_MIPLERP = 4, /*!< Blends the two mipmaps closest to the display size linearly, and then uses the nearest pixel from the result. */
+	FILTER_BILERP_MIPNEAREST = 5, /*!< Uses the closest mipmap to the display size and then uses bilinear filtering on the pixels. */
+} TexFilterMode;
+
+template <> std::string EnumToString<TexFilterMode>(TexFilterMode value);
+template <> TexFilterMode StringToEnum<TexFilterMode>(const std::string& value);
+void NifStream( TexFilterMode & val, istream& in, uint version = 0 );
+void NifStream( TexFilterMode const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, TexFilterMode const & val );
+
+/*!
+ * The motion type. Determines quality of motion?
+ */
+typedef enum MotionQuality : byte {
+	MO_QUAL_MOVING = 0, /*!< Moving */
+	MO_QUAL_FIXED = 1, /*!< Fixed */
+	MO_QUAL_KEYFRAMED = 2, /*!< Keyframed */
+	MO_QUAL_MOVING2 = 3, /*!< Moving(?) */
+	MO_QUAL_MOVING3 = 4, /*!< Moving(?) */
+	MO_QUAL_CRITICAL = 5, /*!< Critical */
+	MO_QUAL_BULLET = 6, /*!< Bullet */
+	MO_QUAL_USER = 7, /*!< User */
+	MO_QUAL_NULL = 8, /*!< Null */
+} MotionQuality;
+
+template <> std::string EnumToString<MotionQuality>(MotionQuality value);
+template <> MotionQuality StringToEnum<MotionQuality>(const std::string& value);
+void NifStream( MotionQuality & val, istream& in, uint version = 0 );
+void NifStream( MotionQuality const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, MotionQuality const & val );
+
+/*!
+ * Sets mesh color in Oblivion Construction Set.  Anything higher than 57
+ * is also null.
+ */
+typedef enum OblivionLayer : uint {
+	OL_UNIDENTIFIED = 0, /*!< Unidentified (white) */
+	OL_STATIC = 1, /*!< Static (red) */
+	OL_ANIM_STATIC = 2, /*!< AnimStatic (magenta) */
+	OL_TRANSPARENT = 3, /*!< Transparent (light pink) */
+	OL_CLUTTER = 4, /*!< Clutter (light blue) */
+	OL_WEAPON = 5, /*!< Weapon (orange) */
+	OL_PROJECTILE = 6, /*!< Projectile (light orange) */
+	OL_SPELL = 7, /*!< Spell (cyan) */
+	OL_BIPED = 8, /*!< Biped (green) Seems to apply to all creatures/NPCs */
+	OL_TREES = 9, /*!< Trees (light brown) */
+	OL_PROPS = 10, /*!< Props (magenta) */
+	OL_WATER = 11, /*!< Water (cyan) */
+	OL_TRIGGER = 12, /*!< Trigger (light grey) */
+	OL_TERRAIN = 13, /*!< Terrain (light yellow) */
+	OL_TRAP = 14, /*!< Trap (light grey) */
+	OL_NONCOLLIDABLE = 15, /*!< NonCollidable (white) */
+	OL_CLOUD_TRAP = 16, /*!< CloudTrap (greenish grey) */
+	OL_GROUND = 17, /*!< Ground (none) */
+	OL_PORTAL = 18, /*!< Portal (green) */
+	OL_STAIRS = 19, /*!< Stairs (white) */
+	OL_CHAR_CONTROLLER = 20, /*!< CharController (yellow) */
+	OL_AVOID_BOX = 21, /*!< AvoidBox (dark yellow) */
+	OL_UNKNOWN1 = 22, /*!< ? (white) */
+	OL_UNKNOWN2 = 23, /*!< ? (white) */
+	OL_CAMERA_PICK = 24, /*!< CameraPick (white) */
+	OL_ITEM_PICK = 25, /*!< ItemPick (white) */
+	OL_LINE_OF_SIGHT = 26, /*!< LineOfSight (white) */
+	OL_PATH_PICK = 27, /*!< PathPick (white) */
+	OL_CUSTOM_PICK_1 = 28, /*!< CustomPick1 (white) */
+	OL_CUSTOM_PICK_2 = 29, /*!< CustomPick2 (white) */
+	OL_SPELL_EXPLOSION = 30, /*!< SpellExplosion (white) */
+	OL_DROPPING_PICK = 31, /*!< DroppingPick (white) */
+	OL_OTHER = 32, /*!< Other (white) */
+	OL_HEAD = 33, /*!< Head */
+	OL_BODY = 34, /*!< Body */
+	OL_SPINE1 = 35, /*!< Spine1 */
+	OL_SPINE2 = 36, /*!< Spine2 */
+	OL_L_UPPER_ARM = 37, /*!< LUpperArm */
+	OL_L_FOREARM = 38, /*!< LForeArm */
+	OL_L_HAND = 39, /*!< LHand */
+	OL_L_THIGH = 40, /*!< LThigh */
+	OL_L_CALF = 41, /*!< LCalf */
+	OL_L_FOOT = 42, /*!< LFoot */
+	OL_R_UPPER_ARM = 43, /*!< RUpperArm */
+	OL_R_FOREARM = 44, /*!< RForeArm */
+	OL_R_HAND = 45, /*!< RHand */
+	OL_R_THIGH = 46, /*!< RThigh */
+	OL_R_CALF = 47, /*!< RCalf */
+	OL_R_FOOT = 48, /*!< RFoot */
+	OL_TAIL = 49, /*!< Tail */
+	OL_SIDE_WEAPON = 50, /*!< SideWeapon */
+	OL_SHEILD = 51, /*!< Shield */
+	OL_QUIVER = 52, /*!< Quiver */
+	OL_BACK_WEAPON = 53, /*!< BackWeapon */
+	OL_BACK_WEAPON2 = 54, /*!< BackWeapon (?) */
+	OL_PONYTAIL = 55, /*!< PonyTail */
+	OL_WING = 56, /*!< Wing */
+	OL_NULL = 57, /*!< Null */
+} OblivionLayer;
+
+template <> std::string EnumToString<OblivionLayer>(OblivionLayer value);
+template <> OblivionLayer StringToEnum<OblivionLayer>(const std::string& value);
+void NifStream( OblivionLayer & val, istream& in, uint version = 0 );
+void NifStream( OblivionLayer const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, OblivionLayer const & val );
+
+/*!
+ * The type of animation interpolation (blending) that will be used on
+ * the associated key frames.
+ */
+typedef enum KeyType : uint {
+	LINEAR_KEY = 1, /*!< Use linear interpolation. */
+	QUADRATIC_KEY = 2, /*!< Use quadratic interpolation.  Forward and back tangents will be stored. */
+	TBC_KEY = 3, /*!< Use Tension Bias Continuity interpolation.  Tension, bias, and continuity will be stored. */
+	XYZ_ROTATION_KEY = 4, /*!< For use only with rotation data.  Separate X, Y, and Z keys will be stored instead of using quaternions. */
+	UNKNOWN_KEY = 5, /*!< Unknown.  Step function? */
+} KeyType;
+
+template <> std::string EnumToString<KeyType>(KeyType value);
+template <> KeyType StringToEnum<KeyType>(const std::string& value);
+void NifStream( KeyType & val, istream& in, uint version = 0 );
+void NifStream( KeyType const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, KeyType const & val );
+
+/*!
+ * An unsigned 32-bit integer, which describes how to apply vertex
+ * colors.
+ */
+typedef enum VertMode : uint {
+	VERT_MODE_SRC_IGNORE = 0, /*!< Source Ignore. */
+	VERT_MODE_SRC_EMISSIVE = 1, /*!< Source Emissive. */
+	VERT_MODE_SRC_AMB_DIF = 2, /*!< Source Ambient/Diffuse. (Default) */
+} VertMode;
+
+template <> std::string EnumToString<VertMode>(VertMode value);
+template <> VertMode StringToEnum<VertMode>(const std::string& value);
+void NifStream( VertMode & val, istream& in, uint version = 0 );
+void NifStream( VertMode const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, VertMode const & val );
+
+/*!
+ * A material, used by havok shape objects.
+ */
+typedef enum HavokMaterial : uint {
+	HAV_MAT_STONE = 0, /*!< Stone */
+	HAV_MAT_CLOTH = 1, /*!< Cloth */
+	HAV_MAT_DIRT = 2, /*!< Dirt */
+	HAV_MAT_GLASS = 3, /*!< Glass */
+	HAV_MAT_GRASS = 4, /*!< Grass */
+	HAV_MAT_METAL = 5, /*!< Metal */
+	HAV_MAT_ORGANIC = 6, /*!< Organic */
+	HAV_MAT_SKIN = 7, /*!< Skin */
+	HAV_MAT_WATER = 8, /*!< Water */
+	HAV_MAT_WOOD = 9, /*!< Wood */
+	HAV_MAT_HEAVY_STONE = 10, /*!< Heavy Stone */
+	HAV_MAT_HEAVY_METAL = 11, /*!< Heavy Metal */
+	HAV_MAT_HEAVY_WOOD = 12, /*!< Heavy Wood */
+	HAV_MAT_CHAIN = 13, /*!< Chain */
+	HAV_MAT_SNOW = 14, /*!< Snow */
+	HAV_MAT_STONE_STAIRS = 15, /*!< Stone Stairs */
+	HAV_MAT_CLOTH_STAIRS = 16, /*!< Cloth Stairs */
+	HAV_MAT_DIRT_STAIRS = 17, /*!< Dirt Stairs */
+	HAV_MAT_GLASS_STAIRS = 18, /*!< Glass Stairs */
+	HAV_MAT_GRASS_STAIRS = 19, /*!< Grass Stairs */
+	HAV_MAT_METAL_STAIRS = 20, /*!< Metal Stairs */
+	HAV_MAT_ORGANIC_STAIRS = 21, /*!< Organic Stairs */
+	HAV_MAT_SKIN_STAIRS = 22, /*!< Skin Stairs */
+	HAV_MAT_WATER_STAIRS = 23, /*!< Water Stairs */
+	HAV_MAT_WOOD_STAIRS = 24, /*!< Wood Stairs */
+	HAV_MAT_HEAVY_STONE_STAIRS = 25, /*!< Heavy Stone Stairs */
+	HAV_MAT_HEAVY_METAL_STAIRS = 26, /*!< Heavy Metal Stairs */
+	HAV_MAT_HEAVY_WOOD_STAIRS = 27, /*!< Heavy Wood Stairs */
+	HAV_MAT_CHAIN_STAIRS = 28, /*!< Chain Stairs */
+	HAV_MAT_SNOW_STAIRS = 29, /*!< Snow Stairs */
+	HAV_MAT_ELEVATOR = 30, /*!< Elevator */
+} HavokMaterial;
+
+template <> std::string EnumToString<HavokMaterial>(HavokMaterial value);
+template <> HavokMaterial StringToEnum<HavokMaterial>(const std::string& value);
+void NifStream( HavokMaterial & val, istream& in, uint version = 0 );
+void NifStream( HavokMaterial const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, HavokMaterial const & val );
+
+/*!
+ * Specifies the pixel format used by the NiPixelData object to store a
+ * texture.
+ */
+typedef enum PixelFormat : uint {
+	PX_FMT_RGB8 = 0, /*!< 24-bit color: uses 8 bit to store each red, blue, and green component. */
+	PX_FMT_RGBA8 = 1, /*!< 32-bit color with alpha: uses 8 bits to store each red, blue, green, and alpha component. */
+	PX_FMT_PAL8 = 2, /*!< 8-bit palette index: uses 8 bits to store an index into the palette stored in a NiPallete object. */
+} PixelFormat;
+
+template <> std::string EnumToString<PixelFormat>(PixelFormat value);
+template <> PixelFormat StringToEnum<PixelFormat>(const std::string& value);
+void NifStream( PixelFormat & val, istream& in, uint version = 0 );
+void NifStream( PixelFormat const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, PixelFormat const & val );
+
+/*!
+ * The animation cyle behavior.
+ */
+typedef enum CycleType : uint {
+	CYCLE_LOOP = 0, /*!< Loop */
+	CYCLE_REVERSE = 1, /*!< Reverse */
+	CYCLE_CLAMP = 2, /*!< Clamp */
+} CycleType;
+
+template <> std::string EnumToString<CycleType>(CycleType value);
+template <> CycleType StringToEnum<CycleType>(const std::string& value);
+void NifStream( CycleType & val, istream& in, uint version = 0 );
+void NifStream( CycleType const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, CycleType const & val );
+
+/*!
+ * An unsigned 32-bit integer, describing the apply mode of a texture.
+ */
+typedef enum ApplyMode : uint {
+	APPLY_REPLACE = 0, /*!< Replaces existing color */
+	APPLY_DECAL = 1, /*!< For placing images on the object like stickers. */
+	APPLY_MODULATE = 2, /*!< Modulates existing color. (Default) */
+	APPLY_HILIGHT = 3, /*!< PS2 Only.  Function Unknown. */
+	APPLY_HILIGHT2 = 4, /*!< PS2 Only.  Function Unknown. */
+} ApplyMode;
+
+template <> std::string EnumToString<ApplyMode>(ApplyMode value);
+template <> ApplyMode StringToEnum<ApplyMode>(const std::string& value);
+void NifStream( ApplyMode & val, istream& in, uint version = 0 );
+void NifStream( ApplyMode const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, ApplyMode const & val );
+
+/*!
+ * The force field's type.
+ */
+typedef enum FieldType : uint {
+	FIELD_WIND = 0, /*!< Wind (fixed direction) */
+	FIELD_POINT = 1, /*!< Point (fixed origin) */
+} FieldType;
+
+template <> std::string EnumToString<FieldType>(FieldType value);
+template <> FieldType StringToEnum<FieldType>(const std::string& value);
+void NifStream( FieldType & val, istream& in, uint version = 0 );
+void NifStream( FieldType const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, FieldType const & val );
+
+/*!
+ * Determines the way the billboard will react to the camera.
+ */
+typedef enum BillboardMode : ushort {
+	ALWAYS_FACE_CAMERA = 0, /*!< The billboard will always face the camera. */
+	ROTATE_ABOUT_UP = 1, /*!< The billboard will only rotate around the up axis. */
+	RIGID_FACE_CAMERA = 2, /*!< Rigid Face Camera. */
+	ALWAYS_FACE_CENTER = 3, /*!< Always Face Center. */
+	RIGID_FACE_CENTER = 4, /*!< Rigid Face Center. */
+} BillboardMode;
+
+template <> std::string EnumToString<BillboardMode>(BillboardMode value);
+template <> BillboardMode StringToEnum<BillboardMode>(const std::string& value);
+void NifStream( BillboardMode & val, istream& in, uint version = 0 );
+void NifStream( BillboardMode const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, BillboardMode const & val );
+
+/*!
+ * The type of texture.
+ */
+typedef enum TexType : uint {
+	BASE_MAP = 0, /*!< The basic texture used by most meshes. */
+	DARK_MAP = 1, /*!< Used to darken the model with false lighting. */
+	DETAIL_MAP = 2, /*!< Combined with base map for added detail.  Usually tiled over the mesh many times for close-up view. */
+	GLOSS_MAP = 3, /*!< Allows the specularity (glossyness) of an object to differ across its surface. */
+	GLOW_MAP = 4, /*!< Creates a glowing effect.  Basically an incandescence map. */
+	BUMP_MAP = 5, /*!< Used to make the object appear to have more detail than it really does. */
+	DECAL_0_MAP = 6, /*!< For placing images on the object like stickers. */
+	DECAL_1_MAP = 7, /*!< For placing images on the object like stickers. */
+} TexType;
+
+template <> std::string EnumToString<TexType>(TexType value);
+template <> TexType StringToEnum<TexType>(const std::string& value);
+void NifStream( TexType & val, istream& in, uint version = 0 );
+void NifStream( TexType const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, TexType const & val );
+
+/*!
+ * Specifies the availiable texture clamp modes.  That is, the behavior
+ * of pixels outside the range of the texture.
+ */
+typedef enum TexClampMode : uint {
+	CLAMP_S_CLAMP_T = 0, /*!< Clamp in both directions. */
+	CLAMP_S_WRAP_T = 1, /*!< Clamp in the S(U) direction but wrap in the T(V) direction. */
+	WRAP_S_CLAMP_T = 2, /*!< Wrap in the S(U) direction but clamp in the T(V) direction. */
+	WRAP_S_WRAP_T = 3, /*!< Wrap in both directions. */
+} TexClampMode;
+
+template <> std::string EnumToString<TexClampMode>(TexClampMode value);
+template <> TexClampMode StringToEnum<TexClampMode>(const std::string& value);
+void NifStream( TexClampMode & val, istream& in, uint version = 0 );
+void NifStream( TexClampMode const & val, ostream& out, uint version = 0  );
+ostream & operator<<( ostream & out, TexClampMode const & val );
+
+}
+#endif
diff --git a/niflib.cpp b/niflib.cpp
index 56d74f41577b8bab67598994feed7efa392037a1..bfb696200b242bf2bf671dc2c19b1e0da01d70fd 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -858,13 +858,13 @@ void MergeNifTrees( const Ref<NiNode> & target, const Ref<NiControllerSequence>
 
 					//Set cycle type as well
 					switch ( right->GetCycleType() ) {
-						case NiControllerSequence::CYCLE_LOOP:
+						case CYCLE_LOOP:
 							ctlr->SetFlags( 8 ); //Active
 							break;
-						case NiControllerSequence::CYCLE_CLAMP:
+						case CYCLE_CLAMP:
 							ctlr->SetFlags( 12 ); //Active+Clamp
 							break;
-						case NiControllerSequence::CYCLE_REVERSE:
+						case CYCLE_REVERSE:
 							ctlr->SetFlags( 10 ); //Active+Reverse
 							break;
 					}
diff --git a/niflib.h b/niflib.h
index 94d9ff1e3a1571602dc5ceb6b4c54ad1a691bd8c..91a07985eb29ccc7654cedb8a07dafc8b9fe1ef3 100644
--- a/niflib.h
+++ b/niflib.h
@@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE. */
 #include "nif_math.h"
 #include "nif_versions.h"
 #include "Ref.h"
+#include "nif_enums.h"
 
 using namespace std;
 namespace Niflib {
diff --git a/niflib.vcproj b/niflib.vcproj
index 55881ef3ed8a736007464df9540ca509f7d6887c..a78b04870e9074c4f03824dc4d939b441036517f 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -358,6 +358,10 @@
 				RelativePath=".\kfm.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\nif_enums.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\NIF_IO.cpp"
 				>
@@ -1449,6 +1453,10 @@
 				RelativePath=".\nif_basic_types.h"
 				>
 			</File>
+			<File
+				RelativePath=".\nif_enums.h"
+				>
+			</File>
 			<File
 				RelativePath=".\NIF_IO.h"
 				>
diff --git a/obj/NiBillboardNode.cpp b/obj/NiBillboardNode.cpp
index 9ef63c9eed5eae0a6afbba59b456210f7b7c73ad..9eebfe9175a735da1e4279b66721f719c12d0097 100644
--- a/obj/NiBillboardNode.cpp
+++ b/obj/NiBillboardNode.cpp
@@ -35,11 +35,11 @@ const Type & NiBillboardNode::GetType() const {
 	return TYPE;
 };
 
-ushort NiBillboardNode::GetBillboardMode() const {
+BillboardMode NiBillboardNode::GetBillboardMode() const {
 	return billboardMode;
 }
 
-void NiBillboardNode::SetBillboardMode( ushort value ) {
+void NiBillboardNode::SetBillboardMode( BillboardMode value ) {
 	billboardMode = value;
 }
 
diff --git a/obj/NiBillboardNode.h b/obj/NiBillboardNode.h
index 6c3cd0c2a853dfcff005fa7af118a22f4b6d3bd1..9a0ab03a12a4d4ef7d5cd761b17ef6eb36cf24e0 100644
--- a/obj/NiBillboardNode.h
+++ b/obj/NiBillboardNode.h
@@ -38,8 +38,8 @@ public:
 	 * 0: ALWAYS_FACE_CAMERA 1: ROTATE_ABOUT_UP 2: RIGID_FACE_CAMERA 3:
 	 * ALWAYS_FACE_CENTER 4: RIGID_FACE_CENTER
 	 */
-	ushort GetBillboardMode() const;
-	void SetBillboardMode( ushort value );
+	BillboardMode GetBillboardMode() const;
+	void SetBillboardMode( BillboardMode value );
 
 protected:
 	NI_BILLBOARD_NODE_MEMBERS
diff --git a/obj/NiControllerSequence.cpp b/obj/NiControllerSequence.cpp
index c1b0635ecf8be29ab24427272278cc21276253de..c7cb2bbdaa670c3e9d67a299b54bc45bf0d5df9a 100644
--- a/obj/NiControllerSequence.cpp
+++ b/obj/NiControllerSequence.cpp
@@ -171,11 +171,11 @@ void NiControllerSequence::SetStopTime( float value ) {
 	stopTime = value;
 }
 
-NiControllerSequence::CycleType NiControllerSequence::GetCycleType() const {
+CycleType NiControllerSequence::GetCycleType() const {
 	return CycleType(cycleType);
 }
 
-void NiControllerSequence::SetCycleType( NiControllerSequence::CycleType n ) {
+void NiControllerSequence::SetCycleType( CycleType n ) {
 	cycleType = n;
 }
 
diff --git a/obj/NiControllerSequence.h b/obj/NiControllerSequence.h
index d337cf59077345fbd738dbc3a2446795a08d78f4..51a086fe13aceff75a2846fa35d8518d3a3c17fe 100644
--- a/obj/NiControllerSequence.h
+++ b/obj/NiControllerSequence.h
@@ -53,12 +53,6 @@ public:
 	string GetName() const;
 	void SetName( const string & value );
 
-	enum CycleType {
-		CYCLE_LOOP = 0,
-		CYCLE_REVERSE = 1,
-		CYCLE_CLAMP = 2
-	};
-
 	/*! Sets the name and block reference to the NiTextKeyExtraData block which will be used by this controller sequence to specify the keyframe labels or "notes."
 	 * \param new_name The name of the NiTextKeyExtraData block to use.
 	 * \param txt_key A reference to the NiTextKeyExtraData object to use.
diff --git a/obj/NiTextureEffect.cpp b/obj/NiTextureEffect.cpp
index f089fabfb202b2a06ff9a0fc434da860a2f2e1a8..71b279bf17f344b5f8ea93b103402b134970a064 100644
--- a/obj/NiTextureEffect.cpp
+++ b/obj/NiTextureEffect.cpp
@@ -60,11 +60,11 @@ void NiTextureEffect::SetTextureFiltering( uint value ) {
 	textureFiltering = value;
 }
 
-uint NiTextureEffect::GetTextureClamping() const {
+TexClampMode NiTextureEffect::GetTextureClamping() const {
 	return textureClamping;
 }
 
-void NiTextureEffect::SetTextureClamping( uint value ) {
+void NiTextureEffect::SetTextureClamping( TexClampMode value ) {
 	textureClamping = value;
 }
 
diff --git a/obj/NiTextureEffect.h b/obj/NiTextureEffect.h
index 59834edcb89b2c09128ab32ea4d6e0974092f7b8..75b077a7c11d54c7bd38e93222b020275f5f04a6 100644
--- a/obj/NiTextureEffect.h
+++ b/obj/NiTextureEffect.h
@@ -65,8 +65,8 @@ public:
 	 * 0: CLAMP_S_CLAMP (Common value) 1: CLAMP_S_WRAP 2: WRAP_S_CLAMP_T 3:
 	 * WRAP_S_WRAP_T (Common value)
 	 */
-	uint GetTextureClamping() const;
-	void SetTextureClamping( uint value );
+	TexClampMode GetTextureClamping() const;
+	void SetTextureClamping( TexClampMode value );
 
 	/*!
 	 * 0: PROJECTED_LIGHT 1: PROJECTED_SHADOW 2: ENVIRONMENT_MAP (Usual
diff --git a/obj/bhkEntity.cpp b/obj/bhkEntity.cpp
index ff26738e1988965fb93df1f570e5baf9ab517695..56b910cc98bac8686535d842b6e42d36d2403d41 100644
--- a/obj/bhkEntity.cpp
+++ b/obj/bhkEntity.cpp
@@ -44,11 +44,11 @@ void bhkEntity::SetShape( Ref<bhkShape > value ) {
 	shape = value;
 }
 
-uint bhkEntity::GetLayer() const {
+OblivionLayer bhkEntity::GetLayer() const {
 	return layer;
 }
 
-void bhkEntity::SetLayer( uint value ) {
+void bhkEntity::SetLayer( OblivionLayer value ) {
 	layer = value;
 }
 
diff --git a/obj/bhkEntity.h b/obj/bhkEntity.h
index fbbcedbeaa4ac04659a38987c3b16693d3917f3b..303e8e9d2c3e28afddda648982741357af0173a4 100644
--- a/obj/bhkEntity.h
+++ b/obj/bhkEntity.h
@@ -105,8 +105,8 @@ public:
 	 * 56: Wing
     * 57+: Null
 	 */
-	uint GetLayer() const;
-	void SetLayer( uint value );
+	OblivionLayer GetLayer() const;
+	void SetLayer( OblivionLayer value );
 
 protected:
 	BHK_ENTITY_MEMBERS
diff --git a/obj/bhkRigidBody.cpp b/obj/bhkRigidBody.cpp
index c3278a2c4fedf11fa3bce531f3e6912b14e775ab..cca18127933dfdab6405bfa06ae37b8ed69a9004 100644
--- a/obj/bhkRigidBody.cpp
+++ b/obj/bhkRigidBody.cpp
@@ -37,11 +37,11 @@ const Type & bhkRigidBody::GetType() const {
 	return TYPE;
 };
 
-uint bhkRigidBody::GetLayerCopy() const {
+OblivionLayer bhkRigidBody::GetLayerCopy() const {
 	return layerCopy;
 }
 
-void bhkRigidBody::SetLayerCopy( uint value ) {
+void bhkRigidBody::SetLayerCopy( OblivionLayer value ) {
 	layerCopy = value;
 }
 
@@ -165,10 +165,10 @@ void bhkRigidBody::SetMotionSystem( byte value ) {
 	motionSystem = value;
 }
 
-byte bhkRigidBody::GetQualityType() const {
+MotionQuality bhkRigidBody::GetQualityType() const {
 	return qualityType;
 }
 
-void bhkRigidBody::SetQualityType( byte value ) {
+void bhkRigidBody::SetQualityType( MotionQuality value ) {
 	qualityType = value;
 }
diff --git a/obj/bhkRigidBody.h b/obj/bhkRigidBody.h
index 56b9892dfcbb52e6e331e08e3cd72005974ffe07..17b1576ee42af11404cf879dd47a190eee4841f1 100644
--- a/obj/bhkRigidBody.h
+++ b/obj/bhkRigidBody.h
@@ -42,8 +42,8 @@ public:
 	/*!
 	 * Copy of layer value?
 	 */
-	uint GetLayerCopy() const;
-	void SetLayerCopy( uint value );
+	OblivionLayer GetLayerCopy() const;
+	void SetLayerCopy( OblivionLayer value );
 
 	/*!
 	 * Translation.
@@ -156,8 +156,8 @@ public:
     * 7: User
     * 8+: Null
 	 */
-	byte GetQualityType() const;
-	void SetQualityType( byte value );
+	MotionQuality GetQualityType() const;
+	void SetQualityType( MotionQuality value );
 
 protected:
 	BHK_RIGID_BODY_MEMBERS
diff --git a/obj/bhkSphereRepShape.cpp b/obj/bhkSphereRepShape.cpp
index 56962e289892a330bfa88b71b21483f77de74649..7e94f38f6c9b97624c17df4a10ff17589762b96f 100644
--- a/obj/bhkSphereRepShape.cpp
+++ b/obj/bhkSphereRepShape.cpp
@@ -35,11 +35,11 @@ const Type & bhkSphereRepShape::GetType() const {
 	return TYPE;
 };
 
-uint bhkSphereRepShape::GetMaterial() const {
+HavokMaterial bhkSphereRepShape::GetMaterial() const {
 	return material;
 }
 
-void bhkSphereRepShape::SetMaterial( uint value ) {
+void bhkSphereRepShape::SetMaterial( HavokMaterial value ) {
 	material = value;
 }
 
diff --git a/obj/bhkSphereRepShape.h b/obj/bhkSphereRepShape.h
index e4a1d865bc0dbd7cce04b2d8b5b668fba749717e..23b87bac73013a99c24a4516047b6f9b1d959a9d 100644
--- a/obj/bhkSphereRepShape.h
+++ b/obj/bhkSphereRepShape.h
@@ -37,8 +37,8 @@ public:
 	/*!
 	 * The shape's material.
 	 */
-	uint GetMaterial() const;
-	void SetMaterial( uint value );
+	HavokMaterial GetMaterial() const;
+	void SetMaterial( HavokMaterial value );
 
 protected:
 	BHK_SPHERE_REP_SHAPE_MEMBERS