diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp
index 2fb30b85b5579ef791c14700b416bf81e35c54be..d11239bb193c059d7b2d27e251c92b482bee33ff 100644
--- a/NIF_Blocks.cpp
+++ b/NIF_Blocks.cpp
@@ -172,7 +172,7 @@ blk_ref ABlock::GetParent() const {
 		return blk_ref(-1);
 }
 
-void ABlock::Read( ifstream& in, unsigned int version ) {
+void ABlock::Read( istream& in, unsigned int version ) {
 
 	//Read Attributes
 	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
@@ -191,7 +191,7 @@ void ABlock::Read( ifstream& in, unsigned int version ) {
 	//}
 }
 
-void ABlock::Write( ofstream& out, unsigned int version ) const {
+void ABlock::Write( ostream& out, unsigned int version ) const {
 
 	//Write Attributes
 	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
@@ -616,7 +616,7 @@ string NiNode::asString() const {
  * NiTexturingProperty methods
  **********************************************************/
 
-void NiTexturingProperty::Read( ifstream& file, unsigned int version ){
+void NiTexturingProperty::Read( istream& file, unsigned int version ){
 
 	AProperty::Read( file, version );
 
@@ -654,7 +654,7 @@ void NiTexturingProperty::Read( ifstream& file, unsigned int version ){
 	}
 }
 
-void NiTexturingProperty::Write( ofstream& file, unsigned int version ) const {
+void NiTexturingProperty::Write( ostream& file, unsigned int version ) const {
 
 	AProperty::Write( file, version );
 
@@ -899,7 +899,7 @@ void NiTexturingProperty::SetExtraTexture( int n, TexDesc & new_val ) {
  * NiBoneLODController methods
  **********************************************************/
 
-void NiBoneLODController::Read( ifstream& file, unsigned int version ){
+void NiBoneLODController::Read( istream& file, unsigned int version ){
 
 	AController::Read( file, version );
 
@@ -941,7 +941,7 @@ void NiBoneLODController::Read( ifstream& file, unsigned int version ){
 	
 }
 
-void NiBoneLODController::Write( ofstream& file, unsigned int version ) const {
+void NiBoneLODController::Write( ostream& file, unsigned int version ) const {
 	AController::Write( file, version );
 
 	WriteUInt( unkInt1, file );
@@ -1116,7 +1116,7 @@ NiBoneLODController::~NiBoneLODController() {
 /**
  * AShapeData::Read - Assumes block name has already been read from in
  */
-void AShapeData::Read( ifstream& in, unsigned int version ){
+void AShapeData::Read( istream& in, unsigned int version ){
 
 	GetAttr("Name")->Read( in, version );
 	
@@ -1302,7 +1302,7 @@ string AShapeData::asString() const {
 /**
  * AShapeData::Write
  */
-void AShapeData::Write( ofstream& out, unsigned int version ) const {
+void AShapeData::Write( ostream& out, unsigned int version ) const {
 
 	GetAttr("Name")->Write( out, version );
 	
@@ -1464,7 +1464,7 @@ void AShapeData::SetUVSet( int index, const vector<TexCoord> & in ) {
  * AParticlesData methods
  **********************************************************/
 
-void AParticlesData::Read( ifstream& in, unsigned int version ) {
+void AParticlesData::Read( istream& in, unsigned int version ) {
 	AShapeData::Read( in, version );
 
 	//numActive exists up to version 4.0.0.2
@@ -1491,7 +1491,7 @@ void AParticlesData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void AParticlesData::Write( ofstream& out, unsigned int version ) const {
+void AParticlesData::Write( ostream& out, unsigned int version ) const {
 	AShapeData::Write( out, version );
 
 	//numActive exists up to version 4.0.0.2
@@ -1550,7 +1550,7 @@ string AParticlesData::asString() const {
  * APSysData methods
  **********************************************************/
 
-void APSysData::Read( ifstream& file, unsigned int version ) {
+void APSysData::Read( istream& file, unsigned int version ) {
 	AShapeData::Read( file, version );
 
 	bool hasUnkFlts = ReadBool( file, version );
@@ -1574,7 +1574,7 @@ void APSysData::Read( ifstream& file, unsigned int version ) {
 	NifStream( unkByte, file );
 }
 
-void APSysData::Write( ofstream& file, unsigned int version ) const {
+void APSysData::Write( ostream& file, unsigned int version ) const {
 	AShapeData::Write( file, version );
 
 	WriteBool( unkFloats1.size() > 0, file, version );
@@ -1628,7 +1628,7 @@ string APSysData::asString() const {
  * NiMeshPSysData methods
  **********************************************************/
 
-void NiMeshPSysData::Read( ifstream& file, unsigned int version ) {
+void NiMeshPSysData::Read( istream& file, unsigned int version ) {
 	APSysData::Read( file, version );
 
 	unkFloats.resize( vertices.size() * 14 );
@@ -1644,7 +1644,7 @@ void NiMeshPSysData::Read( ifstream& file, unsigned int version ) {
 	NifStream( unk3Ints[2], file );
 }
 
-void NiMeshPSysData::Write( ofstream& file, unsigned int version ) const {
+void NiMeshPSysData::Write( ostream& file, unsigned int version ) const {
 	APSysData::Write( file, version );
 
 	NifStream( unkFloats, file );
@@ -1690,7 +1690,7 @@ string NiMeshPSysData::asString() const {
  * NiPSysData methods
  **********************************************************/
 
-void NiPSysData::Read( ifstream& file, unsigned int version ) {
+void NiPSysData::Read( istream& file, unsigned int version ) {
 	APSysData::Read( file, version );
 
 	//before version 20.0.0.4 there are unknown floats here
@@ -1721,7 +1721,7 @@ void NiPSysData::Read( ifstream& file, unsigned int version ) {
 	NifStream( unkInt, file );
 }
 
-void NiPSysData::Write( ofstream& file, unsigned int version ) const {
+void NiPSysData::Write( ostream& file, unsigned int version ) const {
 	APSysData::Write( file, version );
 
 	//before version 20.0.0.4 there are unknown floats here
@@ -1790,7 +1790,7 @@ string NiPSysData::asString() const {
  * ARotatingParticlesData methods
  **********************************************************/
 
-void ARotatingParticlesData::Read( ifstream& in, unsigned int version ) {
+void ARotatingParticlesData::Read( istream& in, unsigned int version ) {
 	AParticlesData::Read( in, version );
 
 	hasRotations = ReadBool( in, version );
@@ -1806,7 +1806,7 @@ void ARotatingParticlesData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void ARotatingParticlesData::Write( ofstream& out, unsigned int version ) const {
+void ARotatingParticlesData::Write( ostream& out, unsigned int version ) const {
 	AParticlesData::Write( out, version );
 
 	WriteBool( hasRotations, out, version );
@@ -1848,13 +1848,13 @@ string ARotatingParticlesData::asString() const {
  * NiParticleMeshesData methods
  **********************************************************/
 
-void NiParticleMeshesData::Read( ifstream& in, unsigned int version ) {
+void NiParticleMeshesData::Read( istream& in, unsigned int version ) {
 	ARotatingParticlesData::Read( in, version );
 
 	GetAttr("Unknown Link 2")->Read( in, version );
 }
 
-void NiParticleMeshesData::Write( ofstream& out, unsigned int version ) const {
+void NiParticleMeshesData::Write( ostream& out, unsigned int version ) const {
 	ARotatingParticlesData::Write( out, version );
 
 	GetAttr("Unknown Link 2")->Write( out, version );
@@ -1878,7 +1878,7 @@ string NiParticleMeshesData::asString() const {
 /**
  * NiTriShapeData::Read - Assumes block name has already been read from in
  */
-void NiTriShapeData::Read( ifstream& in, unsigned int version ){
+void NiTriShapeData::Read( istream& in, unsigned int version ){
 	AShapeData::Read( in, version );
 
 	short numTriangles = ReadUShort( in );
@@ -1946,7 +1946,7 @@ string NiTriShapeData::asString() const {
 /**
  * NiTriShapeData::Write - Writes block name to out, in addition to data.
  */
-void NiTriShapeData::Write( ofstream& out, unsigned int version ) const {
+void NiTriShapeData::Write( ostream& out, unsigned int version ) const {
 
 	AShapeData::Write( out, version );
 
@@ -2029,7 +2029,7 @@ void NiTriShapeData::SetTriangles( const vector<Triangle> & in ) {
  * NiTriStripsData methods
  **********************************************************/
 
-void NiTriStripsData::Read( ifstream& in, unsigned int version ){
+void NiTriStripsData::Read( istream& in, unsigned int version ){
 	AShapeData::Read( in, version );
 
 	//Read number of Triangles but discard it
@@ -2060,7 +2060,7 @@ void NiTriStripsData::Read( ifstream& in, unsigned int version ){
 	}
 }
 
-void NiTriStripsData::Write( ofstream& out, unsigned int version ) const {
+void NiTriStripsData::Write( ostream& out, unsigned int version ) const {
 
 	AShapeData::Write( out, version );
 
@@ -2197,7 +2197,7 @@ short NiTriStripsData::GetTriangleCount() const {
  * NiBSplineData methods
  **********************************************************/
 
-void NiBSplineData::Read( ifstream& file, unsigned int version ){
+void NiBSplineData::Read( istream& file, unsigned int version ){
 	NifStream( unkInt, file );
 	
 	uint count = ReadUInt( file );
@@ -2205,7 +2205,7 @@ void NiBSplineData::Read( ifstream& file, unsigned int version ){
 	NifStream( unkShorts, file );
 }
 
-void NiBSplineData::Write( ofstream& file, unsigned int version ) const {
+void NiBSplineData::Write( ostream& file, unsigned int version ) const {
 
 	NifStream( unkInt, file );
 
@@ -2233,7 +2233,7 @@ string NiBSplineData::asString() const {
  * NiCollisionData methods
  **********************************************************/
 
-void NiCollisionData::Read( ifstream& in, unsigned int version ){
+void NiCollisionData::Read( istream& in, unsigned int version ){
 	//Read parent node but don't store it
 	ReadUInt( in );
 
@@ -2257,7 +2257,7 @@ void NiCollisionData::Read( ifstream& in, unsigned int version ){
 	} 
 }
 
-void NiCollisionData::Write( ofstream& out, unsigned int version ) const {
+void NiCollisionData::Write( ostream& out, unsigned int version ) const {
 
 	//Write Parent node number
 	WriteUInt( GetParent().get_index(), out );
@@ -2318,7 +2318,7 @@ string NiCollisionData::asString() const {
  * NiSkinData methods
  **********************************************************/
 
-void NiSkinData::Read( ifstream& in, unsigned int version ) {
+void NiSkinData::Read( istream& in, unsigned int version ) {
 	
 	for (int c = 0; c < 3; ++c) {
 		for (int r = 0; r < 3; ++r) {
@@ -2353,7 +2353,7 @@ void NiSkinData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiSkinData::Write( ofstream& out, unsigned int version ) const {
+void NiSkinData::Write( ostream& out, unsigned int version ) const {
 	//Calculate offset matrices prior to writing data
 
 	Matrix33 rot;
@@ -2952,7 +2952,7 @@ string NiGeomMorpherController::asString() const {
  * AKeyframeData methods
  **********************************************************/
 
-void AKeyframeData::Read( ifstream& file, unsigned int version ) {
+void AKeyframeData::Read( istream& file, unsigned int version ) {
 
 	scaleType = rotationType = translationType = xyzTypes[0] = xyzTypes[1] = xyzTypes[2] = KeyType(0);
 
@@ -3013,7 +3013,7 @@ void AKeyframeData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void AKeyframeData::Write( ofstream& file, unsigned int version ) const {
+void AKeyframeData::Write( ostream& file, unsigned int version ) const {
 
 	//--Rotation--//
 	WriteUInt( uint(rotKeys.size()) , file );
@@ -3162,7 +3162,7 @@ string AKeyframeData::asString() const {
  * NiBoolData methods
  **********************************************************/
 
-void NiBoolData::Read( ifstream& file, unsigned int version ) {
+void NiBoolData::Read( istream& file, unsigned int version ) {
 	uint keyCount = ReadUInt( file );
 	NifStream( _type, file );
 
@@ -3172,7 +3172,7 @@ void NiBoolData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiBoolData::Write( ofstream& file, unsigned int version ) const {
+void NiBoolData::Write( ostream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -3210,7 +3210,7 @@ string NiBoolData::asString() const {
  * NiColorData methods
  **********************************************************/
 
-void NiColorData::Read( ifstream& file, unsigned int version ) {
+void NiColorData::Read( istream& file, unsigned int version ) {
 	uint keyCount = ReadUInt( file );
 	NifStream( _type, file );
 
@@ -3220,7 +3220,7 @@ void NiColorData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiColorData::Write( ofstream& file, unsigned int version ) const {
+void NiColorData::Write( ostream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -3253,7 +3253,7 @@ string NiColorData::asString() const {
  * NiControllerSequence methods
  **********************************************************/
 
-void NiControllerSequence::Read( ifstream& file, unsigned int version ) {
+void NiControllerSequence::Read( istream& file, unsigned int version ) {
 	GetAttr("Name")->Read( file, version );
 
 	//Read first ControllerLink
@@ -3270,7 +3270,7 @@ void NiControllerSequence::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiControllerSequence::Write( ofstream& file, unsigned int version ) const {
+void NiControllerSequence::Write( ostream& file, unsigned int version ) const {
 	GetAttr("Name")->Write( file, version );
 
 	//Write first ControllerLink
@@ -3404,7 +3404,7 @@ void NiControllerSequence::ClearControllers() {
  * NiFloatData methods
  **********************************************************/
 
-void NiFloatData::Read( ifstream& file, unsigned int version ) {
+void NiFloatData::Read( istream& file, unsigned int version ) {
 	uint keyCount = ReadUInt( file );
 	NifStream( _type, file );
 
@@ -3414,7 +3414,7 @@ void NiFloatData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiFloatData::Write( ofstream& file, unsigned int version ) const {
+void NiFloatData::Write( ostream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -3447,7 +3447,7 @@ string NiFloatData::asString() const {
  * NiStringExtraData methods
  **********************************************************/
 
-void NiStringExtraData::Read( ifstream& in, unsigned int version ) {
+void NiStringExtraData::Read( istream& in, unsigned int version ) {
 	AExtraData::Read( in, version );
 	
 	//GetAttr("Name")->Read( in, version );
@@ -3462,7 +3462,7 @@ void NiStringExtraData::Read( ifstream& in, unsigned int version ) {
 	GetAttr("String Data")->Read( in, version );
 }
 
-void NiStringExtraData::Write( ofstream& out, unsigned int version ) const {
+void NiStringExtraData::Write( ostream& out, unsigned int version ) const {
 	//GetAttr("Name")->Write( out, version );
 	//GetAttr("Next Extra Data")->Write( out, version );
 	AExtraData::Write( out, version );
@@ -3498,7 +3498,7 @@ string NiStringExtraData::asString() const {
  * NiMorphData methods
  **********************************************************/
 
-void NiMorphData::Read( ifstream& file, unsigned int version ) {
+void NiMorphData::Read( istream& file, unsigned int version ) {
 
 	uint morphCount = ReadUInt( file );
 	NifStream( vertCount, file );
@@ -3524,7 +3524,7 @@ void NiMorphData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiMorphData::Write( ofstream& file, unsigned int version ) const {
+void NiMorphData::Write( ostream& file, unsigned int version ) const {
 	WriteUInt( uint(morphs.size()), file );
 	NifStream( vertCount, file );
 
@@ -3605,7 +3605,7 @@ void NiMorphData::SetMorphVerts( int n, const vector<Vector3> & in ) {
  * NiPalette methods
  **********************************************************/
 
-void NiPalette::Read( ifstream& file, unsigned int version ) {
+void NiPalette::Read( istream& file, unsigned int version ) {
 
 	NifStream( unkByte, file );
 	NifStream( numEntries, file );
@@ -3619,7 +3619,7 @@ void NiPalette::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiPalette::Write( ofstream& file, unsigned int version ) const {
+void NiPalette::Write( ostream& file, unsigned int version ) const {
 
 	NifStream( unkByte, file );
 	NifStream( numEntries, file );
@@ -3690,7 +3690,7 @@ void NiPalette::SetPalette( const vector<Color4> & new_pal ) {
  * NiSkinPartition methods
  **********************************************************/
 
-void NiSkinPartition::Read( ifstream& file, unsigned int version ) {
+void NiSkinPartition::Read( istream& file, unsigned int version ) {
 
 	uint numPartitions = ReadUInt( file );
 	partitions.resize( numPartitions );
@@ -3778,7 +3778,7 @@ void NiSkinPartition::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiSkinPartition::Write( ofstream& file, unsigned int version ) const {
+void NiSkinPartition::Write( ostream& file, unsigned int version ) const {
 
 	WriteUInt( uint(partitions.size()), file );
 
@@ -3908,7 +3908,7 @@ string NiSkinPartition::asString() const {
  * NiStringPalette methods
  **********************************************************/
 
-void NiStringPalette::Read( ifstream& file, unsigned int version ) {
+void NiStringPalette::Read( istream& file, unsigned int version ) {
 
 	GetAttr("Palette")->Read( file, version );
 
@@ -3916,7 +3916,7 @@ void NiStringPalette::Read( ifstream& file, unsigned int version ) {
 	ReadUInt( file );
 }
 
-void NiStringPalette::Write( ofstream& file, unsigned int version ) const {
+void NiStringPalette::Write( ostream& file, unsigned int version ) const {
 
 	attr_ref pal_attr = GetAttr("Palette");
 	pal_attr->Write( file, version );
@@ -3948,7 +3948,7 @@ string NiStringPalette::asString() const {
  * NiPixelData methods
  **********************************************************/
 
-void NiPixelData::Read( ifstream& file, unsigned int version ) {
+void NiPixelData::Read( istream& file, unsigned int version ) {
 	//ABlock::Read( in, version );
 
 	pxFormat = PixelFormat( ReadUInt(file) );
@@ -4002,7 +4002,7 @@ void NiPixelData::Read( ifstream& file, unsigned int version ) {
 	file.read( (char *)data, dataSize);
 }
 
-void NiPixelData::Write( ofstream& file, unsigned int version ) const {
+void NiPixelData::Write( ostream& file, unsigned int version ) const {
 	//ABlock::Write( file, version );
 
 	WriteUInt( uint(pxFormat), file );
@@ -4463,7 +4463,7 @@ void NiPixelData::SetColors( const vector<Color4> & new_pixels, bool generate_mi
  * NiPosData methods
  **********************************************************/
 
-void NiPosData::Read( ifstream& file, unsigned int version ) {
+void NiPosData::Read( istream& file, unsigned int version ) {
 	uint keyCount = ReadUInt( file );
 	NifStream( _type, file );
 
@@ -4473,7 +4473,7 @@ void NiPosData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiPosData::Write( ofstream& file, unsigned int version ) const {
+void NiPosData::Write( ostream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -4506,7 +4506,7 @@ string NiPosData::asString() const {
  * NiTextKeyExtraData methods
  **********************************************************/
 
-void NiTextKeyExtraData::Read( ifstream& file, unsigned int version ) {
+void NiTextKeyExtraData::Read( istream& file, unsigned int version ) {
 	/*GetAttr("Name")->Read( file, version );
 	GetAttr("Next Extra Data")->Read( file, version );
 	*/
@@ -4521,7 +4521,7 @@ void NiTextKeyExtraData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiTextKeyExtraData::Write( ofstream& file, unsigned int version ) const {
+void NiTextKeyExtraData::Write( ostream& file, unsigned int version ) const {
 
 	/*GetAttr("Name")->Write( file, version );
 	GetAttr("Next Extra Data")->Write( file, version );
@@ -4562,7 +4562,7 @@ string NiTextKeyExtraData::asString() const {
  * NiUVData methods
  **********************************************************/
 
-void NiUVData::Read( ifstream& in, unsigned int version ) {	
+void NiUVData::Read( istream& in, unsigned int version ) {	
 	for (uint i = 0; i < 4; ++i) {
 		uint count = ReadUInt( in );
 
@@ -4583,7 +4583,7 @@ void NiUVData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiUVData::Write( ofstream& out, unsigned int version ) const {
+void NiUVData::Write( ostream& out, unsigned int version ) const {
 	for (uint i = 0; i < 4; ++i) {
 		WriteUInt( uint(groups[i].keys.size()), out );
 
@@ -4637,7 +4637,7 @@ string NiUVData::asString() const {
  * NiVertWeightsExtraData methods
  **********************************************************/
  
-void NiVertWeightsExtraData::Read( ifstream& in, unsigned int version ) {
+void NiVertWeightsExtraData::Read( istream& in, unsigned int version ) {
 	AExtraData::Read( in, version );
 
 	//Read byte count but throw it away
@@ -4651,7 +4651,7 @@ void NiVertWeightsExtraData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiVertWeightsExtraData::Write( ofstream& out, unsigned int version ) const {
+void NiVertWeightsExtraData::Write( ostream& out, unsigned int version ) const {
 	AExtraData::Write( out, version );
 
 	uint bytes = 2 + 4 * uint(weights.size());
@@ -4688,7 +4688,7 @@ string NiVertWeightsExtraData::asString() const {
  * NiVisData methods
  **********************************************************/
 
-void NiVisData ::Read( ifstream& in, unsigned int version ) {
+void NiVisData ::Read( istream& in, unsigned int version ) {
 	uint keyCount = ReadUInt( in );
 
 	keys.resize( keyCount );
@@ -4698,7 +4698,7 @@ void NiVisData ::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiVisData ::Write( ofstream& out, unsigned int version ) const {
+void NiVisData ::Write( ostream& out, unsigned int version ) const {
 	WriteUInt( uint(keys.size()), out );
 
 	for (uint i = 0; i < keys.size(); ++i) {
@@ -4729,7 +4729,7 @@ string NiVisData::asString() const {
  * NiLookAtInterpolator methods
  **********************************************************/
 
-//void NiLookAtInterpolator::Read( ifstream& file, unsigned int version ) {
+//void NiLookAtInterpolator::Read( istream& file, unsigned int version ) {
 //	
 //	GetAttr("Unknown Short")->Read( file, version );
 //	
@@ -4746,7 +4746,7 @@ string NiVisData::asString() const {
 //	}
 //}
 //
-//void NiLookAtInterpolator::Write( ofstream& file, unsigned int version ) const {
+//void NiLookAtInterpolator::Write( ostream& file, unsigned int version ) const {
 //
 //}
 //
@@ -4763,7 +4763,7 @@ string NiVisData::asString() const {
  * UnknownMixIn methods
  **********************************************************/
 
-void UnknownMixIn::Read( ifstream &in, unsigned int version ) {
+void UnknownMixIn::Read( istream &in, unsigned int version ) {
 	len = BlockSearch(in);
 
 	//Create byte array and read in unknown block
@@ -4800,7 +4800,7 @@ string UnknownMixIn::asString() const {
 	return out.str();
 }
 
-void UnknownMixIn::Write( ofstream& out, unsigned int version ) const {
+void UnknownMixIn::Write( ostream& out, unsigned int version ) const {
 	out.write( (const char*)data, len );
 }
 
diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index b1d79eb71b1ac71acd5050daeb508d1dbb62bd54..4accae6afc6560b69b1ebe1f4899fa7e93fae9d6 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -86,8 +86,8 @@ public:
 	virtual void DecCrossRef( IBlock * block ) = 0;
 
 	//File I/O
-	virtual void Read( ifstream& in, unsigned int version ) = 0;
-	virtual void Write( ofstream& out, unsigned int version ) const = 0;	
+	virtual void Read( istream& in, unsigned int version ) = 0;
+	virtual void Write( ostream& out, unsigned int version ) const = 0;	
 };
 
 class ABlock : public IBlock/*, public IBlockInternal*/ {
@@ -143,8 +143,8 @@ public:
 	void IncCrossRef( IBlock * block );
 	void DecCrossRef( IBlock * block );
 
-	virtual void Read( ifstream& in, unsigned int version );
-	virtual void Write( ofstream& out, unsigned int version ) const;
+	virtual void Read( istream& in, unsigned int version );
+	virtual void Write( ostream& out, unsigned int version ) const;
 protected:
 	map<string, attr_ref> _attr_map;
 	vector<attr_ref> _attr_vect;
@@ -184,7 +184,7 @@ public:
 	void InitAttrs();
 	void * QueryInterface( int id );
 	void const * QueryInterface( int id ) const;
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		ABlock::Read( in, version );
 		Matrix44 transform;
 		transform = GetLocalTransform();
@@ -292,11 +292,11 @@ public:
 		AddAttr( attr_link, "Next Extra Data", 0, VER_4_2_2_0 );
 	}
 	~AExtraData() {};
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		GetAttr("Name")->Read( in, version );
 		GetAttr("Next Extra Data")->Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		GetAttr("Name")->Write( out, version );
 		GetAttr("Next Extra Data")->Write( out, version );
 	}
@@ -564,8 +564,8 @@ public:
 	~NiTexturingProperty();
 	string GetBlockType() const { return "NiTexturingProperty"; }
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	void FixLinks( const vector<blk_ref> & blocks );
@@ -641,8 +641,8 @@ public:
 	}
 	~NiPixelData() { if (data != NULL) delete [] data; }
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiPixelData"; }
 
@@ -763,8 +763,8 @@ public:
 		AddAttr( attr_link, "Unknown Link", VER_20_0_0_4 );
 	}
 	~AShapeData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	void * QueryInterface( int id );
@@ -805,8 +805,8 @@ public:
 		AddAttr( attr_short, "Unknown Short", VER_4_1_0_12 );
 	}
 	~AParticlesData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 protected:
 	bool hasSizes;
@@ -822,8 +822,8 @@ class APSysData : public AShapeData {
 public:
 	APSysData() {}
 	~APSysData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 protected:
 	vector<float> unkFloats1;
@@ -840,8 +840,8 @@ class NiMeshPSysData : public APSysData {
 public:
 	NiMeshPSysData() {}
 	~NiMeshPSysData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiMeshPSysData"; };
 protected:
@@ -859,8 +859,8 @@ class NiPSysData : public APSysData {
 public:
 	NiPSysData() {}
 	~NiPSysData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiPSysData"; };
 protected:
@@ -881,8 +881,8 @@ class ARotatingParticlesData : public AParticlesData {
 public:
 	ARotatingParticlesData() {}
 	~ARotatingParticlesData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 protected:
 	bool hasRotations;
@@ -899,8 +899,8 @@ public:
 		AddAttr( attr_link, "Unknown Link 2" );
 	}
 	~NiParticleMeshesData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiParticleMeshesData"; }
@@ -926,8 +926,8 @@ class NiTriShapeData : public AShapeData, public ITriShapeData {
 public:
 	NiTriShapeData() : match_group_mode(false) {}
 	~NiTriShapeData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiTriShapeData"; }
 	void * QueryInterface( int id );
@@ -957,8 +957,8 @@ class NiTriStripsData : public AShapeData, public ITriStripsData {
 public:
 	NiTriStripsData() {}
 	~NiTriStripsData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiTriStripsData"; }
@@ -999,8 +999,8 @@ class NiBSplineData : public AData {
 public:
 	NiBSplineData() {}
 	~NiBSplineData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiBSplineData"; }
@@ -1016,8 +1016,8 @@ class NiCollisionData : public AData {
 public:
 	NiCollisionData() {}
 	~NiCollisionData() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiCollisionData"; }
@@ -1095,8 +1095,8 @@ public:
 	~NiBoneLODController();
 	string GetBlockType() const { return "NiBoneLODController"; }
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	void FixLinks( const vector<blk_ref> & blocks );
@@ -1683,8 +1683,8 @@ class AKeyframeData : public AData, public IKeyframeData {
 		AKeyframeData() {}
 		~AKeyframeData() {}
 
-		void Read( ifstream& in, unsigned int version );
-		void Write( ofstream& out, unsigned int version ) const;
+		void Read( istream& in, unsigned int version );
+		void Write( ostream& out, unsigned int version ) const;
 		string asString() const;
 		string GetBlockType() const { return "AKeyframeData"; }
 		
@@ -1766,8 +1766,8 @@ public:
 	NiPalette() {}
 	void Init() {}
 	~NiPalette() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiPalette"; }
@@ -1807,8 +1807,8 @@ public:
 	NiSkinPartition() {}
 	void Init() {}
 	~NiSkinPartition() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiSkinPartition"; }
@@ -1833,8 +1833,8 @@ public:
 	NiStringPalette() { AddAttr( attr_string, "Palette" ); }
 	void Init() {}
 	~NiStringPalette() {}
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiStringPalette"; }
@@ -1849,7 +1849,7 @@ public:
 class ISkinInstInternal {
 public:
 	virtual vector<int> GetBoneList() const = 0;
-	virtual void ReadBoneList( ifstream& in ) = 0;
+	virtual void ReadBoneList( istream& in ) = 0;
 };
 
 class NiSkinInstance : public AData, public ISkinInstInternal {
@@ -1882,7 +1882,7 @@ public:
 
 	vector<int> GetBoneList() const { return bones; }
 
-	void ReadBoneList( ifstream& in ) {
+	void ReadBoneList( istream& in ) {
 		int len = ReadUInt( in );
 		bones.resize( len );
 		for (int i = 0; i < len; ++i ) {
@@ -1917,8 +1917,8 @@ class NiSkinData : public AData, public ISkinData, public ISkinDataInternal {
 		}
 		~NiSkinData();
 
-		void Read( ifstream& in, unsigned int version );
-		void Write( ofstream& out, unsigned int version ) const;
+		void Read( istream& in, unsigned int version );
+		void Write( ostream& out, unsigned int version ) const;
 		string asString() const;
 		string GetBlockType() const { return "NiSkinData"; }
 		void * QueryInterface( int id );
@@ -1976,8 +1976,8 @@ public:
 	NiBoolData() {}
 	~NiBoolData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiBoolData"; };
 
@@ -2012,8 +2012,8 @@ public:
 	NiColorData() {}
 	~NiColorData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiColorData"; };
 
@@ -2053,8 +2053,8 @@ public:
 	}
 	~NiControllerSequence();
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 
 	string GetBlockType() const { return "NiControllerSequence"; }
@@ -2093,8 +2093,8 @@ public:
 	NiFloatData() {}
 	~NiFloatData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiFloatData"; };
 
@@ -2131,8 +2131,8 @@ public:
 	}
 	~NiStringExtraData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiStringExtraData"; }
 };
@@ -2145,11 +2145,11 @@ public:
 	~NiBooleanExtraData() {}
 	string GetBlockType() const { return "NiBooleanExtraData"; };
 
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
 		GetAttr("Boolean Data")->Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		AExtraData::Write( out, version );
 		GetAttr("Boolean Data")->Write( out, version );
 	}
@@ -2173,11 +2173,11 @@ public:
 	~NiColorExtraData() {}
 	string GetBlockType() const { return "NiColorExtraData"; };
 
-	void Read( ifstream& file, unsigned int version ) {
+	void Read( istream& file, unsigned int version ) {
 		AExtraData::Read( file, version );
 		NifStream( color, file );
 	}
-	void Write( ofstream& file, unsigned int version ) const {
+	void Write( ostream& file, unsigned int version ) const {
 		AExtraData::Write( file, version );
 		NifStream( color, file );
 	}
@@ -2204,11 +2204,11 @@ public:
 	~NiFloatExtraData() {}
 	string GetBlockType() const { return "NiFloatExtraData"; };
 
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
 		GetAttr("Float Data")->Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		AExtraData::Write( out, version );
 		GetAttr("Float Data")->Write( out, version );
 	}
@@ -2232,13 +2232,13 @@ public:
 	~NiFloatsExtraData() {}
 	string GetBlockType() const { return "NiFloatsExtraData"; };
 
-	void Read( ifstream& file, unsigned int version ) {
+	void Read( istream& file, unsigned int version ) {
 		AExtraData::Read( file, version );
 		uint count = ReadUInt( file );
 		float_data.resize( count );
 		NifStream( float_data, file );
 	}
-	void Write( ofstream& file, unsigned int version ) const {
+	void Write( ostream& file, unsigned int version ) const {
 		AExtraData::Write( file, version );
 		WriteUInt( uint(float_data.size()), file );
 		NifStream( float_data, file );
@@ -2271,11 +2271,11 @@ public:
 
 	string GetBlockType() const { return "NiIntegerExtraData"; };
 
-		void Read( ifstream& in, unsigned int version ) {
+		void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
 		GetAttr("Integer Data")->Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		AExtraData::Write( out, version );
 		GetAttr("Integer Data")->Write( out, version );
 	}
@@ -2299,8 +2299,8 @@ public:
 	}
 	~NiMorphData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiMorphData"; };
 
@@ -2349,8 +2349,8 @@ public:
 	NiPosData() {}
 	~NiPosData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiPosData"; }
 
@@ -2404,8 +2404,8 @@ public:
 	}
 	~NiTextKeyExtraData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiTextKeyExtraData"; }
 
@@ -2437,8 +2437,8 @@ public:
 	NiUVData() {}
 	~NiUVData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiUVData"; }
 
@@ -2455,8 +2455,8 @@ public:
 	NiVertWeightsExtraData() {}
 	~NiVertWeightsExtraData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiVertWeightsExtraData"; }
 
@@ -2470,8 +2470,8 @@ public:
 	NiVisData() {}
 	~NiVisData() {}
 
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return "NiVisData"; }
 
@@ -2486,8 +2486,8 @@ public:
 		_block_type = block_type;
 	}
 	~UnknownMixIn() { if (data != NULL) delete [] data; }
-	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version ) const;
+	void Read( istream& in, unsigned int version );
+	void Write( ostream& out, unsigned int version ) const;
 	string asString() const;
 	string GetBlockType() const { return _block_type; }
 
@@ -2501,12 +2501,12 @@ class UnknownBlock : public ABlock, public UnknownMixIn {
 public:
 	UnknownBlock( string block_type ) : UnknownMixIn(block_type) {}
 	~UnknownBlock() {}
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		//cout << endl << "Unknown Block Type found:  " << GetBlockType() << "\a" << endl;
 		ABlock::Read( in, version );
 		UnknownMixIn::Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		ABlock::Write( out, version );
 		UnknownMixIn::Write( out, version );
 	}
@@ -2521,11 +2521,11 @@ class UnknownControllerBlock : public AController, public UnknownMixIn {
 public:
 	UnknownControllerBlock( string block_type ) : UnknownMixIn(block_type) {}
 	~UnknownControllerBlock() {}
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		ABlock::Read( in, version );
 		UnknownMixIn::Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		ABlock::Write( out, version );
 		UnknownMixIn::Write( out, version );
 	}
@@ -2546,11 +2546,11 @@ class UnknownPropertyBlock : public AProperty, public UnknownMixIn {
 public:
 	UnknownPropertyBlock( string block_type ) : UnknownMixIn(block_type) {}
 	~UnknownPropertyBlock() {}
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		ABlock::Read( in, version );
 		UnknownMixIn::Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		ABlock::Write( out, version );
 		UnknownMixIn::Write( out, version );
 	}
@@ -2656,8 +2656,8 @@ public:
 	//	Init();
 	//}
 
-	//void Read( ifstream& in, unsigned int version );
-	//void Write( ofstream& out, unsigned int version ) const;
+	//void Read( istream& in, unsigned int version );
+	//void Write( ostream& out, unsigned int version ) const;
 	//string asString() const;
 
 	void Init() {}
diff --git a/NIF_IO.cpp b/NIF_IO.cpp
index 5be46669cb4b69c7461a47b591b4e91b904bab3b..e9fa2bbae0d3d31d4a4d732f72ad732e8821bfd1 100644
--- a/NIF_IO.cpp
+++ b/NIF_IO.cpp
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 #include "NIF_IO.h"
 //#include "NIF.h"
-int BlockSearch( ifstream& in ) {
+int BlockSearch( istream& in ) {
 
 	//Get current file pos
 	int data_start = in.tellg();
@@ -165,55 +165,55 @@ ostream & operator<<(ostream & lh, nifAlphaFormat const & rh) {
 /**
  * Read utility functions
  */
-uint ReadUInt( ifstream& in ){
+uint ReadUInt( istream& in ){
 
 	uint tmp;
 	in.read( (char*)&tmp, 4 );
 	return tmp;
 }
 
-ushort ReadUShort( ifstream& in ){
+ushort ReadUShort( istream& in ){
 
 	ushort tmp;
 	in.read( (char*)&tmp, 2 );
 	return tmp;
 }
 
-byte ReadByte( ifstream& in ){
+byte ReadByte( istream& in ){
 
 	byte tmp;
 	in.read( (char*)&tmp, 1 );
 	return tmp;
 }
 
-void ReadUSVector3( usVector3& vec, ifstream& in ){
+void ReadUSVector3( usVector3& vec, istream& in ){
 
 	vec[0] = ReadUShort( in );
 	vec[1] = ReadUShort( in );
 	vec[2] = ReadUShort( in );
 }
 
-float ReadFloat( ifstream &in ){
+float ReadFloat( istream &in ){
 
 	float tmp;
 	in.read( reinterpret_cast<char*>(&tmp), sizeof(tmp) );
 	return tmp;
 }
 
-void ReadFVector2( fVector2& fvec, ifstream& in ){
+void ReadFVector2( fVector2& fvec, istream& in ){
 
 	fvec[0] = ReadFloat( in );
 	fvec[1] = ReadFloat( in );
 }
 
-void ReadFVector3( fVector3& fvec, ifstream& in ){
+void ReadFVector3( fVector3& fvec, istream& in ){
 
 	fvec[0] = ReadFloat( in );
 	fvec[1] = ReadFloat( in );
 	fvec[2] = ReadFloat( in );
 }
 
-void ReadFVector4( fVector4& fvec, ifstream& in ){
+void ReadFVector4( fVector4& fvec, istream& in ){
 
 	fvec[0] = ReadFloat( in );
 	fvec[1] = ReadFloat( in );
@@ -221,7 +221,7 @@ void ReadFVector4( fVector4& fvec, ifstream& in ){
 	fvec[3] = ReadFloat( in );
 }
 
-string ReadString( ifstream &in ) {
+string ReadString( istream &in ) {
 	uint len = ReadUInt( in );
 	char * str = new char[len + 1];
 	in.read( str, len );
@@ -231,7 +231,7 @@ string ReadString( ifstream &in ) {
 	return out;
 }
 
-bool ReadBool( ifstream &in, unsigned int version ) {
+bool ReadBool( istream &in, unsigned int version ) {
 	if ( version <= 0x04010001 ) {
 		//Bools are stored as integers before version 4.1.0.1
 		return (ReadUInt( in ) != 0);
@@ -244,47 +244,47 @@ bool ReadBool( ifstream &in, unsigned int version ) {
 /**
  * Write utility functions.
  */
-void WriteUInt( uint val, ofstream& out ){
+void WriteUInt( uint val, ostream& out ){
 
 	out.write( (char*)&val, 4 );
 }
 
-void WriteUShort( ushort val, ofstream& out ){
+void WriteUShort( ushort val, ostream& out ){
 
 	out.write( (char*)&val, 2 );
 }
 
-void WriteByte( byte val, ofstream& out ){
+void WriteByte( byte val, ostream& out ){
 
 	out.write( (char*)&val, 1 );
 }
 
-void WriteUSVector3( usVector3 const & vec, ofstream& out ){
+void WriteUSVector3( usVector3 const & vec, ostream& out ){
 
 	WriteUShort( vec[0], out );
 	WriteUShort( vec[1], out );
 	WriteUShort( vec[2], out );
 }
 
-void WriteFloat( float val, ofstream& out ){
+void WriteFloat( float val, ostream& out ){
 
 	out.write( reinterpret_cast<char*>(&val), sizeof(val) );
 }
 
-void WriteFVector2( fVector2 const & fvec, ofstream& out ){
+void WriteFVector2( fVector2 const & fvec, ostream& out ){
 
 	WriteFloat( fvec[0], out );
 	WriteFloat( fvec[1], out );
 }
 
-void WriteFVector3( fVector3 const & fvec, ofstream& out ){
+void WriteFVector3( fVector3 const & fvec, ostream& out ){
 
 	WriteFloat( fvec[0], out );
 	WriteFloat( fvec[1], out );
 	WriteFloat( fvec[2], out );
 }
 
-void WriteFVector4( fVector4 const & fvec, ofstream& out ){
+void WriteFVector4( fVector4 const & fvec, ostream& out ){
 
 	WriteFloat( fvec[0], out );
 	WriteFloat( fvec[1], out );
@@ -292,12 +292,12 @@ void WriteFVector4( fVector4 const & fvec, ofstream& out ){
 	WriteFloat( fvec[3], out );
 }
 
-void WriteString( string const & val, ofstream& out ) {
+void WriteString( string const & val, ostream& out ) {
 	WriteUInt( uint(val.size()), out );
 	out.write( val.c_str(), std::streamsize(val.size()) );
 }
 
-void WriteBool( bool val, ofstream& out, unsigned int version ) {
+void WriteBool( bool val, ostream& out, unsigned int version ) {
 	if ( version < 0x04010001 ) {
 		//Bools are stored as integers before version 4.1.0.1
 		if (val)
@@ -313,7 +313,7 @@ void WriteBool( bool val, ofstream& out, unsigned int version ) {
 	}
 }
 
-void WriteBlockName( const char* name, uint nameLength, ofstream& out ){
+void WriteBlockName( const char* name, uint nameLength, ostream& out ){
 
 	WriteUInt( nameLength, out );
 	out.write( name, nameLength );
@@ -365,40 +365,40 @@ ostream & operator<<(ostream & lh, Bin const & rh) {
 
 //--Overloaded versions of Read/Write functions ReadData/WriteData
 
-void NifStream( uint & val, ifstream& in ) { val = ReadUInt( in ); };
-void NifStream( ushort & val, ifstream& in ) { val = ReadUShort( in ); };
-void NifStream( byte & val, ifstream& in ) { val = ReadByte( in ); };
-void NifStream( float & val, ifstream& in ) { val = ReadFloat( in ); };
-void NifStream( string & val, ifstream& in ) { val = ReadString( in ); };
-void NifStream( KeyType & val, ifstream& in ) { val = KeyType(ReadUInt( in )); };
+void NifStream( uint & val, istream& in ) { val = ReadUInt( in ); };
+void NifStream( ushort & val, istream& in ) { val = ReadUShort( in ); };
+void NifStream( byte & val, istream& in ) { val = ReadByte( in ); };
+void NifStream( float & val, istream& in ) { val = ReadFloat( in ); };
+void NifStream( string & val, istream& in ) { val = ReadString( in ); };
+void NifStream( KeyType & val, istream& in ) { val = KeyType(ReadUInt( in )); };
 
-void NifStream( Vector3 & val, ifstream& in ) {
+void NifStream( Vector3 & val, istream& in ) {
 	val.x = ReadFloat( in );
 	val.y = ReadFloat( in );
 	val.z = ReadFloat( in );
 };
 
-void NifStream( Quaternion & val, ifstream& in ) {
+void NifStream( Quaternion & val, istream& in ) {
 	val.w = ReadFloat( in );
 	val.x = ReadFloat( in );
 	val.y = ReadFloat( in );
 	val.z = ReadFloat( in );
 };
 
-void NifStream( Color4 & val, ifstream& in ) {
+void NifStream( Color4 & val, istream& in ) {
 	val.r = ReadFloat( in );
 	val.g = ReadFloat( in );
 	val.b = ReadFloat( in );
 	val.a = ReadFloat( in );
 };
 
-void NifStream( Triangle & val, ifstream& in ) {
+void NifStream( Triangle & val, istream& in ) {
 	val.v1 = ReadUShort( in );
 	val.v2 = ReadUShort( in );
 	val.v3 = ReadUShort( in );
 };
 
-void NifStream( TexDesc & val, ifstream& in, uint version ) {
+void NifStream( TexDesc & val, istream& in, uint version ) {
 	val.isUsed = ReadBool( in, version );
 	if ( val.isUsed ) {	
 		//Read in link for TexSource
@@ -436,35 +436,35 @@ void NifStream( TexDesc & val, ifstream& in, uint version ) {
 
 
 
-void NifStream( uint const & val, ofstream& out ) { WriteUInt( val, out ); }
-void NifStream( ushort const & val, ofstream& out ) { WriteUShort( val, out ); }
-void NifStream( byte const & val, ofstream& out ) { WriteByte( val, out ); }
-void NifStream( float const & val, ofstream& out ) { WriteFloat( val, out ); }
-void NifStream( string const & val, ofstream& out ) { WriteString( val, out ); }
-void NifStream( KeyType const & val, ofstream& out ) { WriteUInt( val, out ); }
-void NifStream( Vector3 const & val, ofstream& out ) {
+void NifStream( uint const & val, ostream& out ) { WriteUInt( val, out ); }
+void NifStream( ushort const & val, ostream& out ) { WriteUShort( val, out ); }
+void NifStream( byte const & val, ostream& out ) { WriteByte( val, out ); }
+void NifStream( float const & val, ostream& out ) { WriteFloat( val, out ); }
+void NifStream( string const & val, ostream& out ) { WriteString( val, out ); }
+void NifStream( KeyType const & val, ostream& out ) { WriteUInt( val, out ); }
+void NifStream( Vector3 const & val, ostream& out ) {
 	WriteFloat( val.x, out );
 	WriteFloat( val.y, out );
 	WriteFloat( val.z, out );
 };
-void NifStream( Quaternion const & val, ofstream& out ) {
+void NifStream( Quaternion const & val, ostream& out ) {
 	WriteFloat( val.w, out );
 	WriteFloat( val.x, out );
 	WriteFloat( val.y, out );
 	WriteFloat( val.z, out );
 };
-void NifStream( Color4 const & val, ofstream& out ) {
+void NifStream( Color4 const & val, ostream& out ) {
 	WriteFloat( val.r, out );
 	WriteFloat( val.g, out );
 	WriteFloat( val.b, out );
 	WriteFloat( val.a, out );
 };
-void NifStream( Triangle const & val, ofstream& out ) {
+void NifStream( Triangle const & val, ostream& out ) {
 	WriteUShort( val.v1, out );
 	WriteUShort( val.v2, out );
 	WriteUShort( val.v3, out );
 };
-void NifStream( TexDesc const & val, ofstream& out, uint version ) {
+void NifStream( TexDesc const & val, ostream& out, uint version ) {
 	WriteBool( val.isUsed, out, version );
 	if ( val.isUsed ) {
 		//Write link
diff --git a/NIF_IO.h b/NIF_IO.h
index 7218bd82ad25f6135ea1b1675e4870c172510c30..6a1e4e82eb0d52780950a028654443919b69cd88 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 /* INCLUDES */
 #include <iostream>
-#include <fstream>
 #include <iomanip>
 #include <string>
 #include <sstream>
@@ -124,7 +123,7 @@ typedef enum {
 
 //--IO Functions--//
 
-int BlockSearch( ifstream& in );
+int BlockSearch( istream& in );
 
 class Str {
 public:
@@ -180,33 +179,33 @@ ostream & operator<<(ostream & lh, nifAlphaFormat const & rh);
 /**
  * Read utility functions
  */
-uint ReadUInt( ifstream& in );
-ushort ReadUShort( ifstream& in );
-byte ReadByte( ifstream& in );
-float ReadFloat( ifstream &in );
-string ReadString( ifstream &in );
-bool ReadBool( ifstream &in, unsigned int version );
-void ReadUSVector3( usVector3& vec, ifstream& in );
-void ReadFVector2( fVector2& fvec, ifstream& in );
-void ReadFVector3( fVector3& fvec, ifstream& in );
-void ReadFVector4( fVector4& fvec, ifstream& in );
+uint ReadUInt( istream& in );
+ushort ReadUShort( istream& in );
+byte ReadByte( istream& in );
+float ReadFloat( istream &in );
+string ReadString( istream &in );
+bool ReadBool( istream &in, unsigned int version );
+void ReadUSVector3( usVector3& vec, istream& in );
+void ReadFVector2( fVector2& fvec, istream& in );
+void ReadFVector3( fVector3& fvec, istream& in );
+void ReadFVector4( fVector4& fvec, istream& in );
 
 //Read
-void NifStream( uint & val, ifstream& in );
-void NifStream( ushort & val, ifstream& in );
-void NifStream( byte & val, ifstream& in );
-void NifStream( float & val, ifstream& in );
-void NifStream( string & val, ifstream& in );
-void NifStream( Vector3 & val, ifstream& in );
-void NifStream( Quaternion & val, ifstream& in );
-void NifStream( KeyType & val, ifstream& in );
-void NifStream( Color4 & val, ifstream& in );
-void NifStream( Triangle & val, ifstream& in );
-void NifStream( TexDesc & val, ifstream& in, uint version );
+void NifStream( uint & val, istream& in );
+void NifStream( ushort & val, istream& in );
+void NifStream( byte & val, istream& in );
+void NifStream( float & val, istream& in );
+void NifStream( string & val, istream& in );
+void NifStream( Vector3 & val, istream& in );
+void NifStream( Quaternion & val, istream& in );
+void NifStream( KeyType & val, istream& in );
+void NifStream( Color4 & val, istream& in );
+void NifStream( Triangle & val, istream& in );
+void NifStream( TexDesc & val, istream& in, uint version );
 
 
 template <class T> 
-void NifStream( Key<T> & key, ifstream& file, KeyType type ) {
+void NifStream( Key<T> & key, istream& file, KeyType type ) {
 	key.time = ReadFloat( file );
 
 	//If key type is not 1, 2, or 3, throw an exception
@@ -230,7 +229,7 @@ void NifStream( Key<T> & key, ifstream& file, KeyType type ) {
 }
 
 template <class T>
-void NifStream( vector<T> & val, ifstream& file ) {
+void NifStream( vector<T> & val, istream& file ) {
 	typename vector<T>::iterator it;
 	for ( it = val.begin(); it != val.end(); ++it ) {
 		NifStream( *it, file );
@@ -241,43 +240,43 @@ void NifStream( vector<T> & val, ifstream& file ) {
 /**
  * Write utility functions.
  */
-void WriteUInt( uint val, ofstream& out );
+void WriteUInt( uint val, ostream& out );
 
-void WriteUShort( ushort val, ofstream& out );
+void WriteUShort( ushort val, ostream& out );
 
-void WriteByte( byte val, ofstream& out );
+void WriteByte( byte val, ostream& out );
 
-void WriteUSVector3( usVector3 const & fvec, ofstream& out );
+void WriteUSVector3( usVector3 const & fvec, ostream& out );
 
-void WriteFloat( float val, ofstream& out );
+void WriteFloat( float val, ostream& out );
 
-void WriteString( string const & val, ofstream& out );
+void WriteString( string const & val, ostream& out );
 
-void WriteBool( bool val, ofstream& out, unsigned int version );
+void WriteBool( bool val, ostream& out, unsigned int version );
 
-void WriteFVector2( fVector2 const & fvec, ofstream& out );
+void WriteFVector2( fVector2 const & fvec, ostream& out );
 
-void WriteFVector3( fVector3 const & fvec, ofstream& out );
+void WriteFVector3( fVector3 const & fvec, ostream& out );
 
-void WriteFVector4( fVector4 const & fvec, ofstream& out );
+void WriteFVector4( fVector4 const & fvec, ostream& out );
 
-void WriteBlockName( const char* name, uint nameLength, ofstream& out );
+void WriteBlockName( const char* name, uint nameLength, ostream& out );
 
 //Write
-void NifStream( uint const & val, ofstream& out );
-void NifStream( ushort const & val, ofstream& out );
-void NifStream( byte const & val, ofstream& out );
-void NifStream( float const & val, ofstream& out );
-void NifStream( string const & val, ofstream& out );
-void NifStream( Vector3 const & val, ofstream& out );
-void NifStream( Quaternion const & val, ofstream& out );
-void NifStream( KeyType const & val, ofstream& out );
-void NifStream( Color4 const & val, ofstream& out );
-void NifStream( Triangle const & val, ofstream& out );
-void NifStream( TexDesc const & val, ofstream& out, uint version );
+void NifStream( uint const & val, ostream& out );
+void NifStream( ushort const & val, ostream& out );
+void NifStream( byte const & val, ostream& out );
+void NifStream( float const & val, ostream& out );
+void NifStream( string const & val, ostream& out );
+void NifStream( Vector3 const & val, ostream& out );
+void NifStream( Quaternion const & val, ostream& out );
+void NifStream( KeyType const & val, ostream& out );
+void NifStream( Color4 const & val, ostream& out );
+void NifStream( Triangle const & val, ostream& out );
+void NifStream( TexDesc const & val, ostream& out, uint version );
 
 template <class T> 
-void NifStream( Key<T> const & key, ofstream& file, KeyType type ) {
+void NifStream( Key<T> const & key, ostream& file, KeyType type ) {
 	WriteFloat( key.time, file );
 
 	//If key type is not 1, 2, or 3, throw an exception
@@ -301,7 +300,7 @@ void NifStream( Key<T> const & key, ofstream& file, KeyType type ) {
 }
 
 template <class T>
-void NifStream( vector<T> const & val, ofstream& file ) {
+void NifStream( vector<T> const & val, ostream& file ) {
 	typename vector<T>::const_iterator it;
 	for ( it = val.begin(); it != val.end(); ++it ) {
 		NifStream( *it, file );
@@ -334,10 +333,10 @@ public:
 	void SetIndex( int index ) {
 		_index = index;
 	}
-	void Read( ifstream &in ) {
+	void Read( istream &in ) {
 		_index = ReadUInt( in );
 	}
-	void Write( ofstream &out ) const {
+	void Write( ostream &out ) const {
 		WriteUInt( _index, out );
 	}
 	friend ostream & operator<<(ostream & lh, nifIndex const & rh);
diff --git a/SConstruct b/SConstruct
index 8afcecf1ac9e7365437b2ccd8c68e667e4278249..28ff68704c61f6ff65f31d2394f6560af81e62c6 100644
--- a/SConstruct
+++ b/SConstruct
@@ -26,7 +26,7 @@ env.StaticLibrary('niflib', Split('niflib.cpp nif_math.cpp NIF_Blocks.cpp NIF_IO
 env.SharedLibrary('_niflib', 'pyniflib.i', LIBS=['niflib'] + python_lib, LIBPATH=['.'] + python_libpath, SWIGFLAGS = '-c++ -python', CPPPATH = ['.'] + python_include, CPPFLAGS = cppflags, SHLIBPREFIX='')
 
 # Here's how to compile niflyze:
-#env.Program('niflyze', 'niflyze.cpp', LIBS=['niflib'], LIBPATH=['.'], CPPFLAGS = cppflags)
+env.Program('niflyze', 'niflyze.cpp', LIBS=['niflib'], LIBPATH=['.'], CPPFLAGS = cppflags)
 
 # A test program:
-#env.Program('test', 'test.cpp', LIBS=['niflib'], LIBPATH=['.'], CPPFLAGS = cppflags)
+env.Program('test', 'test.cpp', LIBS=['niflib'], LIBPATH=['.'], CPPFLAGS = cppflags)
diff --git a/nif_attrs.h b/nif_attrs.h
index e0d8d485092f7436b3c8f4002a36524a96b6a535..f8bd799942f5ae21da1e4591a22f79f65a9ed5af 100644
--- a/nif_attrs.h
+++ b/nif_attrs.h
@@ -79,20 +79,20 @@ public:
 	void RemoveLinks( blk_ref const & block ) { cout << "RemoveLinks" << endl; throw runtime_error(ATTRERR); }
 	blk_ref FindLink( string const & block_type ) const { cout << "FindLink" << endl; throw runtime_error(ATTRERR); }
 	//Read/WriteFunctions
-	void Read( ifstream& in, unsigned int version ) {
+	void Read( istream& in, unsigned int version ) {
 		if ( version >= _first_ver && version <= _last_ver ) {
 			this->ReadAttr( in, version );
 		}
 	}
-	void Write( ofstream& out, unsigned int version ) const {
+	void Write( ostream& out, unsigned int version ) const {
 		if ( version >= _first_ver && version <= _last_ver ) {
 			this->WriteAttr( out, version );
 		}
 	}
 protected:
 	//Internal Read/Write Functions
-	virtual void ReadAttr( ifstream& in, unsigned int version ) = 0;
-	virtual void WriteAttr( ofstream& out, unsigned int version ) const = 0;
+	virtual void ReadAttr( istream& in, unsigned int version ) = 0;
+	virtual void WriteAttr( ostream& out, unsigned int version ) const = 0;
 
 	string _name;
 	IBlock * _owner;
@@ -181,8 +181,8 @@ public:
 	IntAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~IntAttr() {}
 	AttrType GetType() const { return attr_int; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadUInt( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteUInt( data, out ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadUInt( in ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteUInt( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -203,8 +203,8 @@ public:
 	ShortAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~ShortAttr() {}
 	AttrType GetType() const { return attr_short; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadUShort( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteUShort( data, out ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadUShort( in ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteUShort( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -225,8 +225,8 @@ public:
 	ByteAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~ByteAttr() {}
 	AttrType GetType() const { return attr_byte; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadByte( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteByte( data, out ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadByte( in ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteByte( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -247,8 +247,8 @@ public:
 	BoolAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~BoolAttr() {}
 	AttrType GetType() const { return attr_bool; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadBool( in, version ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteBool( data, out, version ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadBool( in, version ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteBool( data, out, version ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -269,8 +269,8 @@ public:
 	FloatAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0.0f) {}
 	~FloatAttr() {}
 	AttrType GetType() const { return attr_float; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadFloat( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteFloat( data, out ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadFloat( in ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteFloat( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -295,12 +295,12 @@ public:
 	}
 	~Float3Attr() {}
 	AttrType GetType() const { return attr_float3; }
-	void ReadAttr( ifstream& in, unsigned int version ) { 
+	void ReadAttr( istream& in, unsigned int version ) { 
 		data[0] = ReadFloat( in );
 		data[1] = ReadFloat( in );
 		data[2] = ReadFloat( in );
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteFloat( data[0], out );
 		WriteFloat( data[1], out );
 		WriteFloat( data[2], out );
@@ -339,8 +339,8 @@ public:
 	StringAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
 	~StringAttr() {}
 	AttrType GetType() const { return attr_string; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadString( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteString( data, out ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadString( in ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteString( data, out ); }
 	string asString() const { return data; }
 	void Set(string const & n) { data = n; }
 private:
@@ -352,7 +352,7 @@ public:
 	LinkAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), link( owner ) {}
 	~LinkAttr() {}
 	AttrType GetType() const { return attr_link; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		////Remove all links beloning to this attribute
 		//_owner->RemoveAttrLinks(this);
 
@@ -365,7 +365,7 @@ public:
 		//Set block index only
 		link.set_index( ReadUInt( in ) );
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteUInt( link.get_index(), out );
 	}
 	string asString() const {
@@ -402,8 +402,8 @@ public:
 	FlagsAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~FlagsAttr() {}
 	AttrType GetType() const { return attr_flags; }
-	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadUShort( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) const { WriteUShort( data, out ); }
+	void ReadAttr( istream& in, unsigned int version ) { data = ReadUShort( in ); }
+	void WriteAttr( ostream& out, unsigned int version ) const { WriteUShort( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -435,14 +435,14 @@ public:
 	}
 	~MatrixAttr() {}
 	AttrType GetType() const { return attr_matrix33; }
-	void ReadAttr( ifstream& in, unsigned int version ) { 
+	void ReadAttr( istream& in, unsigned int version ) { 
 		for (int c = 0; c < 3; ++c) {
 			for (int r = 0; r < 3; ++r) {
 				data[r][c] = ReadFloat( in );
 			}
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		for (int c = 0; c < 3; ++c) {
 			for (int r = 0; r < 3; ++r) {
 				WriteFloat( data[r][c], out );
@@ -501,7 +501,7 @@ public:
 	BoneAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~BoneAttr() {}
 	AttrType GetType() const { return attr_bones; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		ISkinInstInternal * data = (ISkinInstInternal*)_owner->QueryInterface( SkinInstInternal );
 		if ( data != NULL ) {
 			data->ReadBoneList( in );
@@ -509,7 +509,7 @@ public:
 			throw runtime_error ("Attempted to use a bone list attribute on a block that doesn't support it.");
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		//ISkinInstInternal * data = (ISkinInstInternal*)_owner->QueryInterface( SkinInstInternal );
 		blk_ref data_blk = _owner->GetAttr("Data")->asLink();
 		if ( data_blk.is_null() == false )  {
@@ -566,7 +566,7 @@ public:
 	LinkGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
 	~LinkGroupAttr() {}
 	AttrType GetType() const { return attr_linkgroup; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		int len = ReadUInt( in );
 		//cout << "Link Group Size:  " << len << endl;
 
@@ -580,7 +580,7 @@ public:
 				AddLink( blk_ref( index ) );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		//Write the number of links
 		WriteUInt( uint(links.size()), out );
 		//cout << "Link Group Size:  " << uint(links.size()) << endl;
@@ -667,7 +667,7 @@ public:
 
 	AttrType GetType() const { return attr_targetgroup; }
 
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		int len = ReadUShort( in );
 
 		if ( len > 1000 ) {
@@ -680,7 +680,7 @@ public:
 				AddLink( blk_ref( index ) );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		//Write the number of links
 		WriteUShort( ushort(links.size()), out );
 		//cout << "Link Group Size:  " << uint(links.size()) << endl;
@@ -715,7 +715,7 @@ public:
 	}
 	~BBoxAttr() {}
 	AttrType GetType() const { return attr_bbox; }
-	void ReadAttr( ifstream& in, unsigned int version ) { 
+	void ReadAttr( istream& in, unsigned int version ) { 
 		data.isUsed = ReadBool( in, version );
 		if ( data.isUsed ){
 			data.unknownInt = ReadUInt( in );
@@ -732,7 +732,7 @@ public:
 			data.radius.z = ReadFloat( in );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteBool( data.isUsed, out, version );
 		if ( data.isUsed ){
 			WriteUInt( data.unknownInt, out );
@@ -786,13 +786,13 @@ public:
 	}
 	~CIntAttr() {}
 	AttrType GetType() const { return attr_condint; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		data.isUsed = ReadBool( in, version );
 		if (data.isUsed) {
 			data.unknownInt = ReadUInt( in );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteBool( data.isUsed, out, version );
 		if (data.isUsed) {
 			WriteUInt( data.unknownInt, out );
@@ -886,14 +886,14 @@ public:
 
     //int light      - lighting mode:
     //                 0 - lighting emmisive
-    //  1 - lighting emmisive amb diff
+    //                 1 - lighting emmisive amb diff
 
 class ShaderAttr : public LinkAttr {
 public:
 	ShaderAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver), isUsed(false) {}
 	~ShaderAttr() {}
 	AttrType GetType() const { return attr_shader; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		isUsed = ReadBool( in, version );
 		if ( isUsed ) {	
 			//Read in shader name
@@ -903,7 +903,7 @@ public:
 			LinkAttr::ReadAttr( in, version );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteBool( isUsed, out, version );
 		if ( isUsed ) {	
 			//Write out shader name
@@ -944,7 +944,7 @@ public:
 	}
 	~TexSourceAttr() {}
 	AttrType GetType() const { return attr_texsource; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		data.useExternal = ( ReadByte(in) != 0);
 
 		//All data is always read after version 10.1.0.0
@@ -964,7 +964,7 @@ public:
 			LinkAttr::ReadAttr( in, version );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteByte( byte(data.useExternal), out );
 
 		//All data is always written after version 10.1.0.0
@@ -1137,10 +1137,10 @@ public:
 	ControllerTargetAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ControllerTargetAttr() {}
 	AttrType GetType() const { return attr_controllertarget; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		ReadUInt(in);
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		//WriteUInt( FindTarget()->GetBlockNum(), out );
 		WriteUInt( FindTarget().get_index(), out ); // we need get_index(), GetBlockNum() chokes on null block references
 	}
@@ -1187,10 +1187,10 @@ public:
 	SkeletonRootAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~SkeletonRootAttr() {}
 	AttrType GetType() const { return attr_skeletonroot; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		original_root = ReadUInt( in );  //Read data but do nothing with it
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteUInt( FindRoot().get_index(), out );
 	}
 	blk_ref FindRoot() const {
@@ -1307,10 +1307,10 @@ public:
 	ParentAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ParentAttr() {}
 	AttrType GetType() const { return attr_parent; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		ReadUInt(in);
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteUInt( _owner->GetParent()->GetBlockNum(), out );
 	}
 	string asString() const {
@@ -1332,7 +1332,7 @@ public:
 	~ParticleGroupAttr() {}
 	AttrType GetType() const { return attr_particlegroup; }
 
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		num_particles = ReadUShort( in );
 		num_valid = ReadUShort( in );
 
@@ -1348,7 +1348,7 @@ public:
 		}
 	}
 
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteUShort( num_particles, out );
 		WriteUShort( num_valid, out );
 
@@ -1405,7 +1405,7 @@ public:
 	~LODRangeGroupAttr() {}
 	AttrType GetType() const { return attr_lodrangegroup; }
 
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		int numRanges = ReadUInt( in );
 		ranges.resize( numRanges );
 		for ( uint i = 0; i < ranges.size(); ++i ) {
@@ -1414,7 +1414,7 @@ public:
 		}
 	}
 
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		WriteUInt( uint(ranges.size()), out );
 
 		for ( uint i = 0; i < ranges.size(); ++i ) {
@@ -1456,10 +1456,10 @@ public:
 	}
 	~Unk292BytesAttr() {}
 	AttrType GetType() const { return attr_unk292bytes; }
-	void ReadAttr( ifstream& in, unsigned int version ) {
+	void ReadAttr( istream& in, unsigned int version ) {
 		in.read( (char*)data, 256 );
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) const {
+	void WriteAttr( ostream& out, unsigned int version ) const {
 		out.write( (char*)data, 265 );
 	}
 	string asString() const {
diff --git a/niflib.cpp b/niflib.cpp
index 54e2a1940ba3779aaa4a54504211505fc89054db..855d84f71f857a04ab2d3f5ee9815f5381d76661 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -89,6 +89,13 @@ blk_ref ReadNifTree( string const & file_name ) {
 	return FindRoot( blocks );
 }
 
+//Reads the given input stream and returns a reference to the root block
+blk_ref ReadNifTree( istream & in ) {
+	//Read block list
+	vector<blk_ref> blocks = ReadNifList( in );
+	return FindRoot( blocks );
+}
+
 blk_ref FindRoot( vector<blk_ref> const & blocks ) {
 	//--Look for a NiNode that has no parents--//
 
@@ -119,6 +126,12 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 	//--Open File--//
 	ifstream in( file_name.c_str(), ifstream::binary );
 
+	return ReadNifList( in );
+}
+
+//Reads the given input stream and returns a vector of block references
+vector<blk_ref> ReadNifList( istream & in ) {
+
 	//--Read Header--//
 	char header_string[256];
 	in.getline( header_string, 256 );
@@ -158,7 +171,7 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 
 		////Output
 		//cout << endl << endl 
-		//	 << "====[ " << file_name << " | File Header ]====" << endl
+		//	 << "====[ " << "File Header ]====" << endl
 		//	 << "Header:  " << header_string << endl
 		//	 << "Version:  " << Hex(version) << endl
 		//	 << "Unknown Int 1:  " << unknownInt1 << endl
@@ -178,7 +191,7 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 	} else {
 		////Output
 		//cout << endl << endl 
-		//	<< "====[ " << file_name << " | File Header ]====" << endl
+		//	<< "====[ " << "File Header ]====" << endl
 		//	<< "Header:  " << header_string << endl
 		//	<< "Version:  " << Hex(version) << endl
 		//	<< "Number of Blocks: " << int(numBlocks) << endl;
@@ -204,7 +217,7 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 				if ( checkValue != 0 ) {
 					//Throw an exception if it's not zero
 					cout << "ERROR!  Bad block position.  Invalid check value\a" << endl;
-					cout << "====[ " << file_name << " | Block " << i << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl;
+					cout << "====[ " << "Block " << i << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl;
 					cout << blocks[i - 1]->asString();
 					throw runtime_error("Read failue - Bad block position");
 				}
@@ -217,7 +230,7 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 			uint blockNameLength = ReadUInt( in );
 			if (blockNameLength > 30 || blockNameLength < 6) {
 				cout << "ERROR!  Bad block position.  Invalid Name Length:  " << blockNameLength << "\a" << endl;
-				cout << "====[ " << file_name << " | Block " << i - 1 << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl;
+				cout << "====[ " << "Block " << i - 1 << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl;
 				cout << blocks[i - 1]->asString();
 				throw runtime_error("Read failue - Bad block position");
 			}
@@ -228,7 +241,7 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 			delete [] charBlockName;
 			if ( (blockName[0] != 'N' || blockName[1] != 'i') && (blockName[0] != 'R' || blockName[1] != 'o') && (blockName[0] != 'A' || blockName[1] != 'v')) {
 				cout << "ERROR!  Bad block position.  Invalid Name:  " << blockName << "\a" << endl;
-				cout << "====[ " << file_name << " | Block " << i - 1 << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl;
+				cout << "====[ " << "Block " << i - 1 << " | " << blocks[i - 1]->GetBlockType() << " ]====" << endl;
 				cout << blocks[i - 1]->asString();
 				throw runtime_error("Read failue - Bad block position");
 			}
@@ -273,9 +286,6 @@ vector<blk_ref> ReadNifList( string const & file_name ) {
 	if ( ! in.eof() )
 		throw runtime_error("End of file not reached.  This NIF may be corrupt or improperly supported.");
 		
-	//--Close File--//
-	in.close();
-
 	//--Now that all blocks are read, go back and fix the indices--//
 	for (uint i = 0; i < blocks.size(); ++i) {
 
diff --git a/niflib.h b/niflib.h
index 4e5cf8a88eca8240d975567af0b0f6bb1d130204..74bc868727f782892347e9d93200d873970fe9a5 100644
--- a/niflib.h
+++ b/niflib.h
@@ -231,6 +231,13 @@ enum PixelFormat {
  */
 vector<blk_ref> ReadNifList( string const & file_name );
 
+/*!
+ * Reads the given input stream and returns a vector of block references
+ * \param stream The input stream to read NIF data from.
+ * \return A vector of block references that point to all the blocks read from the stream.
+ */
+vector<blk_ref> ReadNifList( istream & in );
+
 /*!
  * Reads the given file by file name and returns a reference to the root block.
  * \param file_name The name of the file to load, or the complete path if it is not in the working directory.
@@ -250,6 +257,13 @@ vector<blk_ref> ReadNifList( string const & file_name );
  */
 blk_ref ReadNifTree( string const & file_name );
 
+/*!
+ * Reads the given input stream and returns a reference to the root block.
+ * \param stream The input stream to read NIF data from.
+ * \return A block reference that points to the root of the tree of data blocks contained in the NIF file.
+ */
+blk_ref ReadNifTree( istream & in );
+
 /*!
  * Creates a new NIF file of the given file name by crawling through the data tree starting with the root block given.  Automatically writes a kf file and an x/nif file if animation is present.
  * \param file_name The desired file name for the new NIF file.  The path is relative to the working directory unless a full path is specified.
@@ -1499,8 +1513,8 @@ public:
 	 */
 	virtual string GetName() const = 0;
 
-	virtual void Read( ifstream& in, unsigned int version ) = 0;
-	virtual void Write( ofstream& out, unsigned int version ) const = 0;
+	virtual void Read( istream& in, unsigned int version ) = 0;
+	virtual void Write( ostream& out, unsigned int version ) const = 0;
 
 	//--Getters--//