diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp
index e9e985f7aad755a8f5dd7406422d8456f9d0d3c3..4740457edef1a4d0d3e15afdf0d30cae93cd3a61 100644
--- a/NIF_Blocks.cpp
+++ b/NIF_Blocks.cpp
@@ -2124,35 +2124,34 @@ string NiKeyframeData::asString() {
 
 void NiColorData::Read( ifstream& file, unsigned int version ) {
 	uint keyCount = ReadUInt( file );
-	NifStream( keyType, file );
+	NifStream( _type, file );
 
-	keys.resize( keyCount );
-	for (uint i = 0; i < keys.size(); i++) {
-		NifStream( keys[i], file, keyType );
+	_keys.resize( keyCount );
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, _type );
 	}
 }
 
 void NiColorData::Write( ofstream& file, unsigned int version ) {
-	WriteUInt( uint(keys.size()), file );
-	NifStream( keyType, file );
+	WriteUInt( uint(_keys.size()), file );
+	NifStream( _type, file );
 
-	for (uint i = 0; i < keys.size(); i++) {
-		NifStream( keys[i], file, keyType );
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, _type );
 	}
 }
 
-
 string NiColorData::asString() {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
 
-	out << "Color Count:  " << uint(keys.size()) << endl
-		<< "Key Type:  " << keyType << endl;
+	out << "Key Count:  " << uint(_keys.size()) << endl
+		<< "Key Type:  " << _type << endl;
 
 	if (verbose) {
 		vector< Key<Color> >::iterator it;
-		for ( it = keys.begin(); it != keys.end(); ++it ) {
+		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
 			out << "Key Time:  " <<  it->time << "  Color:  " << it->data.r << ", " << it->data.g << ", " << it->data.b << ", " << it->data.a << endl;
 		}
 	} else {
@@ -2166,58 +2165,22 @@ string NiColorData::asString() {
  * NiFloatData methods
  **********************************************************/
 
-void NiFloatData::Read( ifstream& in, unsigned int version ) {	
-	uint keyCount = ReadUInt( in );
-	keyType = ReadUInt( in );
-
-	if (keyCount > 0 && (keyType < 1 || keyType > 3 ) ) {
-		stringstream s;
-		s << "NiFloatData is thought to only support keyType of 1, 2, or 3, but this NIF has a keyType of " << keyType << ".";
-		throw runtime_error(s.str());
-	}
+void NiFloatData::Read( ifstream& file, unsigned int version ) {
+	uint keyCount = ReadUInt( file );
+	NifStream( _type, file );
 
-	keys.resize( keyCount );
-	for (uint i = 0; i < keys.size(); i++) {
-		//Always read the time and data
-		keys[i].time = ReadFloat( in );
-		keys[i].data = ReadFloat( in );
-		if ( keyType == 2 ) {
-			//Uses Quadratic interpolation
-			keys[i].forward_tangent = ReadFloat( in );
-			keys[i].backward_tangent = ReadFloat( in );
-		} else if ( keyType == 3 ) {
-			//Uses TBC interpolation
-			keys[i].tension = ReadFloat( in );
-			keys[i].bias = ReadFloat( in );
-			keys[i].continuity = ReadFloat( in );
-		}
+	_keys.resize( keyCount );
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, _type );
 	}
 }
 
-void NiFloatData::Write( ofstream& out, unsigned int version ) {	
-	WriteUInt( uint(keys.size()), out );
-	WriteUInt( keyType, out );
-
-	if (keys.size() > 0 && (keyType < 1 || keyType > 3 ) ) {
-		stringstream s;
-		s << "NiFloatData is thought to only support keyType of 1, 2, or 3, but this NIF has a keyType of " << keyType << ".";
-		throw runtime_error(s.str());
-	}
+void NiFloatData::Write( ofstream& file, unsigned int version ) {
+	WriteUInt( uint(_keys.size()), file );
+	NifStream( _type, file );
 
-	for (uint i = 0; i < keys.size(); i++) {
-		//Always write the time and data
-		WriteFloat( keys[i].time, out );
-		WriteFloat( keys[i].data, out );
-		if ( keyType == 2 ) {
-			//Uses Quadratic interpolation
-			WriteFloat( keys[i].forward_tangent, out );
-			WriteFloat( keys[i].backward_tangent, out );
-		} else if ( keyType == 3 ) {
-			//Uses TBC interpolation
-			WriteFloat( keys[i].tension, out );
-			WriteFloat( keys[i].bias, out );
-			WriteFloat( keys[i].continuity, out );
-		}
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, _type );
 	}
 }
 
@@ -2226,30 +2189,18 @@ string NiFloatData::asString() {
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
 
-	out << "Key Count:  " << uint(keys.size()) << endl
-		<< "Key Type:  " << keyType << endl
-		<< "Keys:" << endl;
+	out << "Key Count:  " << uint(_keys.size()) << endl
+		<< "Key Type:  " << _type << endl;
 
 	if (verbose) {
-		vector<Key<float> >::iterator it;
-		for ( it = keys.begin(); it != keys.end(); ++it ) {
-			for (uint i = 0; i < keys.size(); i++) {
-				//Always print the time and data
-				out << "   " << i + 1 << ")   Time:  " << it->time << "   Data:  " << it->data;
-				if ( keyType == 2 ) {
-					//Uses Quadratic interpolation
-					out << "   FT:  " << it->forward_tangent << "   BT:  " << it->backward_tangent;
-				} else if ( keyType == 3 ) {
-					//Uses TBC interpolation
-					out << "   T:  " << it->tension << "   B:  " << it->bias << "   C:  " << it->continuity;
-				}
-				out << endl;
-			}
+		vector< Key<float> >::iterator it;
+		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
+			out << "Key Time:  " <<  it->time << "  Float Value:  " << it->data << endl;
 		}
 	} else {
-		out << "   <<Data Not Shown>>" << endl;
+		out << "<<Data Not Shown>>" << endl;
 	}
-	
+
 	return out.str();
 }
 
@@ -2826,46 +2777,22 @@ string NiPixelData::asString() {
  * NiPosData methods
  **********************************************************/
 
-void NiPosData::Read( ifstream& in, unsigned int version ) {
-	uint keyCount = ReadUInt( in );
-	keyType = ReadUInt( in );
-
-	keys.resize(keyCount);
-	for (uint i = 0; i < keys.size(); i++) {
-		keys[i].time = ReadFloat( in );
-		ReadFVector3( keys[i].data, in );
-
-		if (keyType == 2) {
-			ReadFVector3( keys[i].forward_tangent, in );
-			ReadFVector3( keys[i].backward_tangent, in );
-		}
+void NiPosData::Read( ifstream& file, unsigned int version ) {
+	uint keyCount = ReadUInt( file );
+	NifStream( _type, file );
 
-		if (keyType != 1 && keyType != 2) {
-			stringstream str;
-            str << "NiPosData is thought to only support keyTypes of 1 and 2, but this NIF has a keyType of " << keyType << ".";
-			throw runtime_error( str.str() );
-		}
+	_keys.resize( keyCount );
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, _type );
 	}
 }
 
-void NiPosData::Write( ofstream& out, unsigned int version ) {
-	WriteUInt( uint(keys.size()), out );
-	WriteUInt( keyType, out );
-
-	for (uint i = 0; i < keys.size(); i++) {
-		WriteFloat( keys[i].time, out );
-		WriteFVector3( keys[i].data, out );
-
-		if (keyType == 2) {
-			WriteFVector3( keys[i].forward_tangent, out );
-			WriteFVector3( keys[i].backward_tangent, out );
-		}
+void NiPosData::Write( ofstream& file, unsigned int version ) {
+	WriteUInt( uint(_keys.size()), file );
+	NifStream( _type, file );
 
-		if (keyType != 1 && keyType != 2) {
-			stringstream str;
-            str << "NiPosData is thought to only support keyTypes of 1 and 2, but this NIF has a keyType of " << keyType << ".";
-			throw runtime_error( str.str() );
-		}
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, _type );
 	}
 }
 
@@ -2874,22 +2801,18 @@ string NiPosData::asString() {
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
 
-	out << "Key Count:  " << uint(keys.size()) << endl
-		<< "Key Type:  " << keyType << endl;
+	out << "Key Count:  " << uint(_keys.size()) << endl
+		<< "Key Type:  " << _type << endl;
 
 	if (verbose) {
-		for (uint i = 0; i < keys.size(); i++) {
-			out << "Key Time:  " << keys[i].time << "   Position:  " << keys[i].data;
-
-			if (keyType == 2) {
-				out << " F: " << keys[i].forward_tangent << "  B: " << keys[i].backward_tangent;
-			}
-			out << endl;
+		vector< Key<Vector3> >::iterator it;
+		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
+			out << "Key Time:  " <<  it->time << "  Position:  " << it->data.x << ", " << it->data.y << ", " << it->data.z << endl;
 		}
 	} else {
 		out << "<<Data Not Shown>>" << endl;
 	}
-	
+
 	return out.str();
 }
 
@@ -2897,27 +2820,24 @@ string NiPosData::asString() {
  * NiTextKeyExtraData methods
  **********************************************************/
 
-void NiTextKeyExtraData::Read( ifstream& in, unsigned int version ) {
-	ABlock::Read( in, version );
-	
-	uint keyCount = ReadUInt( in );
+void NiTextKeyExtraData::Read( ifstream& file, unsigned int version ) {
+	uint keyCount = ReadUInt( file );
+	//Read type but throw it away, always LINEAR_KEY
+	ReadUInt( file );
 
-	_keys.resize(keyCount);
-	for (uint i = 0; i < _keys.size(); ++i ) {
-		_keys[i].time = ReadFloat( in );
-		_keys[i].data = ReadString( in );
+	_keys.resize( keyCount );
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, LINEAR_KEY );
 	}
 }
 
-void NiTextKeyExtraData::Write( ofstream& out, unsigned int version ) {
+void NiTextKeyExtraData::Write( ofstream& file, unsigned int version ) {
+	WriteUInt( uint(_keys.size()), file );
+	KeyType _type = LINEAR_KEY;
+	NifStream( _type, file );
 
-	ABlock::Write( out, version );
-
-	WriteUInt( uint(_keys.size()), out );
-
-	for (uint i = 0; i < _keys.size(); ++i ) {
-		WriteFloat( _keys[i].time, out );
-		WriteString( _keys[i].data, out );
+	for (uint i = 0; i < _keys.size(); i++) {
+		NifStream( _keys[i], file, LINEAR_KEY );
 	}
 }
 
@@ -2926,19 +2846,17 @@ string NiTextKeyExtraData::asString() {
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
 
-	out << "Next Extra Data:  " <<  GetAttr("Next Extra Data")->asLink() << endl
-		<< "Unknown Int (Key Type?):  " << GetAttr("Unknown Int")->asInt() << endl
-		<< "Key Count:  " << uint(_keys.size()) << endl;
+	out << "Key Count:  " << uint(_keys.size()) << endl;
 
 	if (verbose) {
-		for (uint i = 0; i < _keys.size(); ++i ) {
-			out << "Key Time:  " << _keys[i].time << endl
-				<< "Key Text:  " << _keys[i].data << endl;
+		vector< Key<string> >::iterator it;
+		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
+			out << "Key Time:  " <<  it->time << "  Key Text:  " << it->data << endl;
 		}
 	} else {
 		out << "<<Data Not Shown>>" << endl;
 	}
-	
+
 	return out.str();
 }
 
diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index 78afb0a43d58ff303790513212dfa6bac8db1b6a..5d012a0a97cbb0226b18420afa2306247f43cd34 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -1195,7 +1195,7 @@ public:
 	string GetBlockType() { return "NiGeomMorpherController"; }
 };
 
-class NiColorData : public AData {
+class NiColorData : public AData, public IColorData {
 public:
 	NiColorData() {}
 	~NiColorData() {}
@@ -1205,9 +1205,23 @@ public:
 	string asString();
 	string GetBlockType() { return "NiColorData"; };
 
+	void * QueryInterface( int id ) {
+		if ( id == ID_COLOR_DATA ) {
+			return (void*)static_cast<IColorData*>(this);;
+		} else {
+			return AData::QueryInterface( id );
+		}
+	}
+
+	//--IColorData Functions--//
+	KeyType GetKeyType() { return _type; }
+	void SetKeyType( KeyType t ) { _type = t; }
+	vector< Key<Color> > GetKeys() { return _keys; }
+	void SetKeys( vector< Key<Color> > & keys ) { _keys = keys; }
+
 private:
-	KeyType keyType;
-	vector< Key<Color> > keys;
+	KeyType _type;
+	vector<Key<Color> > _keys;
 };
 
 /**
@@ -1225,7 +1239,7 @@ private:
 	vector< pair< string, blk_ref> > controllers;
 };
 
-class NiFloatData : public AData {
+class NiFloatData : public AData, public IFloatData {
 public:
 	NiFloatData() {}
 	~NiFloatData() {}
@@ -1235,9 +1249,23 @@ public:
 	string asString();
 	string GetBlockType() { return "NiFloatData"; };
 
+	void * QueryInterface( int id ) {
+		if ( id == ID_FLOAT_DATA ) {
+			return (void*)static_cast<IFloatData*>(this);;
+		} else {
+			return AData::QueryInterface( id );
+		}
+	}
+
+	//--IFloatData Functions--//
+	KeyType GetKeyType() { return _type; }
+	void SetKeyType( KeyType t ) { _type = t; }
+	vector< Key<float> > GetKeys() { return _keys; }
+	void SetKeys( vector< Key<float> > & keys ) { _keys = keys; }
+
 private:
-	uint keyType;
-	vector<Key<float> > keys;
+	KeyType _type;
+	vector<Key<float> > _keys;
 };
 
 class NiStringExtraData : public AExtraData {
@@ -1316,7 +1344,7 @@ private:
 	vector<Morph> morphs;
 };
 
-class NiPosData : public AData {
+class NiPosData : public AData, public IPosData {
 public:
 	NiPosData() {}
 	~NiPosData() {}
@@ -1326,9 +1354,23 @@ public:
 	string asString();
 	string GetBlockType() { return "NiPosData"; }
 
+	void * QueryInterface( int id ) {
+		if ( id == ID_POS_DATA ) {
+			return (void*)static_cast<IPosData*>(this);;
+		} else {
+			return AData::QueryInterface( id );
+		}
+	}
+
+	//--IPosData Functions--//
+	KeyType GetKeyType() { return _type; }
+	void SetKeyType( KeyType t ) { _type = t; }
+	vector< Key<Vector3> > GetKeys() { return _keys; }
+	void SetKeys( vector< Key<Vector3> > & keys ) { _keys = keys; }
+
 private:
-	uint keyType;
-	vector<Key<fVector3> > keys;
+	KeyType _type;
+	vector<Key<Vector3> > _keys;
 };
 
 class NiRotatingParticlesData : public ARotatingParticlesData {
diff --git a/niflib.cpp b/niflib.cpp
index 1e1dbc116c55267fbf84a264c3082d51896506ae..68c342e52bb494932af36bddd1b85f6ca5cf2fb7 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -606,3 +606,15 @@ IMorphData * QueryMorphData ( blk_ref & block ) {
 ITriStripsData * QueryTriStripsData ( blk_ref & block ) {
 	return (ITriStripsData*)block->QueryInterface( ID_TRI_STRIPS_DATA );
 }
+
+IColorData * QueryColorData ( blk_ref & block ) {
+	return (IColorData*)block->QueryInterface( ID_COLOR_DATA );
+}
+
+IFloatData * QueryFloatData ( blk_ref & block ) {
+	return (IFloatData*)block->QueryInterface( ID_FLOAT_DATA );
+}
+
+IPosData * QueryPosData ( blk_ref & block ) {
+	return (IPosData*)block->QueryInterface( ID_POS_DATA );
+}
\ No newline at end of file
diff --git a/niflib.h b/niflib.h
index 6d97b537a07c7697e6b2c063fd9dea27ffdeae40..382f252537c7a6bab03b68575673db8dc022bddf 100644
--- a/niflib.h
+++ b/niflib.h
@@ -59,6 +59,9 @@ class IKeyframeData;
 class ITextKeyExtraData;
 class IMorphData;
 class ITriStripsData;
+class IColorData;
+class IFloatData;
+class IPosData;
 class INode;
 class blk_ref;
 class attr_ref;
@@ -80,6 +83,9 @@ const int ID_TEXT_KEY_EXTRA_DATA = 4;
 const int ID_MORPH_DATA = 5;
 const int ID_SHAPE_DATA = 6;
 const int ID_TRI_STRIPS_DATA = 7;
+const int ID_COLOR_DATA = 8;
+const int ID_FLOAT_DATA = 9;
+const int ID_POS_DATA = 10;
 
 //Attribute types
 enum AttrType {
@@ -146,6 +152,9 @@ IKeyframeData * QueryKeyframeData( blk_ref & block );
 ITextKeyExtraData * QueryTextKeyExtraData ( blk_ref & block );
 IMorphData * QueryMorphData ( blk_ref & block );
 ITriStripsData * QueryTriStripsData ( blk_ref & block );
+IColorData * QueryColorData ( blk_ref & block );
+IFloatData * QueryFloatData ( blk_ref & block );
+IPosData * QueryPosData ( blk_ref & block );
 
 //--Simple Structures--//
 
@@ -628,8 +637,40 @@ public:
 	virtual ~ITextKeyExtraData () {}
 	virtual vector< Key<string> > GetKeys() = 0;
 	virtual void SetKeys( vector< Key<string> > const & keys ) = 0;
+
+};
+
+class IColorData {
+public:
+	IColorData() {}
+	virtual ~IColorData () {}
+	virtual KeyType GetKeyType() = 0;
+	virtual void SetKeyType( KeyType t ) = 0;
+	virtual vector< Key<Color> > GetKeys() = 0;
+	virtual void SetKeys( vector< Key<Color> > & keys ) = 0;
 };
 
+class IFloatData {
+public:
+	IFloatData() {}
+	virtual ~IFloatData () {}
+	virtual KeyType GetKeyType() = 0;
+	virtual void SetKeyType( KeyType t ) = 0;
+	virtual vector< Key<float> > GetKeys() = 0;
+	virtual void SetKeys( vector< Key<float> > & keys ) = 0;
+};
+
+class IPosData {
+public:
+	IPosData() {}
+	virtual ~IPosData () {}
+	virtual KeyType GetKeyType() = 0;
+	virtual void SetKeyType( KeyType t ) = 0;
+	virtual vector< Key<Vector3> > GetKeys() = 0;
+	virtual void SetKeys( vector< Key<Vector3> > & keys ) = 0;
+};
+
+
 class IMorphData {
 public:
 	IMorphData() {}
diff --git a/pyniflib.i b/pyniflib.i
index 131d3642179ab553a02fb4e16bc0ce8774f3469a..1985d3f644adb917d79c3a520367ee6fa12f1bfd 100644
--- a/pyniflib.i
+++ b/pyniflib.i
@@ -95,6 +95,8 @@ struct Key {
 %template(vector_Key_Vector3) std::vector< Key<Vector3> >;
 %template(Key_float) Key<float>;
 %template(vector_Key_float) std::vector< Key<float> >;
+%template(Key_Color) Key<Color>;
+%template(vector_Key_Color) std::vector< Key<Color> >;
 %template(Key_string) Key<std::string>;
 %template(vector_Key_string) std::vector< Key<std::string> >;
 %template(blablabla) Key<double>;