diff --git a/include/gen/Header.h b/include/gen/Header.h
index 1aceda4ba90f20dd103ab61386ea631af9cac7e5..378bebb785babeb780a2a6a821942d3e2dd7455b 100644
--- a/include/gen/Header.h
+++ b/include/gen/Header.h
@@ -44,10 +44,6 @@ struct NIFLIB_API Header {
 	 * Number of file objects.
 	 */
 	mutable uint numBlocks;
-	/*!
-	 * Unknown.
-	 */
-	uint unknownInt1;
 	/*!
 	 * This also appears to be the extra user version number and must be set
 	 * in some circumstances.
diff --git a/include/gen/obj_defines.h b/include/gen/obj_defines.h
index 5bdd4a43f88a36e4f96e8dc58e3aff2d2c747083..ba1efdfedcc93526d62312bf444cee93e0fefb4d 100644
--- a/include/gen/obj_defines.h
+++ b/include/gen/obj_defines.h
@@ -3071,10 +3071,10 @@ vector< array<4,float> > unknownFloats3; \
 vector< array<10,float> > unknownFloats4; \
 vector< array<12,float> > unknownFloats5; \
 uint unknownInt1; \
-Ref<NiPSysModifier > modifier; \
+Ref<NiObject > modifier; \
 byte unknownByte2; \
 mutable uint numUnknownLinks; \
-vector<Ref<NiPSysModifier > > unknownLinks; \
+vector<Ref<NiObject > > unknownLinks; \
 ushort unknownShort4; \
 uint unknownInt2; \
 byte unknownByte12; \
diff --git a/include/nif_versions.h b/include/nif_versions.h
index 6d77e1556ba9acc3b84bccc36bac93f5748d4662..30833a6f545b9d049d7afa6bba89649f1110d998 100644
--- a/include/nif_versions.h
+++ b/include/nif_versions.h
@@ -5,7 +5,9 @@ All rights reserved.  Please see niflib.h for licence. */
 #define _NIF_VERSIONS_H_
 
 //NIF Version Constants
-const unsigned VER_4_0_0_0     = 0X04000000; /*!< NIF Version 4.0.0.0 */
+
+const unsigned VER_3_3_0_13    = 0x0303000D; /*!< NIF Version 3.3.0.13 */
+const unsigned VER_4_0_0_0     = 0x04000000; /*!< NIF Version 4.0.0.0 */
 const unsigned VER_4_0_0_2     = 0x04000002; /*!< NIF Version 4.0.0.2 */ 
 const unsigned VER_4_1_0_12    = 0x0401000C; /*!< NIF Version 4.1.0.12 */ 
 const unsigned VER_4_2_0_2     = 0x04020002; /*!< NIF Version 4.2.0.2 */ 
diff --git a/src/NIF_IO.cpp b/src/NIF_IO.cpp
index 53222bad2e9fee01a6ae9e1c5c97548e3e59613b..90b0dc5dea12affeae85d2df6637bf1f7c79c038 100644
--- a/src/NIF_IO.cpp
+++ b/src/NIF_IO.cpp
@@ -5,74 +5,74 @@ All rights reserved.  Please see niflib.h for licence. */
 #include "../include/niflib.h"
 namespace Niflib {
 
-int BlockSearch( istream& in ) {
-
-	//Get current file pos
-	int data_start = in.tellg();
-
-	//cout << "Current File Pos: " << data_start << endl;
-	//cout << "Searching for next block..." << endl;
-
-	//Find Next Block
-	char tmp1 = 0, tmp2 = 0;
-	uint next_name_len = 0;
-	while (!in.eof()) {
-		while (!in.eof() && !((tmp1 == 'N' && tmp2 == 'i') || (tmp1 == 'R' && tmp2 == 'o') || (tmp1 == 'A' && tmp2 == 'v')) ) {
-			tmp1 = tmp2;
-			in.read(&tmp2, 1);
-		}
-		if (in.eof())
-			break;
-		
-		//Move back to before the uint that holds the length of the string
-		in.seekg(-6, ios_base::cur);
-
-		//Read the length of the string
-		next_name_len = ReadUInt( in );
-
-		//cout << "Matching Data:  " << tmp1 << tmp2 << endl;
-
-		//if name length is > 40, then this is unlikley to be a real node. 
-		if (next_name_len <= 40 && next_name_len >= 5) {
-			//Read the string
-			char* next_name = new char[next_name_len];
-			in.read( next_name, next_name_len );
-			
-			//cout << "Found Match:  " << Str(next_name, next_name_len) << endl;
-
-			//Move back to where we were before we read anything
-			in.seekg( -(int(next_name_len) - 2), ios_base::cur);
-
-			break;
-		}
-		else {
-			//Move back to where we were before we read anything
-			in.seekg(2, ios_base::cur);
-
-			tmp1 = tmp2 = 0;
-			//cout << "Found possible block at:  " << int(in.tellg()) - 6 << endl;
-		}
-	}
-
-	//Note length of data
-	int data_length = 0;
-	if (in.eof()) {
-		//cout << "Reached End of File.  Assuming no more blocks to find." << endl;
-		in.clear();
-		in.seekg(-8, ios_base::end);
-		data_length = int(in.tellg()) - data_start;
-		in.seekg(data_start, ios_base::beg);
-	}
-	else {
-		in.seekg(-6, ios_base::cur);
-		data_length = int(in.tellg()) - data_start;
-		in.seekg(data_start, ios_base::beg);
-	}
-
-	//cout << "Unknown area (" << data_length << " bytes):" << endl;
-
-	return data_length;
-}
+//int BlockSearch( istream& in ) {
+//
+//	//Get current file pos
+//	int data_start = in.tellg();
+//
+//	//cout << "Current File Pos: " << data_start << endl;
+//	//cout << "Searching for next block..." << endl;
+//
+//	//Find Next Block
+//	char tmp1 = 0, tmp2 = 0;
+//	uint next_name_len = 0;
+//	while (!in.eof()) {
+//		while (!in.eof() && !((tmp1 == 'N' && tmp2 == 'i') || (tmp1 == 'R' && tmp2 == 'o') || (tmp1 == 'A' && tmp2 == 'v')) ) {
+//			tmp1 = tmp2;
+//			in.read(&tmp2, 1);
+//		}
+//		if (in.eof())
+//			break;
+//		
+//		//Move back to before the uint that holds the length of the string
+//		in.seekg(-6, ios_base::cur);
+//
+//		//Read the length of the string
+//		next_name_len = ReadUInt( in );
+//
+//		//cout << "Matching Data:  " << tmp1 << tmp2 << endl;
+//
+//		//if name length is > 40, then this is unlikley to be a real node. 
+//		if (next_name_len <= 40 && next_name_len >= 5) {
+//			//Read the string
+//			char* next_name = new char[next_name_len];
+//			in.read( next_name, next_name_len );
+//			
+//			//cout << "Found Match:  " << Str(next_name, next_name_len) << endl;
+//
+//			//Move back to where we were before we read anything
+//			in.seekg( -(int(next_name_len) - 2), ios_base::cur);
+//
+//			break;
+//		}
+//		else {
+//			//Move back to where we were before we read anything
+//			in.seekg(2, ios_base::cur);
+//
+//			tmp1 = tmp2 = 0;
+//			//cout << "Found possible block at:  " << int(in.tellg()) - 6 << endl;
+//		}
+//	}
+//
+//	//Note length of data
+//	int data_length = 0;
+//	if (in.eof()) {
+//		//cout << "Reached End of File.  Assuming no more blocks to find." << endl;
+//		in.clear();
+//		in.seekg(-8, ios_base::end);
+//		data_length = int(in.tellg()) - data_start;
+//		in.seekg(data_start, ios_base::beg);
+//	}
+//	else {
+//		in.seekg(-6, ios_base::cur);
+//		data_length = int(in.tellg()) - data_start;
+//		in.seekg(data_start, ios_base::beg);
+//	}
+//
+//	//cout << "Unknown area (" << data_length << " bytes):" << endl;
+//
+//	return data_length;
+//}
 
 /**
  * Read utility functions
@@ -254,7 +254,7 @@ void NifStream( HeaderString & val, istream& in, uint & version ) {
 	version = ParseVersionString( val.header.substr( ver_start ) );
 
 	//Temporarily read the next 3 strings if this is a < 4 file
-	if ( version < VER_4_0_0_0 ) {
+	if ( version < VER_3_3_0_13 ) {
 		in.getline( tmp, 256 );
 		in.getline( tmp, 256 );
 		in.getline( tmp, 256 );
diff --git a/src/gen/Header.cpp b/src/gen/Header.cpp
index 6a192a85afdd8215a8112a2a1bfea21970b40b74..db066cab1b57ecaf9ac121b4cf2544232c71f791 100644
--- a/src/gen/Header.cpp
+++ b/src/gen/Header.cpp
@@ -5,13 +5,13 @@ All rights reserved.  Please see niflib.h for licence. */
 using namespace Niflib;
 
 //Constructor
-Header::Header() : version((uint)0x04000002), endianType((byte)1), userVersion((uint)0), numBlocks((uint)0), unknownInt1((uint)1), userVersion2((uint)0), numBlockTypes((ushort)0), unknownInt2((uint)0) {};
+Header::Header() : version((uint)0x04000002), endianType((byte)1), userVersion((uint)0), numBlocks((uint)0), userVersion2((uint)0), numBlockTypes((ushort)0), unknownInt2((uint)0) {};
 
 //Destructor
 Header::~Header() {};
 void Header::Read( istream& in ) {
 	NifStream( headerString, in, version );
-	if ( version >= 0x04000000 ) {
+	if ( version >= 0x0303000D ) {
 		NifStream( version, in, version );
 	};
 	if ( version >= 0x14000004 ) {
@@ -20,11 +20,11 @@ void Header::Read( istream& in ) {
 	if ( version >= 0x0A010000 ) {
 		NifStream( userVersion, in, version );
 	};
-	if ( version >= 0x04000000 ) {
+	if ( version >= 0x0303000D ) {
 		NifStream( numBlocks, in, version );
 	};
 	if ( ( version >= 0x0A000102 ) && ( version <= 0x0A000102 ) ) {
-		NifStream( unknownInt1, in, version );
+		NifStream( userVersion, in, version );
 	};
 	if ( version >= 0x0A010000 ) {
 		if ( (userVersion != 0) ) {
@@ -56,7 +56,7 @@ void Header::Write( ostream& out ) const {
 	numBlockTypes = ushort(blockTypes.size());
 	numBlocks = uint(blockTypeIndex.size());
 	NifStream( headerString, out, version );
-	if ( version >= 0x04000000 ) {
+	if ( version >= 0x0303000D ) {
 		NifStream( version, out, version );
 	};
 	if ( version >= 0x14000004 ) {
@@ -65,11 +65,11 @@ void Header::Write( ostream& out ) const {
 	if ( version >= 0x0A010000 ) {
 		NifStream( userVersion, out, version );
 	};
-	if ( version >= 0x04000000 ) {
+	if ( version >= 0x0303000D ) {
 		NifStream( numBlocks, out, version );
 	};
 	if ( ( version >= 0x0A000102 ) && ( version <= 0x0A000102 ) ) {
-		NifStream( unknownInt1, out, version );
+		NifStream( userVersion, out, version );
 	};
 	if ( version >= 0x0A010000 ) {
 		if ( (userVersion != 0) ) {
@@ -104,7 +104,6 @@ string Header::asString( bool verbose ) const {
 	out << "  Endian Type:  " << endianType << endl;
 	out << "  User Version:  " << userVersion << endl;
 	out << "  Num Blocks:  " << numBlocks << endl;
-	out << "  Unknown Int 1:  " << unknownInt1 << endl;
 	if ( (userVersion != 0) ) {
 		out << "    User Version 2:  " << userVersion2 << endl;
 		out << "    Creator:  " << creator << endl;
diff --git a/src/gen/obj_impl.cpp b/src/gen/obj_impl.cpp
index 64610f9691ccd1ee0e67eff449d6393a82712c02..c1cead69ef62b6bfc88eddf5ce79443a49cd5325 100644
--- a/src/gen/obj_impl.cpp
+++ b/src/gen/obj_impl.cpp
@@ -6385,11 +6385,11 @@ std::string NiMeshPSysData::InternalAsString( bool verbose ) const {
 void NiMeshPSysData::InternalFixLinks( const map<unsigned,NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
 	APSysData::FixLinks( objects, link_stack, version, user_version );
 	if ( version <= 0x14000004 ) {
-		modifier = FixLink<NiPSysModifier>( objects, link_stack, version );
+		modifier = FixLink<NiObject>( objects, link_stack, version );
 	};
 	if ( ( version >= 0x0A020000 ) && ( version <= 0x14000004 ) ) {
 		for (uint i2 = 0; i2 < unknownLinks.size(); i2++) {
-			unknownLinks[i2] = FixLink<NiPSysModifier>( objects, link_stack, version );
+			unknownLinks[i2] = FixLink<NiObject>( objects, link_stack, version );
 		};
 	};
 	if ( version >= 0x0A020000 ) {
diff --git a/src/niflib.cpp b/src/niflib.cpp
index 389f2668e565dced16ddf2d335f61ce45625b429..ef9d8bc31b924449b81def87132e9b2245b57716 100644
--- a/src/niflib.cpp
+++ b/src/niflib.cpp
@@ -133,6 +133,8 @@ vector<NiObjectRef> ReadNifList( string const & file_name, NifInfo * info ) {
 	ifstream in( file_name.c_str(), ifstream::binary );
 
 	return ReadNifList( in );
+
+	in.close();
 }
 
 //Reads the given input stream and returns a vector of block references
@@ -195,9 +197,9 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) {
 		//There are two main ways to read objects
 		//One before version 5.0.0.1 and one after
 		if ( header.version >= 0x05000001 ) {
-			//From version 5.0.0.1 to version 10.0.1.0  there is a zero byte at the begining of each object
+			//From version 5.0.0.1 to version 10.0.1.106  there is a zero byte at the begining of each object
 			
-			if ( header.version <= VER_10_1_0_0 ) {
+			if ( header.version <= VER_10_1_0_106 ) {
 				uint checkValue = ReadUInt( in );
 				if ( checkValue != 0 ) {
 					//Throw an exception if it's not zero
@@ -215,6 +217,10 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) {
 
 			// Find which block type this is by using the header arrays
 			objectType = header.blockTypes[ header.blockTypeIndex[i] ];
+
+#ifdef PRINT_OBJECT_NAMES
+			cout << endl << i << ":  " << objectType;
+#endif
 		} else {
 			// Find which object type this is by reading the string at this location
 			uint objectTypeLength = ReadUInt( in );
@@ -239,7 +245,7 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) {
 			cout << endl << i << ":  " << objectType;
 #endif
 
-			if ( header.version < VER_4_0_0_0 ) {
+			if ( header.version < VER_3_3_0_13 ) {
 				//There can be special commands instead of object names
 				//in these versions
 
@@ -284,7 +290,7 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) {
 		}
 
 		uint index;
-		if ( header.version < VER_4_0_0_0 ) {
+		if ( header.version < VER_3_3_0_13 ) {
 			//These old versions have a pointer value after the name
 			//which is used as the index
 			index = ReadUInt(in);
@@ -301,7 +307,7 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) {
 		cout << endl << new_obj->asString() << endl;
 #endif
 
-		if ( header.version >= VER_4_0_0_0 ) {
+		if ( header.version >= VER_3_3_0_13 ) {
 			//We know the number of objects, so increment the count
 			//and break if we've finished
 			++i;
@@ -340,10 +346,6 @@ vector<NiObjectRef> ReadNifList( istream & in, NifInfo * info ) {
 	cout << "Fixing Links:"  << endl;
 #endif
 	//--Now that all blocks are read, go back and fix the links--//
-	if ( header.version < VER_4_0_0_0 ) {
-		//First wen
-	}
-
 	vector<NiObjectRef> obj_list;
 
 	for ( map<unsigned,NiObjectRef>::iterator it = objects.begin(); it != objects.end(); ++it ) {
@@ -1069,6 +1071,7 @@ void MergeNifTrees( const Ref<NiNode> & target, const Ref<NiSequenceStreamHelper
 bool IsSupportedVersion( unsigned int version ) {
    switch (version)
    {
+   case VER_3_3_0_13:
    case VER_4_0_0_0:
    case VER_4_0_0_2:
    case VER_4_1_0_12:
@@ -1130,11 +1133,11 @@ string FormatVersionString(unsigned version) {
 	//Format the version string and return it
 	stringstream out;
 
-	if ( int_ver[0] >= 4 ) {
-		//Version 4+ is in x.x.x.x format.
+	if ( version >= VER_3_3_0_13 ) {
+		//Version 3.3.0.13+ is in x.x.x.x format.
 		out << int_ver[0] << "." << int_ver[1] << "." << int_ver[2] << "." << int_ver[3];
 	} else {
-		//Versions before 4 are in x.x format.
+		//Versions before 3.3.0.13 are in x.x format.
 		out << int_ver[0] << "." << int_ver[1];
 	}