diff --git a/include/obj/NiAlphaController.h b/include/obj/NiAlphaController.h
index 6d741aab5b7a37ea54ac01b6932a5f95830e1a89..943ab424e605ce043d87c56e9f928f8ecc237800 100644
--- a/include/obj/NiAlphaController.h
+++ b/include/obj/NiAlphaController.h
@@ -58,6 +58,27 @@ public:
 	NIFLIB_API virtual const Type & GetType() const;
 
 	//--BEGIN MISC CUSTOM CODE--//
+
+	/*!
+	 * Retrives the alpha data used by this controller.
+	 * \return The alpha data.
+	 */
+	NIFLIB_API Ref<NiFloatData> GetData() const;
+
+	/*!
+	 * Sets the alpha data used by this controller.
+	 * \param[in] n The new alpha data.
+	 */
+	NIFLIB_API void SetData( NiFloatData * n );
+
+	/*!
+	 * This function will adjust the times in all the keys in the data objects
+	 * referenced by this controller and any of its interpolators such that the
+	 * phase will equal 0 and frequency will equal one.  In other words, it
+	 * will cause the key times to be in seconds starting from zero.
+	 */
+	NIFLIB_API virtual void NormalizeKeys();
+
 	//--END CUSTOM CODE--//
 protected:
 	/*! Alpha controller data index. */
diff --git a/include/obj/NiKeyframeController.h b/include/obj/NiKeyframeController.h
index 69905dad9a6e04df8911b0450a3e35611fe3af03..41fa6ee0d931c8671bb65d3ba780ab65e361e78e 100644
--- a/include/obj/NiKeyframeController.h
+++ b/include/obj/NiKeyframeController.h
@@ -13,7 +13,7 @@ All rights reserved.  Please see niflib.h for license. */
 //--BEGIN FILE HEAD CUSTOM CODE--//
 //--END CUSTOM CODE--//
 
-#include "NiTimeController.h"
+#include "NiSingleInterpController.h"
 
 // Include structures
 #include "../Ref.h"
@@ -25,7 +25,7 @@ class NiKeyframeController;
 typedef Ref<NiKeyframeController> NiKeyframeControllerRef;
 
 /*! A time controller object for animation key frames. */
-class NiKeyframeController : public NiTimeController {
+class NiKeyframeController : public NiSingleInterpController {
 public:
 	/*! Constructor */
 	NIFLIB_API NiKeyframeController();
diff --git a/include/obj/NiTextureTransformController.h b/include/obj/NiTextureTransformController.h
index f5bcd8125b03afbdec84aacca6d251eeee704027..b02142b928b22957b636419d0c9b53811fd5f9a1 100644
--- a/include/obj/NiTextureTransformController.h
+++ b/include/obj/NiTextureTransformController.h
@@ -58,6 +58,51 @@ public:
 	NIFLIB_API virtual const Type & GetType() const;
 
 	//--BEGIN MISC CUSTOM CODE--//
+
+	/*
+	 * Retreives the texture slot that is the target of this texture transform controller.
+	 * \return The texture slot that will be animated by this controller.
+	 */
+	NIFLIB_API TexType GetTargetTextureSlot();
+
+	/*
+	 * Retreives the texture slot that will be the target of this texture transform controller.
+	 * \param[in] n The new texture slot that will be animated by this controller.
+	 */
+	NIFLIB_API void SetTargetTextureSlot( TexType n );
+
+	/*
+	 * Retreives the type of texture transformation that this controller applies.
+	 * \return The way this controller will animate the target texture.
+	 */
+	NIFLIB_API TexTransform GetTextureTransformType();
+
+	/*
+	 * Sets the type of texture transformation that this controller applies.
+	 * \param[in] n The new way that this controller will animate the target texture.
+	 */
+	NIFLIB_API void SetTextureTransformType( TexTransform n );
+
+	/*!
+	 * Retrives the float data used by this controller.
+	 * \return The float data.
+	 */
+	NIFLIB_API Ref<NiFloatData> GetData() const;
+
+	/*!
+	 * Sets the float data used by this controller.
+	 * \param[in] n The new float data.
+	 */
+	NIFLIB_API void SetData( NiFloatData * n );
+
+	/*!
+	 * This function will adjust the times in all the keys in the data objects
+	 * referenced by this controller and any of its interpolators such that the
+	 * phase will equal 0 and frequency will equal one.  In other words, it
+	 * will cause the key times to be in seconds starting from zero.
+	 */
+	NIFLIB_API virtual void NormalizeKeys();
+
 	//--END CUSTOM CODE--//
 protected:
 	/*! Unknown. */
diff --git a/include/obj/NiTransformController.h b/include/obj/NiTransformController.h
index 237bc4d08c82dd934b0a20be623f66b0858dcddc..e88065a36756a4adb1aeba845e9603f2eeaa32b4 100644
--- a/include/obj/NiTransformController.h
+++ b/include/obj/NiTransformController.h
@@ -13,14 +13,14 @@ All rights reserved.  Please see niflib.h for license. */
 //--BEGIN FILE HEAD CUSTOM CODE--//
 //--END CUSTOM CODE--//
 
-#include "NiSingleInterpController.h"
+#include "NiKeyframeController.h"
 namespace Niflib {
 
 class NiTransformController;
 typedef Ref<NiTransformController> NiTransformControllerRef;
 
 /*! NiTransformController replaces the NiKeyframeController. */
-class NiTransformController : public NiSingleInterpController {
+class NiTransformController : public NiKeyframeController {
 public:
 	/*! Constructor */
 	NIFLIB_API NiTransformController();
diff --git a/src/gen/register.cpp b/src/gen/register.cpp
index 2152c518d071baf75a7a395b0cbb38c7e992ad7a..f08a84434b999ee914a9d8e5e9535f2725177189 100644
--- a/src/gen/register.cpp
+++ b/src/gen/register.cpp
@@ -72,6 +72,7 @@ All rights reserved.  Please see niflib.h for license. */
 #include "../../include/obj/NiMultiTargetTransformController.h"
 #include "../../include/obj/NiGeomMorpherController.h"
 #include "../../include/obj/NiSingleInterpController.h"
+#include "../../include/obj/NiKeyframeController.h"
 #include "../../include/obj/NiTransformController.h"
 #include "../../include/obj/NiPSysModifierCtlr.h"
 #include "../../include/obj/NiPSysEmitterCtlr.h"
@@ -152,7 +153,6 @@ All rights reserved.  Please see niflib.h for license. */
 #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/NiLookAtController.h"
@@ -324,6 +324,7 @@ namespace Niflib {
 		ObjectRegistry::RegisterObject( "NiMultiTargetTransformController", NiMultiTargetTransformController::Create );
 		ObjectRegistry::RegisterObject( "NiGeomMorpherController", NiGeomMorpherController::Create );
 		ObjectRegistry::RegisterObject( "NiSingleInterpController", NiSingleInterpController::Create );
+		ObjectRegistry::RegisterObject( "NiKeyframeController", NiKeyframeController::Create );
 		ObjectRegistry::RegisterObject( "NiTransformController", NiTransformController::Create );
 		ObjectRegistry::RegisterObject( "NiPSysModifierCtlr", NiPSysModifierCtlr::Create );
 		ObjectRegistry::RegisterObject( "NiPSysEmitterCtlr", NiPSysEmitterCtlr::Create );
@@ -404,7 +405,6 @@ namespace Niflib {
 		ObjectRegistry::RegisterObject( "NiIntegerExtraData", NiIntegerExtraData::Create );
 		ObjectRegistry::RegisterObject( "BSXFlags", BSXFlags::Create );
 		ObjectRegistry::RegisterObject( "NiIntegersExtraData", NiIntegersExtraData::Create );
-		ObjectRegistry::RegisterObject( "NiKeyframeController", NiKeyframeController::Create );
 		ObjectRegistry::RegisterObject( "BSKeyframeController", BSKeyframeController::Create );
 		ObjectRegistry::RegisterObject( "NiKeyframeData", NiKeyframeData::Create );
 		ObjectRegistry::RegisterObject( "NiLookAtController", NiLookAtController::Create );
diff --git a/src/obj/NiAlphaController.cpp b/src/obj/NiAlphaController.cpp
index 6836fe7c82807f48b234742a61c0b89ab61a1ee7..5ffc46bd5f5a72d1aa60afaa418fe2e56796472b 100644
--- a/src/obj/NiAlphaController.cpp
+++ b/src/obj/NiAlphaController.cpp
@@ -8,6 +8,7 @@ All rights reserved.  Please see niflib.h for license. */
 //-----------------------------------NOTICE----------------------------------//
 
 //--BEGIN FILE HEAD CUSTOM CODE--//
+#include "../../include/obj/NiFloatInterpolator.h"
 //--END CUSTOM CODE--//
 
 #include "../../include/FixLink.h"
@@ -110,4 +111,26 @@ std::list<NiObjectRef> NiAlphaController::GetRefs() const {
 }
 
 //--BEGIN MISC CUSTOM CODE--//
+
+Ref<NiFloatData> NiAlphaController::GetData() const {
+	return data;
+}
+
+void NiAlphaController::SetData( NiFloatData * n ) {
+	data = n;
+}
+
+void NiAlphaController::NormalizeKeys() {
+	// If data is not the same as The interpolator data, which will be
+	// normalized by the call to NiSingleInterpController's version of
+	// this function, then normalize it here.
+	NiFloatInterpolatorRef interp = DynamicCast<NiFloatInterpolator>(interpolator);
+	if ( (interp->GetData() != data) && ( data != NULL ) ) {
+		data->NormalizeKeys( this->phase, this->frequency );
+	}
+
+	//Call the parent version of this function to finish up
+	NiSingleInterpController::NormalizeKeys();
+}
+
 //--END CUSTOM CODE--//
diff --git a/src/obj/NiKeyframeController.cpp b/src/obj/NiKeyframeController.cpp
index b14a55234148cf70fe926a1af313f04b8d9b928c..0c8c4f78e1eca4e2aeb34b566e61514562c09d4b 100644
--- a/src/obj/NiKeyframeController.cpp
+++ b/src/obj/NiKeyframeController.cpp
@@ -18,7 +18,7 @@ All rights reserved.  Please see niflib.h for license. */
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type NiKeyframeController::TYPE("NiKeyframeController", &NiTimeController::TYPE );
+const Type NiKeyframeController::TYPE("NiKeyframeController", &NiSingleInterpController::TYPE );
 
 NiKeyframeController::NiKeyframeController() : data(NULL) {
 	//--BEGIN CONSTRUCTOR CUSTOM CODE--//
@@ -43,9 +43,11 @@ void NiKeyframeController::Read( istream& in, list<unsigned int> & link_stack, c
 	//--END CUSTOM CODE--//
 
 	unsigned int block_num;
-	NiTimeController::Read( in, link_stack, info );
-	NifStream( block_num, in, info );
-	link_stack.push_back( block_num );
+	NiSingleInterpController::Read( in, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		NifStream( block_num, in, info );
+		link_stack.push_back( block_num );
+	};
 
 	//--BEGIN POST-READ CUSTOM CODE--//
 	//--END CUSTOM CODE--//
@@ -55,16 +57,18 @@ void NiKeyframeController::Write( ostream& out, const map<NiObjectRef,unsigned i
 	//--BEGIN PRE-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
 
-	NiTimeController::Write( out, link_map, info );
-	if ( info.version < VER_3_3_0_13 ) {
-		NifStream( (unsigned int)&(*data), out, info );
-	} else {
-		if ( data != NULL ) {
-			NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+	NiSingleInterpController::Write( out, link_map, info );
+	if ( info.version <= 0x0A010000 ) {
+		if ( info.version < VER_3_3_0_13 ) {
+			NifStream( (unsigned int)&(*data), out, info );
 		} else {
-			NifStream( 0xFFFFFFFF, out, info );
+			if ( data != NULL ) {
+				NifStream( link_map.find( StaticCast<NiObject>(data) )->second, out, info );
+			} else {
+				NifStream( 0xFFFFFFFF, out, info );
+			}
 		}
-	}
+	};
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
@@ -76,7 +80,7 @@ std::string NiKeyframeController::asString( bool verbose ) const {
 
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiTimeController::asString();
+	out << NiSingleInterpController::asString();
 	out << "  Data:  " << data << endl;
 	return out.str();
 
@@ -88,8 +92,10 @@ void NiKeyframeController::FixLinks( const map<unsigned int,NiObjectRef> & objec
 	//--BEGIN PRE-FIXLINKS CUSTOM CODE--//
 	//--END CUSTOM CODE--//
 
-	NiTimeController::FixLinks( objects, link_stack, info );
-	data = FixLink<NiKeyframeData>( objects, link_stack, info );
+	NiSingleInterpController::FixLinks( objects, link_stack, info );
+	if ( info.version <= 0x0A010000 ) {
+		data = FixLink<NiKeyframeData>( objects, link_stack, info );
+	};
 
 	//--BEGIN POST-FIXLINKS CUSTOM CODE--//
 	//--END CUSTOM CODE--//
@@ -97,7 +103,7 @@ void NiKeyframeController::FixLinks( const map<unsigned int,NiObjectRef> & objec
 
 std::list<NiObjectRef> NiKeyframeController::GetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiTimeController::GetRefs();
+	refs = NiSingleInterpController::GetRefs();
 	if ( data != NULL )
 		refs.push_back(StaticCast<NiObject>(data));
 	return refs;
diff --git a/src/obj/NiTextureTransformController.cpp b/src/obj/NiTextureTransformController.cpp
index 15bc74019fbfd8a06182fc72da95b28367cd1408..057176768569126f7e0fe5f8a9dc03d32766651c 100644
--- a/src/obj/NiTextureTransformController.cpp
+++ b/src/obj/NiTextureTransformController.cpp
@@ -8,6 +8,7 @@ All rights reserved.  Please see niflib.h for license. */
 //-----------------------------------NOTICE----------------------------------//
 
 //--BEGIN FILE HEAD CUSTOM CODE--//
+#include "../../include/obj/NiFloatInterpolator.h"
 //--END CUSTOM CODE--//
 
 #include "../../include/FixLink.h"
@@ -119,4 +120,43 @@ std::list<NiObjectRef> NiTextureTransformController::GetRefs() const {
 }
 
 //--BEGIN MISC CUSTOM CODE--//
+
+TexType NiTextureTransformController::GetTargetTextureSlot() {
+	return textureSlot;
+}
+
+void NiTextureTransformController::SetTargetTextureSlot( TexType n ) {
+	textureSlot = n;
+}
+
+TexTransform NiTextureTransformController::GetTextureTransformType() {
+	return operation;
+}
+
+void NiTextureTransformController::SetTextureTransformType( TexTransform n ) {
+	operation = n;
+}
+
+Ref<NiFloatData> NiTextureTransformController::GetData() const {
+	return data;
+}
+
+void NiTextureTransformController::SetData( NiFloatData * n ) {
+	data = n;
+}
+
+void NiTextureTransformController::NormalizeKeys() {
+	// If data is not the same as The interpolator data, which will be
+	// normalized by the call to NiSingleInterpController's version of
+	// this function, then normalize it here.
+	NiFloatInterpolatorRef interp = DynamicCast<NiFloatInterpolator>(interpolator);
+	if ( (interp->GetData() != data) && ( data != NULL ) ) {
+		data->NormalizeKeys( this->phase, this->frequency );
+	}
+
+	//Call the parent version of this function to finish up
+	NiSingleInterpController::NormalizeKeys();
+}
+
+
 //--END CUSTOM CODE--//
diff --git a/src/obj/NiTransformController.cpp b/src/obj/NiTransformController.cpp
index 7dcd659ddf14cd52728d303125a52c796540325f..47d07dbae80f69111dd942e7558212d30f00d734 100644
--- a/src/obj/NiTransformController.cpp
+++ b/src/obj/NiTransformController.cpp
@@ -17,7 +17,7 @@ All rights reserved.  Please see niflib.h for license. */
 using namespace Niflib;
 
 //Definition of TYPE constant
-const Type NiTransformController::TYPE("NiTransformController", &NiSingleInterpController::TYPE );
+const Type NiTransformController::TYPE("NiTransformController", &NiKeyframeController::TYPE );
 
 NiTransformController::NiTransformController() {
 	//--BEGIN CONSTRUCTOR CUSTOM CODE--//
@@ -41,7 +41,7 @@ void NiTransformController::Read( istream& in, list<unsigned int> & link_stack,
 	//--BEGIN PRE-READ CUSTOM CODE--//
 	//--END CUSTOM CODE--//
 
-	NiSingleInterpController::Read( in, link_stack, info );
+	NiKeyframeController::Read( in, link_stack, info );
 
 	//--BEGIN POST-READ CUSTOM CODE--//
 	//--END CUSTOM CODE--//
@@ -51,7 +51,7 @@ void NiTransformController::Write( ostream& out, const map<NiObjectRef,unsigned
 	//--BEGIN PRE-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
 
-	NiSingleInterpController::Write( out, link_map, info );
+	NiKeyframeController::Write( out, link_map, info );
 
 	//--BEGIN POST-WRITE CUSTOM CODE--//
 	//--END CUSTOM CODE--//
@@ -63,7 +63,7 @@ std::string NiTransformController::asString( bool verbose ) const {
 
 	stringstream out;
 	unsigned int array_output_count = 0;
-	out << NiSingleInterpController::asString();
+	out << NiKeyframeController::asString();
 	return out.str();
 
 	//--BEGIN POST-STRING CUSTOM CODE--//
@@ -74,7 +74,7 @@ void NiTransformController::FixLinks( const map<unsigned int,NiObjectRef> & obje
 	//--BEGIN PRE-FIXLINKS CUSTOM CODE--//
 	//--END CUSTOM CODE--//
 
-	NiSingleInterpController::FixLinks( objects, link_stack, info );
+	NiKeyframeController::FixLinks( objects, link_stack, info );
 
 	//--BEGIN POST-FIXLINKS CUSTOM CODE--//
 	//--END CUSTOM CODE--//
@@ -82,7 +82,7 @@ void NiTransformController::FixLinks( const map<unsigned int,NiObjectRef> & obje
 
 std::list<NiObjectRef> NiTransformController::GetRefs() const {
 	list<Ref<NiObject> > refs;
-	refs = NiSingleInterpController::GetRefs();
+	refs = NiKeyframeController::GetRefs();
 	return refs;
 }
 
diff --git a/src/obj/NiVisController.cpp b/src/obj/NiVisController.cpp
index 0f51d039640e7251e335ee046adc296a19909658..37f99d12725a11a70f9ad9e6cdbb556ad6d531af 100644
--- a/src/obj/NiVisController.cpp
+++ b/src/obj/NiVisController.cpp
@@ -121,7 +121,9 @@ void NiVisController::SetData( NiVisData * n ) {
 
 void NiVisController::NormalizeKeys() {
 
-	//Normalize any keys that are stored in Morph Data
+	//Normalize any keys that are stored any NiVisData
+	//Future NIF versions use BoolData to store this,
+	//so no comparison to the Interpolator data is necessary.
 	if ( data != NULL ) {
 		data->NormalizeKeys( this->phase, this->frequency );
 	}