diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp
index e1148a38677af7a3141a94824db191ee67b576e3..b41a938e769d90944988654e1b2f8f7e54bd792d 100644
--- a/NIF_Blocks.cpp
+++ b/NIF_Blocks.cpp
@@ -34,15 +34,14 @@ POSSIBILITY OF SUCH DAMAGE. */
 //#define IM_DEBUG
 
 #include "NIF_Blocks.h"
-#include "nif_attrs.h"
 #include "nif_math.h"
+#include "nif_attrs.h"
 #include <cmath>
 #include <sstream>
 #ifdef IM_DEBUG
 #include <imdebug.h>
 #endif
 extern bool verbose;
-extern unsigned int blocks_in_memory;
 
 #ifdef WIN32
 #define endl "\r\n"
@@ -50,586 +49,6 @@ extern unsigned int blocks_in_memory;
 
 extern string current_file;
 
-/***********************************************************
- * ABlock methods
- **********************************************************/
-
-ABlock::ABlock() : _block_num(-1), _ref_count(0) {
-		blocks_in_memory++;
-	}
-
-ABlock::~ABlock() {
-	blocks_in_memory--;
-
-	// Delete all attributes
-	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
-		delete _attr_vect[i].ptr();
-	}
-
-	//cout << endl << "Removing cross reference to " << this << " from " << uint(_cross_refs.size()) << " blocks";
-	// Inform all cross-linked blocks that have added their references that this block is dying
-	list<IBlock*>::iterator it;
-	for (it = _cross_refs.begin(); it != _cross_refs.end(); ++it) {
-		//IBlockInternal * blk_int = (IBlockInternal*)(*it)->QueryInterface(BlockInternal);
-		//if ( blk_int != NULL ) {
-			((ABlock*)(*it))->RemoveCrossLink(this);
-		//}
-	}
-}
-
-void ABlock::AddAttr( AttrType type, string const & name, unsigned int first_ver, unsigned int last_ver ) {
-	IAttr * attr;
-
-	switch( type ) {
-		case attr_int:
-			attr = new IntAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_short:
-			attr = new ShortAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_byte:
-			attr = new ByteAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_float:
-			attr = new FloatAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_float3:
-			attr = new Float3Attr( name, this, first_ver, last_ver );
-			break;
-		case attr_string:
-			attr = new StringAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_link:
-			attr = new LinkAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_flags:
-			attr = new FlagsAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_matrix33:
-			attr = new MatrixAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_linkgroup:
-			attr = new LinkGroupAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_bones:
-			attr = new BoneAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_bbox:
-			attr = new BBoxAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_condint:
-			attr = new CIntAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_vertmode:
-			attr = new VertModeAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_lightmode:
-			attr = new LightModeAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_texsource:
-			attr = new TexSourceAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_pixellayout:
-			attr = new PixelLayoutAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_mipmapformat:
-			attr = new MipMapFormatAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_alphaformat:
-			attr = new AlphaFormatAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_controllertarget:
-			attr = new ControllerTargetAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_skeletonroot:
-			attr = new SkeletonRootAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_particlegroup:
-			attr = new ParticleGroupAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_lodinfo:
-			attr = new LODInfoAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_vector3:
-			attr = new Vector3Attr( name, this, first_ver, last_ver );
-			break;
-		case attr_color3:
-			attr = new Color3Attr( name, this, first_ver, last_ver );
-			break;
-		case attr_parent:
-			attr = new ParentAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_unk292bytes:
-			attr = new Unk292BytesAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_bool:
-			attr = new BoolAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_targetgroup:
-			attr = new TargetGroupAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_shader:
-			attr = new ShaderAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_modifiergroup:
-			attr = new ModifierGroupAttr( name, this, first_ver, last_ver );
-			break;
-		case attr_color4:	
-			attr = new Color4Attr( name, this, first_ver, last_ver );	
-			break;
-		case attr_quaternion:
-			attr = new QuaternionAttr( name, this, first_ver, last_ver );	
-			break;
-		case attr_emitterobject:
-			attr = new EmitterObjectAttr( name, this, first_ver, last_ver );	
-			break;
-		case attr_selflink:
-			attr = new SelfLinkAttr( name, this, first_ver, last_ver );	
-			break;
-		case attr_crossref:
-			attr = new CrossRefAttr( name, this, first_ver, last_ver );	
-			break;
-		default:
-			cout << type << endl;
-			throw runtime_error("Unknown attribute type requested.");
-	};
-
-	_attr_map[name] = attr_ref(attr);
-	_attr_vect.push_back(attr_ref(attr));
-}
-
-attr_ref ABlock::GetAttr(string const & attr_name) const {
-	map<string, attr_ref>::const_iterator it;
-	it = _attr_map.find(attr_name);
-	if (it == _attr_map.end()) {
-		//cout << "Requested Attribute does not exist:  " << attr_name << endl;
-		return attr_ref(NULL);
-	} else {
-		return attr_ref((*it).second);
-	}
-	//return _attr_map[attr_name]; 
-}
-
-
-vector<attr_ref> ABlock::GetAttrs() const {
-	return _attr_vect;
-}
-
-blk_ref ABlock::GetParent() const {
-	if (_parents.size() > 0 ) {
-		//Give preferential treatment to the first node parent
-		for ( uint i = 0; i < _parents.size(); ++i ) {
-			if ( _parents[i]->QueryInterface( ID_NODE ) ) {
-				return _parents[i];
-			}
-		}
-		return blk_ref(_parents[0]);
-	} else {
-		return blk_ref(-1);
-	}
-}
-
-void ABlock::Read( istream& in, unsigned int version ) {
-
-	//Read Attributes
-	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
-		_attr_vect[i]->Read( in, version );
-		//if ( _attr_vect[i]->GetType() != "bones" ) {
-		//	cout << "   " << _attr_vect[i]->GetName() << ":  " << _attr_vect[i]->asString() << endl;
-		//}
-	}
-	//map<string, attr_ref>::iterator it;
-	//it = _attr_map.find("Scale");
-	//if (it != _attr_map.end()) {
-	//	if ( _attr_map["Scale"]->asFloat() != 1.0f ) {
-	//		cout << "\a Non-1.0 Scale found!!!" << endl;
-	//		cin.get();
-	//	}
-	//}
-}
-
-void ABlock::Write( ostream& out, unsigned int version ) const {
-
-	//Write Attributes
-	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
-		//cout << "Writing " << blk_ref(this) << " " << _attr_vect[i]->GetName() << endl;
-		_attr_vect[i]->Write( out, version );
-	}
-}
-
-string ABlock::asString() const {
-	// Create a stringstream and set the floating point format
-	// fixed notation with one decimal place
-	stringstream out;
-	out.setf(ios::fixed, ios::floatfield);
-	out << setprecision(1);
-
-	//Output the first parent of this block
-	out << "Parent:  " << GetParent() << endl;
-
-	//Output Attributes
-	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
-		out << _attr_vect[i]->GetName() << ":  " << _attr_vect[i]->asString() << endl;
-	}
-
-	//Return result as a string
-	return out.str();
-}
-
-void ABlock::AddRef() {
-	++_ref_count;
-	//cout << GetBlockType() << " Reference increased to: " << _ref_count << endl;
-}
-
-void ABlock::SubtractRef() {
-	--_ref_count;
-	//cout << GetBlockType() << " Reference decreased to: " << _ref_count << endl;
-
-	if ( _ref_count < 1 ) {
-		//cout << "Block #" << this->GetBlockNum() << " - " << this->GetBlockType() << ":  Deleting block now." << endl;
-		delete this;
-	}
-}
-
-void ABlock::IncCrossRef( IBlock * block ) {
-	_cross_refs.push_back(block);
-}
-
-void ABlock::DecCrossRef( IBlock * block ) {
-	_cross_refs.remove(block);
-}
-
-blk_ref ABlock::Clone( unsigned int version ) {
-	//Create a string stream to temporarily hold the state-save of this block
-	stringstream tmp;
-
-	cout << "Getting a list of all the links in this block" << endl;
-
-	//Get a list of all the links in this block
-	list<blk_ref> link_list = this->GetLinks();
-
-	cout << "Putting the links into a vector & resetting block numbers" << endl;
-
-	//Put the link into a vector and reset the block number of each of these blocks to correspond to its position in the vector
-	int i = 0;
-	vector<blk_ref> link_vec( link_list.size() );
-	list<blk_ref>::iterator it;
-	for ( it = link_list.begin(); it != link_list.end(); ++it ) {
-		((ABlock*)it->get_block())->SetBlockNum(i);
-		link_vec[i] = *it;
-		++i;
-	}
-
-	cout << "Creating new block of same type" << endl;
-
-	//Create a new block of the same type
-	blk_ref clone = CreateBlock( GetBlockType() );
-
-	cout << "Writing this block's data to the stream" << endl;
-
-	//Write this block's data to the stream
-	Write( tmp, version );
-
-	cout << "Reading the data back from the stream" << endl;
-
-	//Read the data back from the stream
-	ABlock * clone_ab = (ABlock*)clone.get_block();
-	clone_ab->Read( tmp, version );
-
-	cout << "Fixing links of clone" << endl;
-
-	//Fix the links of the clone using the original link list
-	clone_ab->FixLinks( link_vec );	
-
-	cout << "Done Cloning" << endl;
-
-	//return new block
-	return clone;
-}
-
-list<blk_ref> ABlock::GetLinks() const {
-	list<blk_ref> links;
-
-	//Search through all attributes for any links and add them to the list
-	vector<attr_ref>::const_iterator it;
-	for ( it = _attr_vect.begin(); it != _attr_vect.end(); ++it ) {
-		if ( (*it)->HasLinks() == true ) {
-			list<blk_ref> link_list = (*it)->asLinkList();
-			links.merge( link_list );
-		}
-	}
-
-	//Remove NULL links
-	links.remove( blk_ref(-1) );
-
-	return links;
-}
-
-void ABlock::FixLinks( const vector<blk_ref> & blocks ) {
-	//Search through all attributes for any links and fix their references based on the list
-	vector<attr_ref>::iterator it;
-	for ( it = _attr_vect.begin(); it != _attr_vect.end(); ++it ) {
-		if ( (*it)->HasLinks() == true ) {
-			//Get the links out of this attribute and fix each one
-			list<blk_ref> links = *it;
-			list<blk_ref>::iterator it2;
-			for (it2 = links.begin(); it2 != links.end(); ++it2) {
-				int index = it2->get_index();
-				if (index < int(blocks.size()) && index >= 0 ) {
-					*it2 = blocks[index];
-				}
-			}
-			//Now clear the old links and send in the new ones
-			(*it)->ClearLinks();
-			(*it)->AddLinks(links);
-		}
-	}
-}
-
-//-- Internal Functions --//
-
-void ABlock::AddChild( IBlock * new_child ) {
-	//If the poiner is null, do nothing
-	if ( new_child == NULL )
-		return;
-
-	//Register this block as a parent of new_child
-	((ABlock*)new_child)->AddParent( this );
-	//IBlockInternal * bk_intl = (IBlockInternal*)new_child->QueryInterface( BlockInternal );
-	//if ( bk_intl != NULL ) {
-	//	bk_intl->AddParent( this );
-	//}
-}
-void ABlock::RemoveChild( IBlock * old_child ) {
-	//If the poiner is null, do nothing
-	if ( old_child == NULL )
-		return;
-
-	//Add this block to first child as a parent
-	((ABlock*)old_child)->RemoveParent( this );
-	//IBlockInternal * bk_intl = (IBlockInternal*)old_child->QueryInterface( BlockInternal );
-	//if ( bk_intl != NULL ) {
-	//	bk_intl->RemoveParent( this );
-	//}
-}
-
-void ABlock::RemoveCrossLink( IBlock * block_to_remove ) {
-	//Ask all attributes to remove any cross links they might have to the specified block
-	//cout << endl << "ABlock::RemoveCrossLink()";
-	vector<attr_ref>::iterator it;
-	for ( it = _attr_vect.begin(); it != _attr_vect.end(); ++it ) {
-		((AAttr*)it->ptr())->RemoveCrossLinks( block_to_remove );
-	}
-}
-
-
-void ABlock::AddParent( IBlock * new_parent) { 
-	//Don't add null parents
-	if ( new_parent != NULL )
-		_parents.push_back( new_parent );
-}
-
-void ABlock::RemoveParent( IBlock * match ) {
-	//Remove just one copy of the parent if there is one, incase a temporary reference is floating around
-	vector<IBlock*>::iterator it = find< vector<IBlock*>::iterator, IBlock*>( _parents.begin(), _parents.end(), match);
-	if (it != _parents.end() ) {
-		_parents.erase( it );
-	}
-
-	/*cout << blk_ref(this) << " Parents Remaining:" << endl << "   ";
-	for ( it = _parents.begin(); it != _parents.end(); ++it ) {
-		cout << blk_ref(*it) << "  ";
-	}
-	cout << endl;*/
-
-		
-	//for (it = _parents.begin(); it != _parents.end(); ) {
-	//	if ( *it == match )
-	//		_parents.erase( it );
-	//	else
-	//		++it;
-	//}
-}
-
-//--Link Classes--//
-
-
-//Constructor
-//It is required for a LinkGroup to be aware of the block it is part of
-
-void Link::SetIndex( const int new_index ) {
-	//This function is for the initial file read.  It records the index of the block which
-	//will later be resolved to a link once all the blocks have been read
-
-	//If there is already a link, kill it
-	if ( link.is_null() == false ) {
-		KillLink();
-		link.nullify();
-	}
-
-	index = new_index;
-}
-
-void Link::SetLink( const blk_ref & new_link ) {
-	if ( link != new_link ) {
-		//Kill previous link
-		KillLink();
-		
-		//Set New Link
-		link = new_link;
-		InitLink();
-	}
-}
-
-void Link::Fix( const vector<blk_ref> & blocks ) {
-	//The purpouse of this function is to convert the block index to a link
-	//to the corresponding block.
-
-	//Ensure that there is an index to convert
-	if (index == -1 ) {
-		return;
-	}
-	
-	if ( index < int(blocks.size()) && index >= 0 ) {
-		link = blocks[index];
-		InitLink();
-	}
-}
-
-void Link::SetOwner( IBlock * owner ) {
-	if ( owner != NULL ) {
-		throw runtime_error("The owner for this Link is already set.");
-	}
-	_owner = owner;
-}
-
-void Link::InitLink() {
-	//Ensure that the owner is set
-	if ( _owner == NULL ) {
-		throw runtime_error("You must specify an owner before you can store a blk_ref in a Link.");
-	}
-	//Add parent at new link site
-	IBlock * target = link.get_block();
-	if ( target != NULL ) {
-		//Get internal interface
-		((ABlock*)target)->AddParent( _owner );
-	}
-}
-void Link::KillLink() {
-	//Remove parent at previous location
-	IBlock * target = link.get_block();
-	if ( target != NULL ) {
-		((ABlock*)target)->RemoveParent( _owner );
-	}
-}
-
-void NifStream( Link & val, istream& in, uint version ) {
-	val.SetIndex( ReadInt( in ) );
-};
-
-void NifStream( Link const & val, ostream& out, uint version ) {
-	blk_ref ref = val.GetLink();
-	if ( ref.is_null() == false ) {
-		WriteInt( ref->GetBlockNum(), out );
-	} else {
-		WriteInt( -1, out );
-	}
-}
-
-ostream & operator<<( ostream & out, Link const & val ) {
-	return out << val.GetLink();
-}
-
-//--CrossRef Classes--//
-
-void CrossRef::SetIndex( const int new_index ) {
-	//This function is for the initial file read.  It records the index of the block which
-	//will later be resolved to a reference once all the blocks have been read
-
-	//If there is already a reference, kill it
-	if ( ref != NULL ) {
-		KillRef();
-		ref = NULL;
-	}
-
-	index = new_index;
-}
-
-void CrossRef::SetCrossRef( IBlock * new_ref ) {
-	if ( ref != new_ref ) {
-		//Kill previous link
-		KillRef();
-		
-		//Set New Link
-		ref = new_ref;
-		InitRef();
-	}
-}
-
-void CrossRef::LostRef(  IBlock * match ) {
-	//This function's purpouse is to inform this CrossRef that the block it is referencing has died
-	//It will be called on every CrossRef in this block, we must check to see if this is the one that
-	//the message is meant for
-	if ( ref == match ) {
-		//Simply set it to NULL  do not call KillRef because the reference is already dead
-		ref = NULL;
-	}
-}
-
-void CrossRef::Fix( const vector<blk_ref> & blocks ) {
-	//The purpouse of this function is to convert the block index to a reference
-	//to the corresponding block.
-	
-	if (index < int(blocks.size()) && index >= 0 ) {
-		ref = blocks[index].get_block();
-		index = -1;
-		InitRef();
-	}
-}
-
-void CrossRef::SetOwner( IBlock * owner ) {
-	if ( owner != NULL ) {
-		throw runtime_error("The owner for this Link is already set.");
-	}
-	_owner = owner;
-}
-
-void CrossRef::InitRef() {
-	//Inform target block that it is being cross referenced
-	//Ensure that the owner is set
-	if ( _owner == NULL ) {
-		throw runtime_error("You must specify an owner before you can store an IBlock * in a CrossRef.");
-	}
-	if ( ref != NULL ) {
-		//Get internal interface
-		((ABlock*)ref)->IncCrossRef( _owner );
-	}
-}
-void CrossRef::KillRef() {
-	//Inform target block that it is no longer being cross referenced
-	if ( ref != NULL ) {
-		((ABlock*)ref)->IncCrossRef( _owner );
-	}
-}
-
-
-void NifStream( CrossRef & val, istream& in, uint version ) {
-	val.SetIndex( ReadInt( in ) );
-};
-
-void NifStream( CrossRef const & val, ostream& out, uint version ) {
-	IBlock * ref = val.GetCrossRef();
-	if ( ref != NULL ) {
-		WriteInt( ref->GetBlockNum(), out );
-	} else {
-		WriteInt( -1, out );
-	}
-}
-
-ostream & operator<<( ostream & out, CrossRef const & val ) {
-	return out << blk_ref(val.GetCrossRef());
-}
-
 /***********************************************************
  * ANode methods
  **********************************************************/
@@ -1491,7 +910,7 @@ string NiScreenLODData::asString() const {
  */
 void AShapeData::Read( istream& in, unsigned int version ){
 
-	GetAttr("Name")->Read( in, version );
+	//GetAttr("Name")->Read( in, version );
 	
 	ushort vert_count = ReadUShort( in );
 
@@ -1571,7 +990,7 @@ void AShapeData::Read( istream& in, unsigned int version ){
 		ReadUShort( in );
 	}
 
-	GetAttr("Unknown Link")->Read( in, version );
+	//GetAttr("Unknown Link")->Read( in, version );
 }
 
 string AShapeData::asString() const {
@@ -1726,7 +1145,7 @@ void AShapeData::CalcCentAndRad( Vector3 & center, float & radius ) const {
  */
 void AShapeData::Write( ostream& out, unsigned int version ) const {
 
-	GetAttr("Name")->Write( out, version );
+	//GetAttr("Name")->Write( out, version );
 	
 	WriteUShort( ushort(vertices.size()), out );
 
@@ -1808,7 +1227,7 @@ void AShapeData::Write( ostream& out, unsigned int version ) const {
 		WriteUShort( 0, out );
 	}
 
-	GetAttr("Unknown Link")->Write( out, version );
+	//GetAttr("Unknown Link")->Write( out, version );
 }
 
 void * AShapeData::QueryInterface( int id ) {
@@ -2071,14 +1490,14 @@ void NiMeshPSysData::Read( istream& file, unsigned int version ) {
 
 	NifStream( unkInt, file );
 
-	GetAttr("Modifier")->Read( file, version );
+	//GetAttr("Modifier")->Read( file, version );
 
 	// From version 10.2.0.0 there are several new entries here
 	if ( version >= VER_10_2_0_0 ) {
 		NifStream( unkByte, file );
 
-		GetAttr("Unknown Link Group")->Read( file, version );
-		GetAttr("Unknown Link 2")->Read( file, version );
+		//GetAttr("Unknown Link Group")->Read( file, version );
+		//GetAttr("Unknown Link 2")->Read( file, version );
 	}
 }
 
@@ -2089,14 +1508,14 @@ void NiMeshPSysData::Write( ostream& file, unsigned int version ) const {
 
 	NifStream( unkInt, file );
 
-	GetAttr("Modifier")->Write( file, version );
+	//GetAttr("Modifier")->Write( file, version );
 
 	// From version 10.2.0.0 there are several new entries here
 	if ( version >= VER_10_2_0_0 ) {
 		NifStream( unkByte, file );
 
-		GetAttr("Unknown Link Group")->Write( file, version );
-		GetAttr("Unknown Link 2")->Write( file, version );
+		//GetAttr("Unknown Link Group")->Write( file, version );
+		//GetAttr("Unknown Link 2")->Write( file, version );
 	}
 }
 
@@ -2316,13 +1735,13 @@ string ARotatingParticlesData::asString() const {
 void NiParticleMeshesData::Read( istream& in, unsigned int version ) {
 	ARotatingParticlesData::Read( in, version );
 
-	GetAttr("Unknown Link 2")->Read( in, version );
+	//GetAttr("Unknown Link 2")->Read( in, version );
 }
 
 void NiParticleMeshesData::Write( ostream& out, unsigned int version ) const {
 	ARotatingParticlesData::Write( out, version );
 
-	GetAttr("Unknown Link 2")->Write( out, version );
+	//GetAttr("Unknown Link 2")->Write( out, version );
 }
 
 string NiParticleMeshesData::asString() const {
@@ -2790,7 +2209,7 @@ void NiSkinData::Read( istream& in, unsigned int version ) {
 	ReadFVector3( translation, in );
 	scale = ReadFloat( in );
 	int boneCount = ReadUInt( in );
-	GetAttr("Skin Partition")->Read( in, version );
+	//GetAttr("Skin Partition")->Read( in, version );
 	//unknownByte exists from version 4.2.1.0 on
 	if ( version >= VER_4_2_1_0 ) {
 		unknownByte = ReadByte( in );
@@ -2831,7 +2250,7 @@ void NiSkinData::Write( ostream& out, unsigned int version ) const {
 	WriteFVector3( tr, out );
 	WriteFloat( sc, out );
 	WriteUInt(short(bone_map.size()), out);
-	GetAttr("Skin Partition")->Write( out, version );
+	//GetAttr("Skin Partition")->Write( out, version );
 	//unknownByte exists from version 4.2.1.0 on
 	if ( version >= VER_4_2_1_0) {
 		WriteByte( unknownByte, out );
@@ -3845,7 +3264,7 @@ string NiColorData::asString() const {
  **********************************************************/
 
 void NiControllerSequence::Read( istream& file, unsigned int version ) {
-	GetAttr("Name")->Read( file, version );
+	//GetAttr("Name")->Read( file, version );
 
 	//Up to version 10.1.0.0 the text key block is up here and named
 	if ( version <= VER_10_1_0_0 ) {
@@ -3903,12 +3322,12 @@ void NiControllerSequence::Read( istream& file, unsigned int version ) {
 		}
 		NifStream( unk_int2, file );
 		NifStream( unk_string, file );
-		GetAttr("String Palette")->Read( file, version );
+		//GetAttr("String Palette")->Read( file, version );
 	}
 }
 
 void NiControllerSequence::Write( ostream& file, unsigned int version ) const {
-	GetAttr("Name")->Write( file, version );
+	//GetAttr("Name")->Write( file, version );
 
 	//Up to version 10.1.0.0 the text key block is up here and named
 	if ( version <= VER_10_1_0_0 ) {
@@ -3934,7 +3353,7 @@ void NiControllerSequence::Write( ostream& file, unsigned int version ) const {
 		if ( version >= VER_10_2_0_0 ) {
 			WriteUInt( children[i].unk_link.get_index(), file );
 			//Write duplicate String Palette index
-			GetAttr("String Palette")->Write( file, version );
+			//GetAttr("String Palette")->Write( file, version );
 
 			//Write offsets
 			NifStream( children[i].name_offset, file );
@@ -3966,7 +3385,7 @@ void NiControllerSequence::Write( ostream& file, unsigned int version ) const {
 		}
 		NifStream( unk_int2, file );
 		NifStream( unk_string, file );
-		GetAttr("String Palette")->Write( file, version );
+		//GetAttr("String Palette")->Write( file, version );
 	}
 }
 
@@ -4269,7 +3688,7 @@ void NiStringExtraData::Read( istream& in, unsigned int version ) {
 		ReadUInt( in );
 	}
 
-	GetAttr("String Data")->Read( in, version );
+	//GetAttr("String Data")->Read( in, version );
 }
 
 void NiStringExtraData::Write( ostream& out, unsigned int version ) const {
@@ -4284,7 +3703,7 @@ void NiStringExtraData::Write( ostream& out, unsigned int version ) const {
 		WriteUInt( uint(string_data->asString().length()) + 4, out );
 	}
 
-	string_data->Write( out, version );
+	//string_data->Write( out, version );
 }
 
 string NiStringExtraData::asString() const {
@@ -4338,7 +3757,7 @@ void NiMorphData::Write( ostream& file, unsigned int version ) const {
 	WriteUInt( uint(morphs.size()), file );
 	NifStream( vertCount, file );
 
-	GetAttr("Unknown Byte")->Write( file, version );
+	//GetAttr("Unknown Byte")->Write( file, version );
 
 	for ( uint i = 0; i < morphs.size() ; ++i ) {
 		WriteUInt( uint(morphs[i].keys.size()), file );
@@ -4720,7 +4139,7 @@ string NiSkinPartition::asString() const {
 
 void NiStringPalette::Read( istream& file, unsigned int version ) {
 
-	GetAttr("Palette")->Read( file, version );
+	//GetAttr("Palette")->Read( file, version );
 
 	//Read extra length and throw it away
 	ReadUInt( file );
@@ -4729,7 +4148,7 @@ void NiStringPalette::Read( istream& file, unsigned int version ) {
 void NiStringPalette::Write( ostream& file, unsigned int version ) const {
 
 	attr_ref pal_attr = GetAttr("Palette");
-	pal_attr->Write( file, version );
+	//pal_attr->Write( file, version );
 	string pal_str = pal_attr->asString();
 
 	//Write length of string again
@@ -4797,7 +4216,7 @@ void NiPixelData::Read( istream& file, unsigned int version ) {
 		file.read( (char*)unk54Bytes, 54 );
 	}
 
-	GetAttr("Palette")->Read( file, version );
+	//GetAttr("Palette")->Read( file, version );
 
 	uint mipCount = ReadUInt( file );
 
@@ -4848,7 +4267,7 @@ void NiPixelData::Write( ostream& file, unsigned int version ) const {
 		}
 	}
 
-	GetAttr("Palette")->Write( file, version );
+	//GetAttr("Palette")->Write( file, version );
 
 	//If there is no data stored, then there are no mipmaps.
 	if ( dataSize > 0 ) {
@@ -5337,7 +4756,7 @@ void NiTextKeyExtraData::Read( istream& file, unsigned int version ) {
 	GetAttr("Next Extra Data")->Read( file, version );
 	*/
 	AExtraData::Read( file, version );
-	GetAttr("Unknown Int")->Read( file, version );
+	//GetAttr("Unknown Int")->Read( file, version );
 
 	uint keyCount = ReadUInt( file );
 
@@ -5353,7 +4772,7 @@ void NiTextKeyExtraData::Write( ostream& file, unsigned int version ) const {
 	GetAttr("Next Extra Data")->Write( file, version );
 	*/
 	AExtraData::Write( file, version );
-	GetAttr("Unknown Int")->Write( file, version );
+	//GetAttr("Unknown Int")->Write( file, version );
 
 	WriteUInt( uint(_keys.size()), file );
 
diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index b9bb923b6b96a6d077ec09f438ef373a3d310d48..c1d1c3a132681be0a04b608648db97776e0dfd9f 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. */
 #define _NIF_BLOCKS_H
 
 /* INCLUDES */
-#include "niflib.h"
+#include "niflib_internal.h"
 #include "nif_math.h"
 #include "NIF_IO.h"
 
@@ -58,125 +58,6 @@ typedef pair<LinkMapIt,LinkMapIt> LinkMapRange;
 const int SkinInstInternal = -2;
 const int SkinDataInternal = -3;
 
-class ABlock : public IBlock {
-public:
-	ABlock();
-	~ABlock();
-	blk_ref Clone( unsigned int version = 0xFFFFFFFF );
-	void AddAttr( AttrType type, string const & name, unsigned int first_ver = 0, unsigned int last_ver = 0xFFFFFFFF );
-	attr_ref GetAttr(string const & attr_name) const;
-	vector<attr_ref> GetAttrs() const;
-	int GetBlockNum() const { return _block_num; }
-	bool IsControllable() const { return false; }
-	bool IsController() const { return false; }
-	string asString() const;
-
-	//Links
-	blk_ref GetParent() const;
-	list<blk_ref> GetLinks() const;
-
-	//Reference Counting
-	void AddRef();
-	void SubtractRef();
-
-	//Interface
-	void * QueryInterface( int id ) {
-		/*if ( id == BlockInternal ) {
-			return (void*)static_cast<IBlockInternal*>(this);;
-		} else {*/
-			return NULL;
-		/*}*/
-	}
-
-	void const * QueryInterface( int id ) const {
-		/*if ( id == BlockInternal ) {
-			return (void const *)static_cast<IBlockInternal const *>(this);;
-		} else {*/
-			return NULL;
-		/*}*/
-	}
-
-	//--Internal Functions--//
-	void AddParent( IBlock * new_parent);
-	void RemoveParent( IBlock * match );
-	void SetBlockNum( int n ) { _block_num = n; }
-	virtual void FixLinks( const vector<blk_ref> & blocks );
-	void SetBlockTypeNum( int n ) { _block_type_num = n; }
-	int GetBlockTypeNum() { return _block_type_num; }
-
-	void AddChild( IBlock * new_child );
-	void RemoveChild( IBlock * old_child );
-
-	virtual void RemoveCrossLink( IBlock * block_to_remove );
-
-	void IncCrossRef( IBlock * block );
-	void DecCrossRef( IBlock * block );
-	virtual void ReassignCrossRefs( const map<string,blk_ref> & name_map ) {}
-
-	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;
-	int _block_num;
-	int _block_type_num;
-	unsigned int _ref_count;
-	vector<IBlock*> _parents;
-	list<IBlock*> _cross_refs;
-};
-
-//--Link Classes--//
-
-class Link {
-public:
-	//Constructors
-	Link () : _owner(NULL), index(-1) {}
-	Link ( IBlock * owner) : _owner(owner), index(-1) {}
-	//Destructor
-	~Link() { KillLink(); }
-	void SetIndex( const int new_index );
-	blk_ref GetLink() const { return link; }
-	void SetLink( const blk_ref & new_link );
-	void Fix( const vector<blk_ref> & blocks );
-	void SetOwner( IBlock * owner );
-private:
-	IBlock * _owner;
-	blk_ref link;
-	int index;
-	void InitLink();
-	void KillLink();
-};
-
-void NifStream( Link & val, istream& in, uint version = 0 );
-void NifStream( Link const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, Link const & val );
-
-//--CrossRef Classes--//
-
-class CrossRef {
-public:
-	//Constructors
-	CrossRef () : _owner(NULL), ref(NULL), index(-1) {}
-	CrossRef ( IBlock * owner) : _owner(owner), ref(NULL), index(-1) {}
-	//Destructor
-	~CrossRef() { KillRef(); }
-	void SetIndex( const int new_index );
-	IBlock * GetCrossRef() const { return ref; }
-	void SetCrossRef( IBlock * new_ref );
-	void LostRef( IBlock * match );
-	void Fix( const vector<blk_ref> & blocks );
-	void SetOwner( IBlock * owner );
-private:
-	IBlock * _owner;
-	IBlock * ref;
-	int index;
-	void InitRef();
-	void KillRef();
-};
-void NifStream( CrossRef & val, istream& in, uint version  = 0);
-void NifStream( CrossRef const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, CrossRef const & val );
-
 class AControllable : public ABlock {
 public:
 	AControllable();
@@ -318,17 +199,17 @@ public:
 class AExtraData : public AData {
 public:
 	AExtraData() {
-		AddAttr( attr_string, "Name", VER_10_0_1_0 );
-		AddAttr( attr_link, "Next Extra Data", 0, VER_4_2_2_0 );
+		//AddAttr( attr_string, "Name", VER_10_0_1_0 );
+		//AddAttr( attr_link, "Next Extra Data", 0, VER_4_2_2_0 );
 	}
 	~AExtraData() {};
 	void Read( istream& in, unsigned int version ) {
-		GetAttr("Name")->Read( in, version );
-		GetAttr("Next Extra Data")->Read( in, version );
+		//GetAttr("Name")->Read( in, version );
+		//GetAttr("Next Extra Data")->Read( in, version );
 	}
 	void Write( ostream& out, unsigned int version ) const {
-		GetAttr("Name")->Write( out, version );
-		GetAttr("Next Extra Data")->Write( out, version );
+		//GetAttr("Name")->Write( out, version );
+		//GetAttr("Next Extra Data")->Write( out, version );
 	}
 	string asString() const {
 		stringstream out;
@@ -616,7 +497,8 @@ public:
  */
 class NiTexturingProperty : public AProperty, public ITexturingProperty {
 public:
-	NiTexturingProperty( ) { AddAttr( attr_flags, "Flags", 0, VER_10_0_1_0 ); }
+	NiTexturingProperty( ) { //AddAttr( attr_flags, "Flags", 0, VER_10_0_1_0 ); 
+	}
 	void Init() {}
 	~NiTexturingProperty();
 	string GetBlockType() const { return "NiTexturingProperty"; }
@@ -692,8 +574,8 @@ public:
 	NiPixelData() {
 		data = NULL;
 		dataSize = 0;
-		AddAttr( attr_int, "Unknown Int" );
-		AddAttr( attr_link, "Palette" );
+		//AddAttr( attr_int, "Unknown Int" );
+		//AddAttr( attr_link, "Palette" );
 
 	}
 	~NiPixelData() { if (data != NULL) delete [] data; }
@@ -793,8 +675,8 @@ public:
 class AShapeData : public AData, public IShapeData {
 public:
 	AShapeData() {
-		AddAttr( attr_string, "Name", VER_10_2_0_0 );
-		AddAttr( attr_link, "Unknown Link", VER_20_0_0_4 );
+		//AddAttr( attr_string, "Name", VER_10_2_0_0 );
+		//AddAttr( attr_link, "Unknown Link", VER_20_0_0_4 );
 	}
 	~AShapeData() {}
 	void Read( istream& in, unsigned int version );
@@ -872,9 +754,9 @@ protected:
 class NiMeshPSysData : public APSysData {
 public:
 	NiMeshPSysData() {
-		AddAttr( attr_link, "Modifier" );
-		AddAttr( attr_linkgroup, "Unknown Link Group", VER_10_2_0_0 );
-		AddAttr( attr_link, "Unknown Link 2", VER_10_2_0_0 );
+		//AddAttr( attr_link, "Modifier" );
+		//AddAttr( attr_linkgroup, "Unknown Link Group", VER_10_2_0_0 );
+		//AddAttr( attr_link, "Unknown Link 2", VER_10_2_0_0 );
 	}
 	~NiMeshPSysData() {}
 	void Read( istream& in, unsigned int version );
@@ -934,7 +816,7 @@ protected:
 class NiParticleMeshesData : public ARotatingParticlesData {
 public:
 	NiParticleMeshesData() {
-		AddAttr( attr_link, "Unknown Link 2" );
+		//AddAttr( attr_link, "Unknown Link 2" );
 	}
 	~NiParticleMeshesData() {}
 	void Read( istream& in, unsigned int version );
@@ -1023,7 +905,9 @@ private:
  */
 class NiBSplineBasisData : public AData {
 public:
-	NiBSplineBasisData() { AddAttr( attr_int, "Unknown Int" ); }
+	NiBSplineBasisData() { 
+		//AddAttr( attr_int, "Unknown Int" );
+	}
 	~NiBSplineBasisData() {}
 
 	string GetBlockType() const { return "NiBSplineBasisData"; }
@@ -1920,7 +1804,9 @@ private:
 
 class NiStringPalette : public AData {
 public:
-	NiStringPalette() { AddAttr( attr_string, "Palette" ); }
+	NiStringPalette() { 
+		//AddAttr( attr_string, "Palette" ); 
+	}
 	void Init() {}
 	~NiStringPalette() {}
 	void Read( istream& in, unsigned int version );
@@ -1945,10 +1831,10 @@ public:
 class NiSkinInstance : public AData, public ISkinInstInternal {
 public:
 	NiSkinInstance(){
-		AddAttr( attr_link, "Data" );
-		AddAttr( attr_link, "Skin Partition", VER_10_2_0_0 );
-		AddAttr( attr_skeletonroot, "Skeleton Root" );
-		AddAttr( attr_bones, "Bones" );
+		//AddAttr( attr_link, "Data" );
+		//AddAttr( attr_link, "Skin Partition", VER_10_2_0_0 );
+		//AddAttr( attr_skeletonroot, "Skeleton Root" );
+		//AddAttr( attr_bones, "Bones" );
 	}
 	~NiSkinInstance() {}
 	string GetBlockType() const { return "NiSkinInstance"; }
@@ -1996,7 +1882,7 @@ class NiSkinData : public AData, public ISkinData, public ISkinDataInternal {
 	public:
 
 		NiSkinData() { 
-			AddAttr( attr_link, "Skin Partition", 0, VER_10_1_0_0 );
+			//AddAttr( attr_link, "Skin Partition", 0, VER_10_1_0_0 );
 			SetIdentity33(rotation);
 			translation[0] = 0.0f;
 			translation[1] = 0.0f;
@@ -2140,8 +2026,8 @@ private:
 class NiControllerSequence : public AData, public IControllerSequence {
 public:
 	NiControllerSequence() {
-		AddAttr( attr_string, "Name" );
-		AddAttr( attr_link, "String Palette", VER_10_2_0_0 );
+		//AddAttr( attr_string, "Name" );
+		//AddAttr( attr_link, "String Palette", VER_10_2_0_0 );
 	}
 	~NiControllerSequence();
 
@@ -2274,7 +2160,7 @@ private:
 class NiStringExtraData : public AExtraData {
 public:
 	NiStringExtraData() {
-		AddAttr( attr_string, "String Data" );
+		//AddAttr( attr_string, "String Data" );
 	}
 	~NiStringExtraData() {}
 
@@ -2287,18 +2173,18 @@ public:
 class NiBooleanExtraData : public AExtraData {
 public:
 	NiBooleanExtraData() {
-		AddAttr( attr_byte, "Boolean Data" );
+		//AddAttr( attr_byte, "Boolean Data" );
 	}
 	~NiBooleanExtraData() {}
 	string GetBlockType() const { return "NiBooleanExtraData"; };
 
 	void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
-		GetAttr("Boolean Data")->Read( in, version );
+		//GetAttr("Boolean Data")->Read( in, version );
 	}
 	void Write( ostream& out, unsigned int version ) const {
 		AExtraData::Write( out, version );
-		GetAttr("Boolean Data")->Write( out, version );
+		//GetAttr("Boolean Data")->Write( out, version );
 	}
 
 	string asString() const {
@@ -2357,20 +2243,20 @@ private:
 class NiVectorExtraData : public AExtraData {
 public:
 	NiVectorExtraData() {
-		AddAttr( attr_vector3, "Vector Data" );
-		AddAttr( attr_float, "Unknown Float" );
+		//AddAttr( attr_vector3, "Vector Data" );
+		//AddAttr( attr_float, "Unknown Float" );
 	}
 	~NiVectorExtraData() {}
 	string GetBlockType() const { return "NiVectorExtraData"; };
 
 	void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
-		GetAttr("Vector Data")->Read( in, version );
-		GetAttr("Unknown Float")->Read( in, version );
+		//GetAttr("Vector Data")->Read( in, version );
+		//GetAttr("Unknown Float")->Read( in, version );
 	}
 	void Write( ostream& out, unsigned int version ) const {
-		GetAttr("Vector Data")->Write( out, version );
-		GetAttr("Unknown Float")->Write( out, version );
+		//GetAttr("Vector Data")->Write( out, version );
+		//GetAttr("Unknown Float")->Write( out, version );
 	}
 
 	string asString() const {
@@ -2419,18 +2305,18 @@ private:
 class NiFloatExtraData : public AExtraData {
 public:
 	NiFloatExtraData() {
-		AddAttr( attr_float, "Float Data" );
+		//AddAttr( attr_float, "Float Data" );
 	}
 	~NiFloatExtraData() {}
 	string GetBlockType() const { return "NiFloatExtraData"; };
 
 	void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
-		GetAttr("Float Data")->Read( in, version );
+		//GetAttr("Float Data")->Read( in, version );
 	}
 	void Write( ostream& out, unsigned int version ) const {
 		AExtraData::Write( out, version );
-		GetAttr("Float Data")->Write( out, version );
+		//GetAttr("Float Data")->Write( out, version );
 	}
 
 	string asString() const {
@@ -2521,7 +2407,7 @@ private:
 class NiIntegerExtraData : public AExtraData {
 public:
 	NiIntegerExtraData() {
-		AddAttr( attr_int, "Integer Data" );
+		//AddAttr( attr_int, "Integer Data" );
 	}
 	~NiIntegerExtraData() {}
 
@@ -2529,11 +2415,11 @@ public:
 
 	void Read( istream& in, unsigned int version ) {
 		AExtraData::Read( in, version );
-		GetAttr("Integer Data")->Read( in, version );
+		//GetAttr("Integer Data")->Read( in, version );
 	}
 	void Write( ostream& out, unsigned int version ) const {
 		AExtraData::Write( out, version );
-		GetAttr("Integer Data")->Write( out, version );
+		//GetAttr("Integer Data")->Write( out, version );
 	}
 
 	string asString() const {
@@ -2551,7 +2437,7 @@ public:
 class NiMorphData : public AData, public IMorphData {
 public:
 	NiMorphData() {
-		AddAttr( attr_byte, "Unknown Byte" );
+		//AddAttr( attr_byte, "Unknown Byte" );
 	}
 	~NiMorphData() {}
 
@@ -2656,7 +2542,7 @@ public:
 class NiTextKeyExtraData : public AExtraData, public ITextKeyExtraData {
 public:
 	NiTextKeyExtraData() {
-		AddAttr( attr_int, "Unknown Int", 0, VER_4_2_2_0 );
+		//AddAttr( attr_int, "Unknown Int", 0, VER_4_2_2_0 );
 	}
 	~NiTextKeyExtraData() {}
 
diff --git a/NIF_IO.cpp b/NIF_IO.cpp
index e3b490bed6a157a9fe19adfdf9913102418d9bfb..e608867ca8967c3356169f5ce5e4db4a1dfe42d2 100644
--- a/NIF_IO.cpp
+++ b/NIF_IO.cpp
@@ -653,10 +653,10 @@ void NifStream( TexDesc & val, istream& in, uint version ) {
 				val.translation.v = ReadFloat( in );
 				val.tiling.u = ReadFloat( in );
 				val.tiling.v = ReadFloat( in );
-				val.w_rotation = ReadFloat( in );
-				val.transform_type = ReadUInt( in );
-				val.center_offset.u = ReadFloat( in );
-				val.center_offset.v = ReadFloat( in );
+				val.wRotation = ReadFloat( in );
+				val.transformType = ReadUInt( in );
+				val.centerOffset.u = ReadFloat( in );
+				val.centerOffset.v = ReadFloat( in );
 			}
 		}
 	}
@@ -691,10 +691,10 @@ void NifStream( TexDesc const & val, ostream& out, uint version ) {
 				WriteFloat( val.translation.v, out );
 				WriteFloat( val.tiling.u, out );
 				WriteFloat( val.tiling.v, out );
-				WriteFloat( val.w_rotation, out );
-				WriteUInt( val.transform_type, out );
-				WriteFloat( val.center_offset.u, out );
-				WriteFloat( val.center_offset.v, out );
+				WriteFloat( val.wRotation, out );
+				WriteUInt( val.transformType, out );
+				WriteFloat( val.centerOffset.u, out );
+				WriteFloat( val.centerOffset.v, out );
 			}
 		}
 	}
@@ -716,9 +716,9 @@ ostream & operator<<( ostream & out, TexDesc const & val ) {
 			out << endl
 				<< "         Translation: " << val.translation << endl
 				<< "         Tiling: " << val.tiling << endl
-				<< "         W-rotation: " << val.w_rotation << endl
-				<< "         Transform Type: " << val.transform_type << endl
-				<< "         Center Offset: " << val.center_offset << endl;
+				<< "         W-rotation: " << val.wRotation << endl
+				<< "         Transform Type: " << val.transformType << endl
+				<< "         Center Offset: " << val.centerOffset << endl;
 		} else {
 			out << "None" << endl;
 		}
@@ -729,6 +729,42 @@ ostream & operator<<( ostream & out, TexDesc const & val ) {
 	return out;
 }
 
+//CrossRef
+void NifStream( CrossRef & val, istream& in, uint version ) {
+	val.SetIndex( ReadInt( in ) );
+};
+
+void NifStream( CrossRef const & val, ostream& out, uint version ) {
+	IBlock * ref = val.GetCrossRef();
+	if ( ref != NULL ) {
+		WriteInt( ref->GetBlockNum(), out );
+	} else {
+		WriteInt( -1, out );
+	}
+}
+
+ostream & operator<<( ostream & out, CrossRef const & val ) {
+	return out << blk_ref(val.GetCrossRef());
+}
+
+//Link
+void NifStream( Link & val, istream& in, uint version ) {
+	val.SetIndex( ReadInt( in ) );
+};
+
+void NifStream( Link const & val, ostream& out, uint version ) {
+	blk_ref ref = val.GetLink();
+	if ( ref.is_null() == false ) {
+		WriteInt( ref->GetBlockNum(), out );
+	} else {
+		WriteInt( -1, out );
+	}
+}
+
+ostream & operator<<( ostream & out, Link const & val ) {
+	return out << val.GetLink();
+}
+
 
 
 //--Enums--//
diff --git a/NIF_IO.h b/NIF_IO.h
index 2dcf46d8cf36f9b5abfd86a35d4827f54bb4e30d..83a6116d64adfd95b6ab9206f87e875a5615b49f 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -39,17 +39,9 @@ POSSIBILITY OF SUCH DAMAGE. */
 #include <iomanip>
 #include <string>
 #include <sstream>
-#include "niflib.h"
+#include "niflib_internal.h"
 using namespace std;
 
-struct HeaderString {
-	string header;
-};
-
-typedef unsigned char	byte;
-typedef unsigned short	ushort;
-typedef unsigned int	uint;
-
 typedef ushort usVector3[3];
 
 typedef float fVector2[2];
@@ -222,6 +214,16 @@ void NifStream( TexDesc & val, istream& in, uint version );  // version is signi
 void NifStream( TexDesc const & val, ostream& out, uint version ); // version is significant
 ostream & operator<<( ostream & out, TexDesc const & val );
 
+//Link
+void NifStream( Link & val, istream& in, uint version = 0 );
+void NifStream( Link const & val, ostream& out, uint version = 0 );
+ostream & operator<<( ostream & out, Link const & val );
+
+//CrossRef
+void NifStream( CrossRef & val, istream& in, uint version  = 0);
+void NifStream( CrossRef const & val, ostream& out, uint version = 0 );
+ostream & operator<<( ostream & out, CrossRef const & val );
+
 //--Enums--//
 
 //TexType
diff --git a/docsys_extract.cpp b/docsys_extract.cpp
index b83d63691018132acc9efc568748002386d456c0..1da50544455aac82b1a6b4cb22f67f56a715d1e5 100644
--- a/docsys_extract.cpp
+++ b/docsys_extract.cpp
@@ -39,34 +39,34 @@ extern map<string, blk_factory_func> global_block_map;
 //--Block Class Constructors--//
 
 AControllable::AControllable() {
-	AddAttr( attr_string, "Name", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Extra Data", 0, 67240448 );
-	AddAttr( attr_linkgroup, "Extra Data List", 167772416, 0xFFFFFFFF );
-	AddAttr( attr_link, "Controller", 0, 0xFFFFFFFF );
+	//AddAttr( attr_string, "Name", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Extra Data", 0, 67240448 );
+	//AddAttr( attr_linkgroup, "Extra Data List", 167772416, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Controller", 0, 0xFFFFFFFF );
 	Init();
 }
 
 AController::AController() {
-	AddAttr( attr_link, "Next Controller", 0, 0xFFFFFFFF );
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frequency", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Phase", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Start Time", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Stop Time", 0, 0xFFFFFFFF );
-	AddAttr( attr_controllertarget, "Target", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Next Controller", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frequency", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Phase", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Start Time", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Stop Time", 0, 0xFFFFFFFF );
+	//AddAttr( attr_controllertarget, "Target", 0, 0xFFFFFFFF );
 	Init();
 }
 
 ADynamicEffect::ADynamicEffect() {
-	AddAttr( attr_condint, "Affected Node List?", 0, 67108866 );
-	AddAttr( attr_bool, "Switch State", 167903232, 0xFFFFFFFF );
-	AddAttr( attr_linkgroup, "Affected Nodes", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_condint, "Affected Node List?", 0, 67108866 );
+	//AddAttr( attr_bool, "Switch State", 167903232, 0xFFFFFFFF );
+	//AddAttr( attr_linkgroup, "Affected Nodes", 167837696, 0xFFFFFFFF );
 	Init();
 }
 
 AFx::AFx() {
-	AddAttr( attr_byte, "Unknown1", 0, 0xFFFFFFFF );
-	AddAttr( attr_unk292bytes, "Unknown2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_unk292bytes, "Unknown2", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -75,34 +75,34 @@ AInterpolator::AInterpolator() {
 }
 
 ALight::ALight() {
-	AddAttr( attr_float, "Dimmer", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Ambient Color", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Diffuse Color", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Specular Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Dimmer", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Ambient Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Diffuse Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Specular Color", 0, 0xFFFFFFFF );
 	Init();
 }
 
 ANode::ANode() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Translation", 0, 0xFFFFFFFF );
-	AddAttr( attr_matrix33, "Rotation", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Scale", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Velocity", 0, 67240448 );
-	AddAttr( attr_linkgroup, "Properties", 0, 0xFFFFFFFF );
-	AddAttr( attr_bbox, "Bounding Box", 0, 67240448 );
-	AddAttr( attr_link, "Collision Data", 167772416, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Translation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_matrix33, "Rotation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Scale", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Velocity", 0, 67240448 );
+	//AddAttr( attr_linkgroup, "Properties", 0, 0xFFFFFFFF );
+	//AddAttr( attr_bbox, "Bounding Box", 0, 67240448 );
+	//AddAttr( attr_link, "Collision Data", 167772416, 0xFFFFFFFF );
 	Init();
 }
 
 AParentNode::AParentNode() {
-	AddAttr( attr_linkgroup, "Children", 0, 0xFFFFFFFF );
-	AddAttr( attr_linkgroup, "Effects", 0, 0xFFFFFFFF );
+	//AddAttr( attr_linkgroup, "Children", 0, 0xFFFFFFFF );
+	//AddAttr( attr_linkgroup, "Effects", 0, 0xFFFFFFFF );
 	Init();
 }
 
 AParticleModifier::AParticleModifier() {
-	AddAttr( attr_link, "Next Modifier", 0, 0xFFFFFFFF );
-	AddAttr( attr_parent, "Previous Modifier", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Next Modifier", 0, 0xFFFFFFFF );
+	//AddAttr( attr_parent, "Previous Modifier", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -111,46 +111,46 @@ AParticleNode::AParticleNode() {
 }
 
 AParticleSystemController::AParticleSystemController() {
-	AddAttr( attr_float, "Speed", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Speed Random", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Vertical Direction", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Vertical Angle", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Horizontal Direction", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Horizontal Angle", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 6", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 7", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 8", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 9", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 10", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 11", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Size", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Emit Start Time", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Emit Stop Time", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Emit Rate", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Lifetime", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Lifetime Random", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Start Random", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Emitter", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short 2?", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 13?", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 1?", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 2?", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short 3?", 0, 0xFFFFFFFF );
-	AddAttr( attr_particlegroup, "Particles", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Particle Extra", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Trailer", 0, 0xFFFFFFFF );
+	///*AddAttr( attr_float, "Speed", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Speed Random", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Vertical Direction", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Vertical Angle", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Horizontal Direction", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Horizontal Angle", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 6", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 7", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 8", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 9", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 10", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 11", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Size", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Emit Start Time", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Emit Stop Time", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Emit Rate", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Lifetime", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Lifetime Random", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Start Random", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Emitter", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short 2?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 13?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 1?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 2?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short 3?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_particlegroup, "Particles", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Particle Extra", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Trailer", 0, 0xFFFFFFFF );*/
 	Init();
 }
 
 APointLight::APointLight() {
-	AddAttr( attr_float, "Constant Attenuation", 0, 0xFFFFFFFF );
+	/*AddAttr( attr_float, "Constant Attenuation", 0, 0xFFFFFFFF );
 	AddAttr( attr_float, "Linear Attenuation", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Quadratic Attenuation", 0, 0xFFFFFFFF );
+	AddAttr( attr_float, "Quadratic Attenuation", 0, 0xFFFFFFFF );*/
 	Init();
 }
 
@@ -159,7 +159,7 @@ AProperty::AProperty() {
 }
 
 APSysEmitter::APSysEmitter() {
-	AddAttr( attr_float, "Speed", 0, 0xFFFFFFFF );
+	/*AddAttr( attr_float, "Speed", 0, 0xFFFFFFFF );
 	AddAttr( attr_float, "Speed Variation", 0, 0xFFFFFFFF );
 	AddAttr( attr_float, "Declination", 0, 0xFFFFFFFF );
 	AddAttr( attr_float, "Declination Variation", 0, 0xFFFFFFFF );
@@ -169,27 +169,27 @@ APSysEmitter::APSysEmitter() {
 	AddAttr( attr_float, "Initial Radius", 0, 0xFFFFFFFF );
 	AddAttr( attr_float, "Radius Variation", 0, 0xFFFFFFFF );
 	AddAttr( attr_float, "Life Span", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Life Span Variation", 0, 0xFFFFFFFF );
+	AddAttr( attr_float, "Life Span Variation", 0, 0xFFFFFFFF );*/
 	Init();
 }
 
 APSysModifier::APSysModifier() {
-	AddAttr( attr_string, "Name", 0, 0xFFFFFFFF );
+	/*AddAttr( attr_string, "Name", 0, 0xFFFFFFFF );
 	AddAttr( attr_int, "Order", 0, 0xFFFFFFFF );
 	AddAttr( attr_controllertarget, "Target", 0, 0xFFFFFFFF );
-	AddAttr( attr_bool, "Active", 0, 0xFFFFFFFF );
+	AddAttr( attr_bool, "Active", 0, 0xFFFFFFFF );*/
 	Init();
 }
 
 APSysVolumeEmitter::APSysVolumeEmitter() {
-	AddAttr( attr_emitterobject, "Emitter Object", 335544324, 0xFFFFFFFF );
+	/*AddAttr( attr_emitterobject, "Emitter Object", 335544324, 0xFFFFFFFF );*/
 	Init();
 }
 
 AShape::AShape() {
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Skin Instance", 0, 0xFFFFFFFF );
-	AddAttr( attr_shader, "Shader", 167772416, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Skin Instance", 0, 0xFFFFFFFF );
+	//AddAttr( attr_shader, "Shader", 167772416, 0xFFFFFFFF );
 	Init();
 }
 
@@ -202,10 +202,10 @@ FxButton::FxButton() {
 }
 
 FxRadioButton::FxRadioButton() {
-	AddAttr( attr_int, "Unknown Int 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int  2", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 3", 0, 0xFFFFFFFF );
-	AddAttr( attr_linkgroup, "Unknown Links", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int  2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_linkgroup, "Unknown Links", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -214,13 +214,13 @@ FxWidget::FxWidget() {
 }
 
 NiAlphaController::NiAlphaController() {
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiAlphaProperty::NiAlphaProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Threshold", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Threshold", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -233,13 +233,13 @@ NiAutoNormalParticles::NiAutoNormalParticles() {
 }
 
 NiBillboardNode::NiBillboardNode() {
-	AddAttr( attr_short, "Billboard Mode", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Billboard Mode", 167837696, 0xFFFFFFFF );
 	Init();
 }
 
 NiBoolInterpolator::NiBoolInterpolator() {
-	AddAttr( attr_bool, "Bool Value", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Bool Value", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -256,73 +256,73 @@ NiBSParticleNode::NiBSParticleNode() {
 }
 
 NiBSplineCompFloatInterpolator::NiBSplineCompFloatInterpolator() {
-	AddAttr( attr_float, "Unknown Floats[0]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[1]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[2]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[3]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[4]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[5]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[6]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[7]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[0]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[1]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[2]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[3]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[4]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[5]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[6]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[7]", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiBSplineCompPoint3Interpolator::NiBSplineCompPoint3Interpolator() {
-	AddAttr( attr_int, "Unknown 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[0]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[1]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[2]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[3]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[4]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Floats[5]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[0]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[1]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[2]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[3]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[4]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Floats[5]", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiBSplineCompTransformInterpolator::NiBSplineCompTransformInterpolator() {
-	AddAttr( attr_float, "Unknown1[0]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown1[1]", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Basis Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[0]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[1]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[2]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[3]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[4]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[5]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[6]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[7]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[8]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[9]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[10]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[11]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[12]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[13]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[14]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[15]", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown4[16]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown1[0]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown1[1]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Basis Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[0]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[1]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[2]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[3]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[4]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[5]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[6]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[7]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[8]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[9]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[10]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[11]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[12]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[13]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[14]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[15]", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown4[16]", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiCamera::NiCamera() {
-	AddAttr( attr_short, "Unknown Short", 167837696, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frustum Left", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frustum Right", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frustum Top", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frustum Bottom", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frustum Near", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Frustum Far", 0, 0xFFFFFFFF );
-	AddAttr( attr_bool, "Use Orthographic Projection", 167837696, 0xFFFFFFFF );
-	AddAttr( attr_float, "Viewport Left", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Viewport Right", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Viewport Top", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Viewport Bottom", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "LOD Adjust", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link?", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 2", 67240192, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frustum Left", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frustum Right", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frustum Top", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frustum Bottom", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frustum Near", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Frustum Far", 0, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Use Orthographic Projection", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Viewport Left", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Viewport Right", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Viewport Top", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Viewport Bottom", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "LOD Adjust", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 2", 67240192, 0xFFFFFFFF );
 	Init();
 }
 
@@ -331,120 +331,120 @@ NiDirectionalLight::NiDirectionalLight() {
 }
 
 NiDitherProperty::NiDitherProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiFlipController::NiFlipController() {
-	AddAttr( attr_int, "Texture Slot", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 2", 0, 0x0A010000 );
-	AddAttr( attr_float, "Delta", 0, 0x0A010000 );
-	AddAttr( attr_linkgroup, "Sources", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Texture Slot", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 2", 0, 0x0A010000 );
+	//AddAttr( attr_float, "Delta", 0, 0x0A010000 );
+	//AddAttr( attr_linkgroup, "Sources", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiFloatExtraDataController::NiFloatExtraDataController() {
-	AddAttr( attr_link, "Unknown Link", 335544324, 0xFFFFFFFF );
-	AddAttr( attr_string, "Unknown String", 335544324, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link", 335544324, 0xFFFFFFFF );
+	//AddAttr( attr_string, "Unknown String", 335544324, 0xFFFFFFFF );
 	Init();
 }
 
 NiFloatInterpolator::NiFloatInterpolator() {
-	AddAttr( attr_float, "Float Value", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Float Value", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiFogProperty::NiFogProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Fog Depth", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Fog Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Fog Depth", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Fog Color", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiGeomMorpherController::NiGeomMorpherController() {
-	AddAttr( attr_short, "Unknown", 167837696, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiGravity::NiGravity() {
-	AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Force", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Type", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Position", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Direction", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Force", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Type", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Position", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Direction", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiKeyframeController::NiKeyframeController() {
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiLightColorController::NiLightColorController() {
-	AddAttr( attr_short, "Unknown Short", 167837696, 167837696 );
-	AddAttr( attr_link, "Data", 0, 167837696 );
-	AddAttr( attr_link, "Interpolator", 167903232, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short", 167903232, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 167837696, 167837696 );
+	//AddAttr( attr_link, "Data", 0, 167837696 );
+	//AddAttr( attr_link, "Interpolator", 167903232, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 167903232, 0xFFFFFFFF );
 	Init();
 }
 
 NiLightDimmerController::NiLightDimmerController() {
-	AddAttr( attr_link, "Unknown Link", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiLODNode::NiLODNode() {
-	AddAttr( attr_lodinfo, "LOD Info", 0, 0xFFFFFFFF );
+	//AddAttr( attr_lodinfo, "LOD Info", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiLookAtController::NiLookAtController() {
-	AddAttr( attr_short, "Unknown1", 167837696, 0xFFFFFFFF );
-	AddAttr( attr_link, "Look At Node", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown1", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Look At Node", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiLookAtInterpolator::NiLookAtInterpolator() {
-	AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Look At", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Translation", 0, 0xFFFFFFFF );
-	AddAttr( attr_quaternion, "Rotation", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Scale", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Look At", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Translation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_quaternion, "Rotation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Scale", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link 3", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiMaterialColorController::NiMaterialColorController() {
-	AddAttr( attr_short, "Unknown", 167837696, 167837696 );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short", 167903232, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown", 167837696, 167837696 );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 167903232, 0xFFFFFFFF );
 	Init();
 }
 
 NiMaterialProperty::NiMaterialProperty() {
-	AddAttr( attr_flags, "Flags", 0, 167772416 );
-	AddAttr( attr_color3, "Ambient Color", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Diffuse Color", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Specular Color", 0, 0xFFFFFFFF );
-	AddAttr( attr_color3, "Emissive Color", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Glossiness", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Alpha", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 167772416 );
+	//AddAttr( attr_color3, "Ambient Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Diffuse Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Specular Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_color3, "Emissive Color", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Glossiness", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Alpha", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiMeshParticleSystem::NiMeshParticleSystem() {
-	AddAttr( attr_modifiergroup, "Modifiers", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_modifiergroup, "Modifiers", 167837696, 0xFFFFFFFF );
 	Init();
 }
 
 NiMultiTargetTransformController::NiMultiTargetTransformController() {
-	AddAttr( attr_targetgroup, "Targets", 0, 0xFFFFFFFF );
+	//AddAttr( attr_targetgroup, "Targets", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -453,29 +453,29 @@ NiNode::NiNode() {
 }
 
 NiParticleBomb::NiParticleBomb() {
-	AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 6", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 7", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 8", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 9", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 10", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 6", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 7", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 8", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 9", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 10", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiParticleColorModifier::NiParticleColorModifier() {
-	AddAttr( attr_link, "Color Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Color Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiParticleGrowFade::NiParticleGrowFade() {
-	AddAttr( attr_float, "Grow", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Fade", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Grow", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Fade", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -484,16 +484,16 @@ NiParticleMeshes::NiParticleMeshes() {
 }
 
 NiParticleMeshModifier::NiParticleMeshModifier() {
-	AddAttr( attr_linkgroup, "Particle Meshes", 0, 0xFFFFFFFF );
+	//AddAttr( attr_linkgroup, "Particle Meshes", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiParticleRotation::NiParticleRotation() {
-	AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -502,7 +502,7 @@ NiParticles::NiParticles() {
 }
 
 NiParticleSystem::NiParticleSystem() {
-	AddAttr( attr_modifiergroup, "Modifiers", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_modifiergroup, "Modifiers", 167837696, 0xFFFFFFFF );
 	Init();
 }
 
@@ -511,41 +511,41 @@ NiParticleSystemController::NiParticleSystemController() {
 }
 
 NiPathController::NiPathController() {
-	AddAttr( attr_short, "Unknown Short 2", 167837696, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown Int 3", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Pos Data", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Float Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short 2", 167837696, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown Int 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Pos Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Float Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPlanarCollider::NiPlanarCollider() {
-	AddAttr( attr_short, "Unknown Short", 167772416, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short 2", 67240448, 67240448 );
-	AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 6", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 7", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 8", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 9", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 10", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 11", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 12", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 13", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 14", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 15", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 16", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 167772416, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short 2", 67240448, 67240448 );
+	//AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 6", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 7", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 8", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 9", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 10", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 11", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 12", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 13", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 14", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 15", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 16", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPoint3Interpolator::NiPoint3Interpolator() {
-	AddAttr( attr_vector3, "Point 3 Value", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Point 3 Value", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -554,94 +554,94 @@ NiPointLight::NiPointLight() {
 }
 
 NiPSysAgeDeathModifier::NiPSysAgeDeathModifier() {
-	AddAttr( attr_bool, "Spawn on Death", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Spawn Modifier", 0, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Spawn on Death", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Spawn Modifier", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysBoundUpdateModifier::NiPSysBoundUpdateModifier() {
-	AddAttr( attr_short, "Update Skip", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Update Skip", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysBoxEmitter::NiPSysBoxEmitter() {
-	AddAttr( attr_float, "Width", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Height", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Depth", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Width", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Height", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Depth", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysColliderManager::NiPSysColliderManager() {
-	AddAttr( attr_link, "Collider", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Bounce", 0, 0xFFFFFFFF );
-	AddAttr( attr_bool, "Spawn on Collide", 0, 0xFFFFFFFF );
-	AddAttr( attr_bool, "Die on Collide", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Spawn Modifier", 0, 0xFFFFFFFF );
-	AddAttr( attr_selflink, "Manager", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Unknown Link?", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Collider Object", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Collider", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Bounce", 0, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Spawn on Collide", 0, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Die on Collide", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Spawn Modifier", 0, 0xFFFFFFFF );
+	//AddAttr( attr_selflink, "Manager", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Unknown Link?", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Collider Object", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysColorModifier::NiPSysColorModifier() {
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysCylinderEmitter::NiPSysCylinderEmitter() {
-	AddAttr( attr_float, "Radius", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Height", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Radius", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Height", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysEmitterCtlr::NiPSysEmitterCtlr() {
-	AddAttr( attr_link, "Interpolator", 167903232, 0xFFFFFFFF );
-	AddAttr( attr_string, "Unknown String", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Interpolator", 167903232, 0xFFFFFFFF );
+	//AddAttr( attr_string, "Unknown String", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysEmitterDeclinationVarCtlr::NiPSysEmitterDeclinationVarCtlr() {
-	AddAttr( attr_link, "Interpolator", 0, 0xFFFFFFFF );
-	AddAttr( attr_string, "Unknown String", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Interpolator", 0, 0xFFFFFFFF );
+	//AddAttr( attr_string, "Unknown String", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysEmitterInitialRadiusCtlr::NiPSysEmitterInitialRadiusCtlr() {
-	AddAttr( attr_link, "Interpolator", 0, 0xFFFFFFFF );
-	AddAttr( attr_string, "Unknown String", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Interpolator", 0, 0xFFFFFFFF );
+	//AddAttr( attr_string, "Unknown String", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysGravityModifier::NiPSysGravityModifier() {
-	AddAttr( attr_crossref, "Gravity Object", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Gravity Axis", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Decay", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Strength", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Turbulence", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Turbulence Scale", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Force Type", 0, 0xFFFFFFFF );
+	//AddAttr( attr_crossref, "Gravity Object", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Gravity Axis", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Decay", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Strength", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Turbulence", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Turbulence Scale", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Force Type", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysGrowFadeModifier::NiPSysGrowFadeModifier() {
-	AddAttr( attr_float, "Grow Time", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Grow Generation", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Fade Time", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Fade Generation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Grow Time", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Grow Generation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Fade Time", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Fade Generation", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysMeshUpdateModifier::NiPSysMeshUpdateModifier() {
-	AddAttr( attr_linkgroup, "Meshes", 0, 0xFFFFFFFF );
+	//AddAttr( attr_linkgroup, "Meshes", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysPlanarCollider::NiPSysPlanarCollider() {
-	AddAttr( attr_float, "Width", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Height", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "X Axis", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Y Axis", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Width", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Height", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "X Axis", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Y Axis", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -654,30 +654,30 @@ NiPSysResetOnLoopCtlr::NiPSysResetOnLoopCtlr() {
 }
 
 NiPSysRotationModifier::NiPSysRotationModifier() {
-	AddAttr( attr_float, "Initial Rotation Speed", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Initial Rotation Speed Variation", 335544324, 0xFFFFFFFF );
-	AddAttr( attr_float, "Initial Rotation Angle", 335544324, 0xFFFFFFFF );
-	AddAttr( attr_float, "Initial Rotation Angle Variation", 335544324, 0xFFFFFFFF );
-	AddAttr( attr_bool, "Random Rot Speed Sign", 335544324, 0xFFFFFFFF );
-	AddAttr( attr_bool, "Random Initial Axis", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Initial Axis", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Initial Rotation Speed", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Initial Rotation Speed Variation", 335544324, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Initial Rotation Angle", 335544324, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Initial Rotation Angle Variation", 335544324, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Random Rot Speed Sign", 335544324, 0xFFFFFFFF );
+	//AddAttr( attr_bool, "Random Initial Axis", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Initial Axis", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysSpawnModifier::NiPSysSpawnModifier() {
-	AddAttr( attr_short, "Num Spawn Generations", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Percentage Spawned", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Min Num to Spawn", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Max Num to Spawn", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Spawn Speed Chaos", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Spawn Dir Chaos", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Life Span", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Life Span Variation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Num Spawn Generations", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Percentage Spawned", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Min Num to Spawn", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Max Num to Spawn", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Spawn Speed Chaos", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Spawn Dir Chaos", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Life Span", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Life Span Variation", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiPSysSphereEmitter::NiPSysSphereEmitter() {
-	AddAttr( attr_float, "Radius", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Radius", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -694,89 +694,89 @@ NiSequenceStreamHelper::NiSequenceStreamHelper() {
 }
 
 NiShadeProperty::NiShadeProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiSourceTexture::NiSourceTexture() {
-	AddAttr( attr_texsource, "Texture Source", 0, 0xFFFFFFFF );
-	AddAttr( attr_pixellayout, "Pixel Layout", 0, 0xFFFFFFFF );
-	AddAttr( attr_mipmapformat, "Use Mipmaps", 0, 0xFFFFFFFF );
-	AddAttr( attr_alphaformat, "Alpha Format", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Unknown Byte 2", 167903232, 0xFFFFFFFF );
+	//AddAttr( attr_texsource, "Texture Source", 0, 0xFFFFFFFF );
+	//AddAttr( attr_pixellayout, "Pixel Layout", 0, 0xFFFFFFFF );
+	//AddAttr( attr_mipmapformat, "Use Mipmaps", 0, 0xFFFFFFFF );
+	//AddAttr( attr_alphaformat, "Alpha Format", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown Byte", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown Byte 2", 167903232, 0xFFFFFFFF );
 	Init();
 }
 
 NiSpecularProperty::NiSpecularProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiSphericalCollider::NiSphericalCollider() {
-	AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 4", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float 5", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiSpotLight::NiSpotLight() {
-	AddAttr( attr_float, "Cutoff Angle", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Exponent", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Cutoff Angle", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Exponent", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiStencilProperty::NiStencilProperty() {
-	AddAttr( attr_flags, "Flags", 0, 167772416 );
-	AddAttr( attr_bool, "Stencil Enabled", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Stencil Function", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Stencil Ref", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Stencil Mask", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Fail Action", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Z Fail Action", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Pass Action", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Draw Mode", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 167772416 );
+	//AddAttr( attr_bool, "Stencil Enabled", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Stencil Function", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Stencil Ref", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Stencil Mask", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Fail Action", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Z Fail Action", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Pass Action", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Draw Mode", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiTextureEffect::NiTextureEffect() {
-	AddAttr( attr_matrix33, "Model Projection Matrix", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Model Projection Transform", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Texture Filtering", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Texture Clamping", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Texture Type", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Coordinate Generation Type", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Source Texture", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Clipping Plane", 0, 0xFFFFFFFF );
-	AddAttr( attr_vector3, "Unknown Vector", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Unknown Float", 0, 0xFFFFFFFF );
-	AddAttr( attr_short, "PS2 L", 0, 167903232 );
-	AddAttr( attr_short, "PS2 K", 0, 167903232 );
-	AddAttr( attr_short, "Unknown Short", 0, 67174412 );
+	//AddAttr( attr_matrix33, "Model Projection Matrix", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Model Projection Transform", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Texture Filtering", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Texture Clamping", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Texture Type", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Coordinate Generation Type", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Source Texture", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Clipping Plane", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Unknown Vector", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Unknown Float", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "PS2 L", 0, 167903232 );
+	//AddAttr( attr_short, "PS2 K", 0, 167903232 );
+	//AddAttr( attr_short, "Unknown Short", 0, 67174412 );
 	Init();
 }
 
 NiTextureTransformController::NiTextureTransformController() {
-	AddAttr( attr_int, "Unknown1", 0, 0xFFFFFFFF );
-	AddAttr( attr_byte, "Unknown2", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown3", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Unknown4", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown1", 0, 0xFFFFFFFF );
+	//AddAttr( attr_byte, "Unknown2", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown3", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Unknown4", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiTransformController::NiTransformController() {
-	AddAttr( attr_link, "Interpolator", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Interpolator", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiTransformInterpolator::NiTransformInterpolator() {
-	AddAttr( attr_vector3, "Translation", 0, 0xFFFFFFFF );
-	AddAttr( attr_quaternion, "Rotation", 0, 0xFFFFFFFF );
-	AddAttr( attr_float, "Scale", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vector3, "Translation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_quaternion, "Rotation", 0, 0xFFFFFFFF );
+	//AddAttr( attr_float, "Scale", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
@@ -789,31 +789,31 @@ NiTriStrips::NiTriStrips() {
 }
 
 NiUVController::NiUVController() {
-	AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_short, "Unknown Short", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiVertexColorProperty::NiVertexColorProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
-	AddAttr( attr_vertmode, "Vertex Mode", 0, 0xFFFFFFFF );
-	AddAttr( attr_lightmode, "Lighting Mode", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_vertmode, "Vertex Mode", 0, 0xFFFFFFFF );
+	//AddAttr( attr_lightmode, "Lighting Mode", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiVisController::NiVisController() {
-	AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
+	//AddAttr( attr_link, "Data", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiWireframeProperty::NiWireframeProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
 	Init();
 }
 
 NiZBufferProperty::NiZBufferProperty() {
-	AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
-	AddAttr( attr_int, "Function", 67174412, 0xFFFFFFFF );
+	//AddAttr( attr_flags, "Flags", 0, 0xFFFFFFFF );
+	//AddAttr( attr_int, "Function", 67174412, 0xFFFFFFFF );
 	Init();
 }
 
diff --git a/nif_attrs.h b/nif_attrs.h
index c45f7b5f7864a1a094e1027c7e1550ec4ccc38ae..f37033a5315def0f84f32c9a808e5ac8c4858458 100644
--- a/nif_attrs.h
+++ b/nif_attrs.h
@@ -36,399 +36,291 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 #include <sstream>
 #include <list>
-#include "niflib.h"
-#include "NIF_Blocks.h"
-#include "NIF_IO.h"
+#include "niflib_internal.h"
 
 #define endl "\r\n"
 
-const char ATTRERR[] = "Attribute type Missmatch.";
-
-class AAttr : public IAttr {
-public:
-	AAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : _name(name), _owner(owner), _first_ver(first_ver), _last_ver(last_ver) {}
-	~AAttr() {} //cout << "   Attribute \"" << _name << "\" deleted" << endl; }
-	string GetName() const { return _name; }
-	//Getters
-	int asInt() const { throw runtime_error(ATTRERR); }
-	float asFloat() const { throw runtime_error(ATTRERR); }
-	Float3 asFloat3() const { throw runtime_error(ATTRERR); }
-	Float4 asFloat4() const { throw runtime_error(ATTRERR); }
-	Matrix33 asMatrix33() const { throw runtime_error(ATTRERR); }
-	blk_ref asLink() const { throw runtime_error(ATTRERR); }
-	TexSource asTexSource() const { throw runtime_error(ATTRERR); }
-	BoundingBox asBoundingBox() const { throw runtime_error(ATTRERR); }
-	ConditionalInt asConditionalInt() const { throw runtime_error(ATTRERR); }
-	TexDesc asTexDesc() const { throw runtime_error(ATTRERR); }
-	list<blk_ref> asLinkList() const { throw runtime_error(ATTRERR); }
-	//Setters
-	void Set(int) { throw runtime_error(ATTRERR); }
-	void Set(float) { throw runtime_error(ATTRERR); }
-	void Set(Float3 const &) { throw runtime_error(ATTRERR); }
-	void Set(Float4 const &) { throw runtime_error(ATTRERR); }
-	void Set(string const &) { throw runtime_error(ATTRERR); }
-	void Set(Matrix33 const &) { throw runtime_error(ATTRERR); }
-	void Set(blk_ref const &) { throw runtime_error(ATTRERR); }
-	void Set(TexSource const &) { throw runtime_error(ATTRERR); }
-	void Set(BoundingBox const &) { throw runtime_error(ATTRERR); }
-	void Set(ConditionalInt const &) { throw runtime_error(ATTRERR); }
-	void Set(TexDesc const &) { throw runtime_error(ATTRERR); }
-	//Link functions
-	bool HasLinks() const { return false; }
-	void AddLink( blk_ref const & block ) { cout << "AddLink" << endl; throw runtime_error(ATTRERR); }
-	void AddLinks( list<blk_ref> const & new_links ) { cout << "AddLinkS" << endl; throw runtime_error(ATTRERR); }
-	void ClearLinks() { cout << "ClearLinks" << endl; throw runtime_error(ATTRERR); }
-	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( istream& in, unsigned int version ) {
-		if ( version >= _first_ver && version <= _last_ver ) {
-			this->ReadAttr( in, version );
-		}
-	}
-	void Write( ostream& out, unsigned int version ) const {
-		if ( version >= _first_ver && version <= _last_ver ) {
-			this->WriteAttr( out, version );
-		}
-	}
-	//Function to remove CrossLinks without decrimenting them
-	virtual void RemoveCrossLinks( IBlock * block_to_remove ) {};
-protected:
-	//Internal Read/Write Functions
-	virtual void ReadAttr( istream& in, unsigned int version ) = 0;
-	virtual void WriteAttr( ostream& out, unsigned int version ) const = 0;
-
-	string _name;
-	IBlock * _owner;
-	unsigned int _first_ver, _last_ver;
-};
-
-class lnk_ref : public blk_ref {
+class IntAttr : public AAttr {
 public:
-	lnk_ref ( IBlock * owner) : _owner(owner) { InitLink(); }
-	lnk_ref( IBlock * owner, int index ) : blk_ref(index), _owner(owner) { InitLink(); }
-	lnk_ref( IBlock * owner, blk_ref block ) : blk_ref(block), _owner(owner) { InitLink(); }
-
-	//Copy Constructors
-	lnk_ref( const lnk_ref & rh ) {
-		/*cout << "Copy constructor " << endl;*/
-		//Kill previous link
-		KillLink();
-		_owner = rh._owner;
-		blk_ref::operator=(rh);
-		//Set New Link
-		InitLink();
-	}
-	//Destructor
-	~lnk_ref() { KillLink(); }
-	//Assignment Operator
-	lnk_ref & operator=(const blk_ref & rh ) { 
-		if ( blk_ref(*this)!= rh ) {
-			//Kill previous link
-			KillLink();
-			blk_ref::operator=(rh);
-			//Set New Link
-			InitLink();
-		}
+	IntAttr( string const & name, IBlock * owner, int * data ) : AAttr( name, owner ), _data(data) {}
+	~IntAttr() {}
+	AttrType GetType() const { return attr_int; }
+	string asString() const {
+		stringstream out;
+		out.setf(ios::fixed, ios::floatfield);
+		out << setprecision(1);
 
-		return *this;
-	}
-	void set_block( IBlock * block ) {
-		/*cout << "set_block " << endl;*/
-		//Use assignment operator code
-		operator=( blk_ref(block) );
-	}
-	void set_index( int index ) { 
-		/*cout << "set_index " << endl;*/
-		//Use assigntment operator code
-		operator=( blk_ref(index) );
-	}
-	IBlock * owner() const {
-		if ( _owner == NULL ) {
-			throw runtime_error("Link reference owner is NULL.");
-		} else {
-			return _owner;
-		}
-	}
+		out << *_data;
 
-private:
-	IBlock * _owner;
-	void InitLink() {
-		//cout << "+ Reference " << this << endl;
-		//Add parent at new link site
-		if ( _block != NULL ) {
-			//Get internal interface
-			((ABlock*)_block)->AddParent( _owner );
-			//IBlockInternal * bk_intl = (IBlockInternal*)_block->QueryInterface( BlockInternal );
-			//if ( bk_intl != NULL ) {
-			//	bk_intl->AddParent( _owner );
-			//}
-		}
-	}
-	void KillLink() {
-		//cout << "- Reference " << this << endl;
-		//Remove cross-reference at previous location
-		if ( _block != NULL ) {
-			((ABlock*)_block)->RemoveParent( _owner );
-			//Get internal interface
-			//IBlockInternal * bk_intl = (IBlockInternal*)_block->QueryInterface( BlockInternal );
-			//if ( bk_intl != NULL ) {
-			//	bk_intl->RemoveParent( _owner );
-			//}
-		}
+		return out.str();
 	}
-	lnk_ref( const blk_ref & rh ); // Intentionally Undefined
+	int asInt() const { return *_data; }
+	void Set(int n ) { *_data = n; }
+protected:
+	int * _data;
 };
 
-class IntAttr : public AAttr {
+class UIntAttr : public AAttr {
 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() {}
+	UIntAttr( string const & name, IBlock * owner, uint * data ) : AAttr( name, owner ), _data(data) {}
+	~UIntAttr() {}
 	AttrType GetType() const { return attr_int; }
-	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);
 		out << setprecision(1);
 
-		out << data;
+		out << *_data;
 
 		return out.str();
 	}
-	int asInt() const { return data; }
-	void Set(int n ) { data = n; }
+	int asInt() const { return int(*_data); }
+	void Set(int n ) { *_data = uint(n); }
 protected:
-	int data;
+	uint * _data;
 };
 
 class ShortAttr : public AAttr {
 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( string const & name, IBlock * owner, short * data ) : AAttr( name, owner ), _data(data) {}
 	~ShortAttr() {}
 	AttrType GetType() const { return attr_short; }
-	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);
 		out << setprecision(1);
 
-		out << data;
+		out << *_data;
 
 		return out.str();
 	}
-	int asInt() const { return int(data); }
-	void Set(int n ) { data = short(n); }
-private:
-	short data;
+	int asInt() const { return int(*_data); }
+	void Set(int n ) { *_data = short(n); }
+protected:
+	short * _data;
 };
 
-class ByteAttr : public AAttr {
+class UShortAttr : public AAttr {
 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( istream& in, unsigned int version ) { data = ReadByte( in ); }
-	void WriteAttr( ostream& out, unsigned int version ) const { WriteByte( data, out ); }
+	UShortAttr( string const & name, IBlock * owner, ushort * data ) : AAttr( name, owner ), _data(data) {}
+	~UShortAttr() {}
+	AttrType GetType() const { return attr_short; }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << int(data);
+		out << *_data;
 
 		return out.str();
 	}
-	int asInt() const { return int(data); }
-	void Set(int n ) { data = char(n); }
-private:
-	char data;
+	int asInt() const { return int(*_data); }
+	void Set(int n ) { *_data = ushort(n); }
+protected:
+	ushort * _data;
 };
 
-class BoolAttr : public AAttr {
+class ByteAttr : public AAttr {
 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( istream& in, unsigned int version ) { data = ReadBool( in, version ); }
-	void WriteAttr( ostream& out, unsigned int version ) const { WriteBool( data, out, version ); }
+	ByteAttr( string const & name, IBlock * owner, byte * data ) : AAttr( name, owner ), _data(data) {}
+	~ByteAttr() {}
+	AttrType GetType() const { return attr_byte; }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << int(data);
+		out << int(*_data);
 
 		return out.str();
 	}
-	int asInt() const { return int(data); }
-	void Set(int n ) { data = (n != 0); }
-private:
-	bool data;
+	int asInt() const { return int(*_data); }
+	void Set(int n ) { *_data = byte(n); }
+protected:
+	byte * _data;
 };
 
 class FloatAttr : public AAttr {
 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( string const & name, IBlock * owner, float * data ) : AAttr( name, owner ), _data(data) {}
 	~FloatAttr() {}
 	AttrType GetType() const { return attr_float; }
-	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);
 		out << setprecision(1);
 
-		out << data;
+		out << *_data;
 
 		return out.str();
 	}
-	float asFloat() const { return data; }
-	void Set(float n ) { data = n; }
-private:
-	float data;
+	float asFloat() const { return *_data; }
+	void Set(float n ) { *_data = n; }
+protected:
+	float * _data;
 };
 
 class Float3Attr : public AAttr {
 public:
-	Float3Attr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : AAttr(name, owner, first_ver, last_ver) {
-		data[0] = 0.0f;
-		data[1] = 0.0f;
-		data[2] = 0.0f;
-	}
+	Float3Attr( string const & name, IBlock * owner, Float3 * data ) : AAttr( name, owner ), _data(data) {}
 	~Float3Attr() {}
 	AttrType GetType() const { return attr_float3; }
-	void ReadAttr( istream& in, unsigned int version ) { 
-		data[0] = ReadFloat( in );
-		data[1] = ReadFloat( in );
-		data[2] = ReadFloat( in );
-	}
-	void WriteAttr( ostream& out, unsigned int version ) const {
-		WriteFloat( data[0], out );
-		WriteFloat( data[1], out );
-		WriteFloat( data[2], out );
-	}
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << "(" << setw(5) << data[0] << ", " << setw(5) << data[1] << ", " << setw(5) << data[2] << " )";
-		
+		out << *_data;
+
 		return out.str();
 	}
-	Float3 asFloat3() const { return data; }
-	void Set(Float3 const & n) { data = n; }
-private:
-	Float3 data;
+	Float3 asFloat3() const { return *_data; }
+	void Set(Float3 const & n ) { *_data = n; }
+protected:
+	Float3 * _data;
 };
 
 class Float4Attr : public AAttr {
 public:
-	Float4Attr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : AAttr(name, owner, first_ver, last_ver) {
-		data[0] = 0.0f;
-		data[1] = 0.0f;
-		data[2] = 0.0f;
-		data[3] = 0.0f;
-	}
+	Float4Attr( string const & name, IBlock * owner, Float4 * data ) : AAttr( name, owner ), _data(data) {}
 	~Float4Attr() {}
 	AttrType GetType() const { return attr_float4; }
-	void ReadAttr( istream& in, unsigned int version ) { 
-		data[0] = ReadFloat( in );
-		data[1] = ReadFloat( in );
-		data[2] = ReadFloat( in );
-		data[3] = ReadFloat( in );
-	}
-	void WriteAttr( ostream& out, unsigned int version ) const {
-		WriteFloat( data[0], out );
-		WriteFloat( data[1], out );
-		WriteFloat( data[2], out );
-		WriteFloat( data[3], out );
-	}
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << "(" << setw(5) << data[0] << ", " << setw(5) << data[1] << ", " << setw(5) << data[2] << ", " << setw(5) << data[3] << " )";
-		
+		out << *_data;
+
 		return out.str();
 	}
-	Float4 asFloat4() const { return data; }
-	void Set(Float4 const & n) { data = n; }
-private:
-	Float4 data;
+	Float4 asFloat4() const { return *_data; }
+	void Set(Float4 const & n ) { *_data = n; }
+protected:
+	Float4 * _data;
 };
 
-class Vector3Attr : public Float3Attr {
+class Vector3Attr : public AAttr {
 public:
-	Vector3Attr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float3Attr(name, owner, first_ver, last_ver) {}
+	Vector3Attr( string const & name, IBlock * owner, Vector3 * data ) : AAttr( name, owner ), _data(data) {}
 	~Vector3Attr() {}
 	AttrType GetType() const { return attr_vector3; }
-};
+	string asString() const {
+		stringstream out;
+		out.setf(ios::fixed, ios::floatfield);
+		out << setprecision(1);
 
-class Color3Attr : public Float3Attr {
-public:
-	Color3Attr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float3Attr(name, owner, first_ver, last_ver) {}
-	~Color3Attr() {}
-	AttrType GetType() const { return attr_color3; }
-};
+		out << *_data;
 
-class Color4Attr : public Float4Attr {
-public:
-	Color4Attr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float4Attr(name, owner, first_ver, last_ver) {}
-	~Color4Attr() {}
-	AttrType GetType() const { return attr_color4; }
+		return out.str();
+	}
+	Float3 asFloat3() const { return Float3(_data->x, _data->y, _data->z); }
+	void Set(Float3 const & n ) { 
+		_data->x = n.data[0];
+		_data->y = n.data[1];
+		_data->z = n.data[2];
+	}
+protected:
+	Vector3 * _data;
 };
 
-class QuaternionAttr : public Float4Attr {
+//class Color3Attr : public AAttr {
+//public:
+//	Color3Attr( string const & name, IBlock * owner, Color3 * data ) : AAttr( name, owner ), _data(data) {}
+//	~Color3Attr() {}
+//	AttrType GetType() const { return attr_color3; }
+//	string asString() const {
+//		stringstream out;
+//		out.setf(ios::fixed, ios::floatfield);
+//		out << setprecision(1);
+//
+//		out << *data;
+//
+//		return out.str();
+//	}
+//	Float3 asFloat3() const { return Float3(_data->r, _data->g, _data->b); }
+//	void Set(Float3 const & n ) { 
+//		_data->r = n.data[0];
+//		_data->g = n.data[1];
+//		_data->b = n.data[2];
+//	}
+//protected:
+//	Color3 * _data;
+//};
+
+//class Color4Attr : public AAttr {
+//public:
+//	Color4Attr( string const & name, IBlock * owner, Color4 * data ) : AAttr( name, owner ), _data(data) {}
+//	~Color4Attr() {}
+//	AttrType GetType() const { return attr_color4; }
+//	string asString() const {
+//		stringstream out;
+//		out.setf(ios::fixed, ios::floatfield);
+//		out << setprecision(1);
+//
+//		out << *data;
+//
+//		return out.str();
+//	}
+//	Float3 asFloat4() const { return Float3(_data->r, _data->g, _data->b, _data->a); }
+//	void Set(Float4 const & n ) { 
+//		_data->r = n.data[0];
+//		_data->g = n.data[1];
+//		_data->b = n.data[2];
+//		_data->a = n.data[2];
+//	}
+//protected:
+//	Color4 * _data;
+//};
+
+class QuaternionAttr : public AAttr {
 public:
-	QuaternionAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float4Attr(name, owner, first_ver, last_ver) {}
+	QuaternionAttr( string const & name, IBlock * owner, Quaternion * data ) : AAttr( name, owner ), _data(data) {}
 	~QuaternionAttr() {}
 	AttrType GetType() const { return attr_quaternion; }
+	string asString() const {
+		stringstream out;
+		out.setf(ios::fixed, ios::floatfield);
+		out << setprecision(1);
+
+		out << *_data;
+
+		return out.str();
+	}
+	Float4 asFloat4() const { return Float4(_data->w, _data->x, _data->y, _data->z); }
+	void Set(Float4 const & n ) { 
+		_data->w = n.data[0];
+		_data->x = n.data[1];
+		_data->y = n.data[2];
+		_data->z = n.data[2];
+	}
+protected:
+	Quaternion * _data;
 };
 
 class StringAttr : public AAttr {
 public:
-	StringAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
+	StringAttr( string const & name, IBlock * owner, string * data ) : AAttr( name, owner ), _data(data) {}
 	~StringAttr() {}
 	AttrType GetType() const { return attr_string; }
-	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; }
+	string asString() const { return *_data; }
+	void Set(string const & n) { *_data = n; }
 private:
-	string data;
+	string * _data;
 };
 
 class LinkAttr : public AAttr {
 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( string const & name, IBlock * owner, Link * data ) : AAttr( name, owner ), _data(data) {}
 	~LinkAttr() {}
 	AttrType GetType() const { return attr_link; }
-	void ReadAttr( istream& in, unsigned int version ) {
-		////Remove all links beloning to this attribute
-		//_owner->RemoveAttrLinks(this);
-
-		////Add a new link with read in link
-		//blk_link l;
-		//l.attr = this;
-		//l.block = ReadUInt( in );
-		//_owner->AddLink(l);
-
-		//Set block index only
-		link.set_index( ReadUInt( in ) );
-	}
-	void WriteAttr( ostream& out, unsigned int version ) const {
-		WriteUInt( link.get_index(), out );
-	}
+	
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << link;
+		out << *_data;
 
 		return out.str();
 	}
@@ -436,56 +328,36 @@ public:
 	list<blk_ref> asLinkList() const { 
 		list<blk_ref> out;
 
-		out.push_back( blk_ref(link) );
+		out.push_back( _data->GetLink() );
 
 		return out; 
 	}
-	void ClearLinks() { link = blk_ref(-1); }
+	void ClearLinks() { _data->Nullify(); }
 	void AddLinks( list<blk_ref> const & new_links ) {
 		//Just take the first one
-		link = *(new_links.begin());
+		_data->SetLink( *(new_links.begin()) );
 	}
 
-	blk_ref asLink() const { return blk_ref(link); }
-	void Set( blk_ref const & n ) { link = n; }
+	blk_ref asLink() const { return _data->GetLink(); }
+	void Set( blk_ref const & n ) { _data->SetLink(n); }
 private:
-	lnk_ref link;
+	Link * _data;
 };
 
 class CrossRefAttr : public AAttr {
 public:
-	CrossRefAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), tmp_blk_num(-1), link(NULL) {}
-	~CrossRefAttr() {
-		//cout << endl << "~CrossRefAttr()";
-		//This attribute is dying, so decrement the link
-		UpdateLink(NULL);
-	}
-	AttrType GetType() const { 
-		//cout << endl << "CrossRefAttr::GetType()";
+	CrossRefAttr( string const & name, IBlock * owner, CrossRef * data ) : AAttr( name, owner ), _data(data) {}
+	~CrossRefAttr() {}
+	AttrType GetType() const {
 		return attr_link;
 	}
-	void ReadAttr( istream& in, unsigned int version ) {
-		//cout << endl << "CrossRefAttr::ReadAttr()";
-		//Update any existing links to null
-		UpdateLink(NULL);
-
-		tmp_blk_num = ReadUInt( in );
-	}
-	void WriteAttr( ostream& out, unsigned int version ) const {
-		//cout << endl << "CrossRefAttr::WriteAttr()";
-		if ( link == NULL ) {
-			WriteUInt( 0xFFFFFFFF, out );
-		} else {
-			WriteUInt( link->GetBlockNum(), out );
-		}
-	}
 	string asString() const {
 		//cout << endl << "CrossRefAttr::asString()";
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << GetBlkRef();
+		out << *_data;
 
 		return out.str();
 	}
@@ -497,85 +369,32 @@ public:
 		//cout << endl << "CrossRefAttr::asLinkList()";
 		list<blk_ref> out;
 
-		out.push_back( GetBlkRef() );
+		out.push_back( blk_ref(_data->GetCrossRef()) );
 
 		return out; 
 	}
 	void ClearLinks() { 
 		//cout << endl << "CrossRefAttr::ClearLinks()";
-		UpdateLink( NULL );
+		_data->Nullify();
 	}
 	void AddLinks( list<blk_ref> const & new_links ) {
 		//cout << endl << "CrossRefAttr::AddLinks()";
 		//Just take the first one
-		UpdateLink( (*(new_links.begin())).get_block() );
-	}
-
-	void UpdateLink( IBlock * new_ptr ) {
-		//cout << endl << "CrossRefAttr::UpdateLink()";
-		//cout << endl << "Setting tmp_blk_num to -1";
-		//The link cannot be temporary after being updated
-		tmp_blk_num = -1;
-
-		/*cout << endl << "Check if new pointer is same as old"
-			<< endl << "Old Value:  " << link
-			<< endl << "New Value:  " << new_ptr;*/
-		//Check if the new pointer is the same as the old pointer
-		if ( new_ptr == link )
-			return;
-
-		//cout << endl << "If different, decrement ref to old site if it exists.";
-		//The new pointer is different, so decrement the reference at the old site if it exists
-		if ( link != NULL ) {
-			//cout << endl << "Decrimenting Cross Reference at:  " << link;
-			((ABlock*)link)->DecCrossRef( _owner );
-		}
-
-		//Now set the pointer to the new location
-		link = new_ptr;
-
-		//If link is not null, we need to increment the cross reference count
-		if ( link != NULL ) {
-			//cout << endl << "Incrementing Cross Reference at:  " << link;
-			((ABlock*)link)->IncCrossRef( _owner );
-		}
+		_data->SetCrossRef( new_links.begin()->get_block() );
 	}
 
-	blk_ref GetBlkRef() const {
-		//cout << endl << "CrossRefAttr::GetBlkRef()";
-		//If the link is not fixed, there will be a temporary block number
-		if ( tmp_blk_num != -1 ) {
-			return blk_ref(tmp_blk_num);
-		} else {
-			if ( link == NULL ) {
-				return blk_ref(-1);
-			} else {
-				return blk_ref(link);
-			}
-		}
-	}
-
-	blk_ref asLink() const { return GetBlkRef(); }
+	blk_ref asLink() const { return blk_ref(_data->GetCrossRef()); }
 	void Set( blk_ref const & n ) { 
-		//cout << endl << "CrossRefAttr::Set()";
-		UpdateLink( n.get_block() );
-	}
-	void RemoveCrossLinks( IBlock * block_to_remove ) {
-		//cout << endl << "CrossRefAttr::RemoveCrossLinks()";
-		if ( link == block_to_remove ) {
-			link = NULL;
-			//Do not decrement target location because it is already dead
-		}
+		_data->SetCrossRef( n.get_block() );
 	}
 private:
-	int tmp_blk_num;
-	IBlock * link;
+	CrossRef * _data;
 };
 
 
 class FlagsAttr : public AAttr {
 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( string const & name, IBlock * owner ) : AAttr( name, owner ), data(0) {}
 	~FlagsAttr() {}
 	AttrType GetType() const { return attr_flags; }
 	void ReadAttr( istream& in, unsigned int version ) { data = ReadUShort( in ); }
@@ -602,79 +421,34 @@ private:
 	short data;
 };
 
-class MatrixAttr : public AAttr {
+class Matrix33Attr : public AAttr {
 public:
-	MatrixAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
-		data[0][0] = 1.0f;	data[0][1] = 0.0f;	data[0][2] = 0.0f;
-		data[1][0] = 0.0f;	data[1][1] = 1.0f;	data[1][2] = 0.0f;
-		data[2][0] = 0.0f;	data[2][1] = 0.0f;	data[2][2] = 1.0f;
-	}
-	~MatrixAttr() {}
+	Matrix33Attr( string const & name, IBlock * owner, Matrix33 * data ) : AAttr( name, owner ), _data(data) {}
+	~Matrix33Attr() {}
 	AttrType GetType() const { return attr_matrix33; }
-	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( 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 );
-			}
-		}
-	}
+	
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		out << endl
-			<< "   |" << setw(6) << data[0][0] << "," << setw(6) << data[0][1] << "," << setw(6) << data[0][2] << " |" << endl
-			<< "   |" << setw(6) << data[1][0] << "," << setw(6) << data[1][1] << "," << setw(6) << data[1][2] << " |" << endl
-			<< "   |" << setw(6) << data[2][0] << "," << setw(6) << data[2][1] << "," << setw(6) << data[2][2] << " |";
-		
+		out << *_data << endl;
+
 		return out.str();
 	}
 	Matrix33 asMatrix33() const {
-		return data;
-		//for (int c = 0; c < 3; ++c) {
-		//	for (int r = 0; r < 3; ++r) {
-		//		out[r][c] = data[r][c];
-		//	}
-		//}
+		return *_data;
 	}
 	void Set( Matrix33 const & n ) {
-		for (int c = 0; c < 3; ++c) {
-			for (int r = 0; r < 3; ++r) {
-				data[r][c] = n[r][c];
-			}
-		}
+		*_data = n;
 	}
-
-	//vector<float> asFloatList() const {
-	//	vector<float> list(9);
-	//	list[0] = data[0][0];	list[1] = data[0][1];	list[2] = data[0][2];
-	//	list[0] = data[1][0];	list[1] = data[1][1];	list[2] = data[1][2];
-	//	list[0] = data[2][0];	list[1] = data[2][1];	list[2] = data[2][2];
-	//	return list;
-	//}
-	//void Set(vector<float> n ) {
-	//	if ( n.size() != 9)
-	//		throw runtime_error("List size must equal 9");
-
-	//	data[0][0] = n[0];	data[0][1] = n[1];	data[0][2] = n[2];
-	//	data[1][0] = n[0];	data[1][1] = n[1];	data[1][2] = n[2];
-	//	data[2][0] = n[0];	data[2][1] = n[1];	data[2][2] = n[2];
-	//}
 private:
-	Matrix33 data;
+	Matrix33 * _data;
 };
-
+/*
 class BoneAttr : public AAttr {
 public:
-	BoneAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	BoneAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~BoneAttr() {}
 	AttrType GetType() const { return attr_bones; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -732,53 +506,22 @@ public:
 		return out.str();
 	}
 };
-
-typedef list<lnk_ref> LinkSetList;
-typedef LinkSetList::iterator LinkSetIt;
-typedef LinkSetList::const_iterator LinkSetConstIt;
+*/
 
 class LinkGroupAttr : public AAttr {
 public:
-	LinkGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
+	LinkGroupAttr( string const & name, IBlock * owner, vector<Link> * data ) : AAttr( name, owner ), _data(data) {}
 	~LinkGroupAttr() {}
 	AttrType GetType() const { return attr_linkgroup; }
-	void ReadAttr( istream& in, unsigned int version ) {
-		int len = ReadUInt( in );
-		//cout << "Link Group Size:  " << len << endl;
-
-		if ( len > 1000 ) {
-			throw runtime_error("Unlikley number of links found. (>1000)");
-		}
-
-		for (int i = 0; i < len; ++i ) {
-			int index = ReadUInt( in );
-			if (index != -1 )
-				AddLink( blk_ref( index ) );
-		}
-	}
-	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;
-
-		if ( links.size() > 1000 ) {
-			throw runtime_error("You probably shouldn't write more than 1000 links");
-		}
-
-		//Write the block indices
-		for (LinkSetConstIt it = links.begin(); it != links.end(); ++it ) {
-			WriteUInt( it->get_index(), out );
-		}
-	}
+	
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
-
-		for (LinkSetList::const_iterator it = links.begin(); it != links.end(); ++it ) {
-			out << endl << "   " << *it;
+		for (vector<Link>::const_iterator it = _data->begin(); it != _data->end(); ++it ) {
+			out << endl << "   " << it->GetLink();
 		}
-		if (links.size() == 0 ) {
+		if (_data->size() == 0 ) {
 			out << "None";
 		}
 
@@ -790,24 +533,26 @@ public:
 	list<blk_ref> asLinkList() const { 
 		list<blk_ref> out;
 
-		for (LinkSetList::const_iterator it = links.begin(); it != links.end(); ++it ) {
-			out.push_back( blk_ref(*it) );
+		for (vector<Link>::iterator it = _data->begin(); it != _data->end(); ++it ) {
+			out.push_back( it->GetLink() );
 		}
 
 		return out; 
 	}
 
 	void AddLink( blk_ref const & block ) {
-		links.push_back( lnk_ref(_owner, block) );
+		Link new_link(_owner);
+		new_link.SetLink( block );
+		_data->push_back( new_link);
 	}
 
 	void AddLinks( list<blk_ref> const & new_links ) {
 		//Add new list of links
-		list<blk_ref>::const_iterator it;
-		for (it = new_links.begin(); it != new_links.end(); ++it ) {
-			lnk_ref l(_owner, *it );
+		for (list<blk_ref>::const_iterator it = new_links.begin(); it != new_links.end(); ++it ) {
+			Link new_link(_owner);
+			new_link.SetLink( *it );
 			try {
-				links.push_back( l );
+				_data->push_back( new_link );
 			}
 			catch( exception & e ) {
 				cout << "Error:  " << e.what() << endl;
@@ -817,28 +562,33 @@ public:
 
 	blk_ref FindLink( string const & block_type ) const {
 		//Find the first link with the requested block type
-		for (LinkSetList::const_iterator it = links.begin(); it != links.end(); ++it ) {
-			if ( (*it)->GetBlockType() == block_type )
-				return blk_ref(*it);
+		for (vector<Link>::const_iterator it = _data->begin(); it != _data->end(); ++it ) {
+			if ( it->GetLink()->GetBlockType() == block_type )
+				return it->GetLink();
 		}
 
 		//No block was found, so return a null one
 		return blk_ref(-1);
 	}
 
-	void ClearLinks() { links.clear(); }
+	void ClearLinks() { _data->clear(); }
 
 	void RemoveLinks( blk_ref const & block ) {
 		//Remove all links that match this block
-		links.remove( lnk_ref( _owner, block ) );
+		for (vector<Link>::iterator it = _data->begin(); it != _data->end(); ++it ) {
+			if ( it->GetLink() == block ) {
+				_data->erase( it );
+				return;
+			}
+		}
 	}
 protected:
-	LinkSetList links;
+	vector<Link> * _data;
 };
-
+/*
 class TargetGroupAttr : public AAttr {
 public:
-	TargetGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
+	TargetGroupAttr( string const & name, IBlock * owner ) : AAttr( name, owner ) {
 		//cout << endl << "TargetGroupAttr()";
 	}
 	~TargetGroupAttr() {
@@ -984,7 +734,7 @@ private:
 
 class ModifierGroupAttr : public LinkGroupAttr {
 public:
-	ModifierGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkGroupAttr( name, owner, first_ver, last_ver ) {}
+	ModifierGroupAttr( string const & name, IBlock * owner ) : LinkGroupAttr( name, owner, first_ver, last_ver ) {}
 	~ModifierGroupAttr() {}
 
 	AttrType GetType() const { return attr_modifiergroup; }
@@ -1009,202 +759,32 @@ public:
 
 	}
 };
-
-class BBoxAttr : public AAttr {
+*/
+class BoundingBoxAttr : public AAttr {
 public:
-	BBoxAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
-		data.isUsed = false;
-		
-		data.unknownInt = 0;
-
-		data.translation.x = 0.0f;	data.translation.y = 0.0f;	data.translation.z = 0.0f;
-
-		data.rotation[0][0] = 1.0f;	data.rotation[0][1] = 0.0f;	data.rotation[0][2] = 0.0f;
-		data.rotation[1][0] = 0.0f;	data.rotation[1][1] = 1.0f;	data.rotation[1][2] = 0.0f;
-		data.rotation[2][0] = 0.0f;	data.rotation[2][1] = 0.0f;	data.rotation[2][2] = 1.0f;
-
-		data.radius.x = 0.0f;
-		data.radius.y = 0.0f;
-		data.radius.z = 0.0f;
-	}
-	~BBoxAttr() {}
+	BoundingBoxAttr( string const & name, IBlock * owner, BoundingBox * data ) : AAttr( name, owner ), _data(data) {}
+	~BoundingBoxAttr() {}
 	AttrType GetType() const { return attr_bbox; }
-	void ReadAttr( istream& in, unsigned int version ) { 
-		data.isUsed = ReadBool( in, version );
-		if ( data.isUsed ){
-			data.unknownInt = ReadUInt( in );
-			data.translation.x = ReadFloat( in );
-			data.translation.y = ReadFloat( in );
-			data.translation.z = ReadFloat( in );
-			for (int c = 0; c < 3; ++c) {
-				for (int r = 0; r < 3; ++r) {
-					data.rotation[r][c] = ReadFloat( in );
-				}
-			}
-			data.radius.x = ReadFloat( in );
-			data.radius.y = ReadFloat( in );
-			data.radius.z = ReadFloat( in );
-		}
-	}
-	void WriteAttr( ostream& out, unsigned int version ) const {
-		WriteBool( data.isUsed, out, version );
-		if ( data.isUsed ){
-			WriteUInt( data.unknownInt, out );
-			WriteFloat( data.translation.x, out );
-			WriteFloat( data.translation.y, out );
-			WriteFloat( data.translation.z, out );
-			for (int c = 0; c < 3; ++c) {
-				for (int r = 0; r < 3; ++r) {
-					WriteFloat(data.rotation[r][c], out );
-				}
-			}
-			WriteFloat( data.radius.x, out );
-			WriteFloat( data.radius.y, out );
-			WriteFloat( data.radius.z, out );
-		}
-	}
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
 		out << setprecision(1);
 
-		if ( data.isUsed ) {
-			out << endl
-				<< "   Position:  " << "(" << setw(5) << data.translation.x << ", " << setw(5) << data.translation.y << ", " << setw(5) << data.translation.z << " )" << endl
-				<< "   Rotation:"  << endl
-				<< "      |" << setw(5) << data.rotation[0][0] << ", " << setw(5) << data.rotation[0][1] << ", " << setw(5) << data.rotation[0][2] << " |" << endl
-				<< "      |" << setw(5) << data.rotation[1][0] << ", " << setw(5) << data.rotation[1][1] << ", " << setw(5) << data.rotation[1][2] << " |" << endl
-				<< "      |" << setw(5) << data.rotation[2][0] << ", " << setw(5) << data.rotation[2][1] << ", " << setw(5) << data.rotation[2][2] << " |" << endl
-				<< "   X Radius:  " << data.radius.x << endl
-				<< "   Y Radius:  " << data.radius.y << endl
-				<< "   Z Radius:  " << data.radius.z;
-		} 
-		else {
-			out << "None";
-		}
+		out << *_data;
 
 		return out.str();
 	}
-	BoundingBox asBoundingBox() const { return data; }
-	void Set(BoundingBox const & n ) { data = n; }
+	BoundingBox asBoundingBox() const { return *_data; }
+	void Set(BoundingBox const & n ) { *_data = n; }
 
 private:
-	BoundingBox data;
-};
-
-class CIntAttr : public AAttr {
-public:
-	CIntAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
-		data.isUsed = false;
-		data.unknownInt = 0;
-	}
-	~CIntAttr() {}
-	AttrType GetType() const { return attr_condint; }
-	void ReadAttr( istream& in, unsigned int version ) {
-		data.isUsed = ReadBool( in, version );
-		if (data.isUsed) {
-			data.unknownInt = ReadUInt( in );
-		}
-	}
-	void WriteAttr( ostream& out, unsigned int version ) const {
-		WriteBool( data.isUsed, out, version );
-		if (data.isUsed) {
-			WriteUInt( data.unknownInt, out );
-		}
-	}
-	string asString() const {
-		stringstream out;
-		out.setf(ios::fixed, ios::floatfield);
-		out << setprecision(1);
-
-		if (data.isUsed) {
-			out << data.unknownInt;
-		}
-		else {
-			out << "None";
-		}
-
-		return out.str();
-	}
-	ConditionalInt asConditionalInt() const { return data; }
-	void Set(ConditionalInt const & n ) {
-		data.isUsed = n.isUsed;
-		data.unknownInt = n.unknownInt;
-	}
-private:
-	ConditionalInt data;
-};
-
-class VertModeAttr : public IntAttr {
-public:
-	VertModeAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
-	~VertModeAttr() {}
-	AttrType GetType() const { return attr_vertmode; }
-
-	string asString() const {
-		stringstream out;
-		out.setf(ios::fixed, ios::floatfield);
-		out << setprecision(1);
-
-		switch ( data ) {
-			case 0:
-				out << "Source Ingore";
-				break;
-			case 1:
-				out << "Source Emmisive";
-				break;
-			case 2:
-				out << "Source Amb Diff";
-				break;
-			default:
-				out << "!Invalid Value! - " << data;
-				break;
-		}
-
-		return out.str();
-	}
-};
-
-class LightModeAttr : public IntAttr {
-public:
-	LightModeAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
-	~LightModeAttr() {}
-	AttrType GetType() const { return attr_lightmode; }
-	string asString() const {
-		stringstream out;
-		out.setf(ios::fixed, ios::floatfield);
-		out << setprecision(1);
-
-		switch ( data ) {
-			case 0:
-				out << "Emmisive";
-				break;
-			case 1:
-				out << "Emmisive Amb Diff";
-				break;
-			default:
-				out << "!Invalid Value! - " << data;
-				break;
-		}
-
-		return out.str();
-	}
+	BoundingBox * _data;
 };
 
-
-
-    //int vertex     - vertex mode:
-    //                 0 - source ignore
-    //                 1 - source emmisive
-    //                 2 - source amb diff
-
-    //int light      - lighting mode:
-    //                 0 - lighting emmisive
-    //                 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( string const & name, IBlock * owner ) : LinkAttr(name, owner, first_ver, last_ver), isUsed(false) {}
 	~ShaderAttr() {}
 	AttrType GetType() const { return attr_shader; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -1249,10 +829,11 @@ protected:
 	bool isUsed;
 	string _shader_name;
 };
+*/
 
-class TexSourceAttr : public LinkAttr {
+/*class TexSourceAttr : public LinkAttr {
 public:
-	TexSourceAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver) {
+	TexSourceAttr( string const & name, IBlock * owner ) : LinkAttr(name, owner ) {
 		data.unknownByte = 0;
 		data.useExternal = false;
 	}
@@ -1327,128 +908,11 @@ public:
 	}
 private:
 	TexSource data;
-};
-
-class PixelLayoutAttr : public IntAttr {
-public:
-	PixelLayoutAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
-	~PixelLayoutAttr() {}
-	AttrType GetType() const { return attr_pixellayout; }
+};*/
 
-	string asString() const {
-		stringstream out;
-		out.setf(ios::fixed, ios::floatfield);
-		out << setprecision(1);
-
-		switch ( data ) {
-			case 0:
-				out << "Palettised";
-				break;
-			case 1:
-				out << "16-bit High Color";
-				break;
-			case 2:
-				out << "32-bit True Color";
-				break;
-			case 3:
-				out << "Compressed";
-				break;
-			case 4:
-				out << "Bump Map";
-				break;
-			case 5:
-				out << "Default";
-				break;
-			default:
-				out << "!Invalid Value! - " << data;
-				break;
-		}
-
-		return out.str();
-	}
-};
-
-//typedef enum {
-//   PALETTISED = 0,
-//   HIGH_COLOR_16 = 1,
-//   TRUE_COLOR_32 = 2,
-//   COMPRESSED = 3,
-//   BUMPMAP = 4,
-//   PIX_DEFAULT = 5
-//} SMB_PixelLayout;
-
-class MipMapFormatAttr : public IntAttr {
+/*class ControllerTargetAttr : public AAttr {
 public:
-	MipMapFormatAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
-	~MipMapFormatAttr() {}
-	AttrType GetType() const { return attr_mipmapformat; }
-
-	string asString() const {
-		stringstream out;
-		out.setf(ios::fixed, ios::floatfield);
-		out << setprecision(1);
-
-		switch ( data ) {
-			case 0:
-				out << "No";
-				break;
-			case 1:
-				out << "Yes";
-				break;
-			case 2:
-				out << "Default";
-				break;
-			default:
-				out << "!Invalid Value! - " << data;
-				break;
-		}
-
-		return out.str();
-	}
-};
-
-//typedef enum {
-//   MIPMAP_NO = 0,
-//   MIPMAP_YES = 1,
-//   MIPMAP_MIP_DEFAULT = 2,
-//} SMB_MipMapFormat;
-
-class AlphaFormatAttr : public IntAttr {
-public:
-	AlphaFormatAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
-	~AlphaFormatAttr() {}
-	AttrType GetType() const { return attr_alphaformat; }
-
-	string asString() const {
-		stringstream out;
-		out.setf(ios::fixed, ios::floatfield);
-		out << setprecision(1);
-
-		switch ( data ) {
-			case 0:
-				out << "None";
-				break;
-			case 1:
-				out << "Binary";
-				break;
-			case 2:
-				out << "Smooth";
-				break;
-			case 3:
-				out << "Default";
-				break;
-			default:
-				out << "!Invalid Value! - " << data;
-				break;
-		}
-
-		return out.str();
-	}
-};
-
-class ControllerTargetAttr : public AAttr {
-public:
-	ControllerTargetAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	ControllerTargetAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ControllerTargetAttr() {}
 	AttrType GetType() const { return attr_controllertarget; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -1494,11 +958,11 @@ public:
 	blk_ref asLink() const { return FindTarget(); }
 	void Set(blk_ref const &) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
 
-};
+};*/
 
-class EmitterObjectAttr : public AAttr {
+/*class EmitterObjectAttr : public AAttr {
 public:
-	EmitterObjectAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	EmitterObjectAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~EmitterObjectAttr() {}
 	AttrType GetType() const { return attr_emitterobject; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -1544,11 +1008,11 @@ public:
 	blk_ref asLink() const { return FindTarget(); }
 	void Set(blk_ref const &) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
 
-};
+};*/
 
-class SelfLinkAttr : public AAttr {
+/*class SelfLinkAttr : public AAttr {
 public:
-	SelfLinkAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	SelfLinkAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~SelfLinkAttr() {}
 	AttrType GetType() const { return attr_emitterobject; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -1574,7 +1038,7 @@ public:
 
 class SkeletonRootAttr : public AAttr {
 public:
-	SkeletonRootAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	SkeletonRootAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~SkeletonRootAttr() {}
 	AttrType GetType() const { return attr_skeletonroot; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -1604,7 +1068,6 @@ public:
 		}
 
 		//Arbitrarily start at the first bone in the list, and get it's ancestors
-		/*NEW CODE BEGIN*/
 		// We want to get the closest common ancestor between the _owner and the bones
 		// So start with a list of ancestors of the first bone (this is just a random choice)
 		blk_ref block = bones[0];
@@ -1678,7 +1141,7 @@ public:
 			//We didn't find the root this time, set block to par and try again
 			block = par;
 		}
-		OLD CODE END*/
+		//OLD CODE END
 	}
 	string asString() const {
 		stringstream out;
@@ -1700,7 +1163,7 @@ private:
 
 class ParentAttr : public AAttr {
 public:
-	ParentAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	ParentAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ParentAttr() {}
 	AttrType GetType() const { return attr_parent; }
 	void ReadAttr( istream& in, unsigned int version ) {
@@ -1724,7 +1187,7 @@ public:
 
 class ParticleGroupAttr : public AAttr {
 public:
-	ParticleGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	ParticleGroupAttr( string const & name, IBlock * owner ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ParticleGroupAttr() {}
 	AttrType GetType() const { return attr_particlegroup; }
 
@@ -1797,7 +1260,7 @@ private:
 
 class LODInfoAttr : public LinkAttr {
 public:
-	LODInfoAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver) {}
+	LODInfoAttr( string const & name, IBlock * owner ) : LinkAttr(name, owner, first_ver, last_ver) {}
 	~LODInfoAttr() {}
 	AttrType GetType() const { return attr_lodinfo; }
 
@@ -1859,7 +1322,7 @@ private:
 
 class Unk292BytesAttr : public AAttr {
 public:
-	Unk292BytesAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
+	Unk292BytesAttr( string const & name, IBlock * owner ) : AAttr( name, owner ) {
 		for ( int i = 0; i < 256; ++i ) {
 			data[i] = 0;
 		}
@@ -1911,7 +1374,7 @@ public:
 	}
 protected:
 	byte data[256];
-};
+};*/
 
 
 #endif
diff --git a/niflib.cpp b/niflib.cpp
index c36ed1246a04a8bb0235905ca736e68dcda6c8f1..f683e0a2c67f7111af19a674ee4f4cb8726533a3 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 #include "niflib.h"
 #include "NIF_Blocks.h"
-#include "nif_attrs.h"
+//#include "nif_attrs.h"
 #include "kfm.h"
 #include <exception>
 #include <stdexcept>
@@ -880,7 +880,6 @@ void MergeNifTrees( blk_ref target, blk_ref right, unsigned int version ) {
 attr_ref::operator blk_ref() const { return _attr->asLink(); }
 attr_ref::operator TexSource() const { return _attr->asTexSource(); }
 attr_ref::operator BoundingBox() const { return _attr->asBoundingBox(); }
-attr_ref::operator ConditionalInt() const { return _attr->asConditionalInt(); }
 
 string TexDesc::asString() const {
 	stringstream out;
@@ -946,9 +945,9 @@ string TexDesc::asString() const {
 			out << endl
 				<< "         Translation: " << translation.u << ", " << translation.v << endl
 				<< "         Tiling: " << tiling.u << ", " << tiling.v << endl
-				<< "         W-rotation: " << w_rotation << endl
-				<< "         Transform Type: " << transform_type << endl
-				<< "         Center Offset: " << center_offset.u << ", " << center_offset.v << endl;
+				<< "         W-rotation: " << wRotation << endl
+				<< "         Transform Type: " << transformType << endl
+				<< "         Center Offset: " << centerOffset.u << ", " << centerOffset.v << endl;
 		} else {
 			out << "None" << endl;
 		}
diff --git a/niflib.h b/niflib.h
index 28955d82205b0be95a9da4fe66c29153f99716de..460347221ed661b1e7f44d406d37d298c7b5d548 100644
--- a/niflib.h
+++ b/niflib.h
@@ -74,7 +74,6 @@ struct blk_link;
 struct Texture;
 struct TextureSource;
 struct BoundingBox;
-struct ConditionalInt;
 struct SkinWeight;
 struct ControllerLink;
 struct TexDesc;
@@ -119,7 +118,6 @@ enum AttrType {
 	attr_linkgroup, /*!< Link Group Attribute.  Links to several other Nif blocks lower in the Nif tree. */ 
 	attr_bones, /*!< Bones Attribute.  Automatic. */ 
 	attr_bbox, /*!< Bounding Box Attribute.  Holds a BoundingBox structure. */ 
-	attr_condint, /*!< Conditional Integer Attribute.  Holds a ConditionalInt structure. */ 
 	attr_vertmode, /*!< Vertex Mode Attribute.  Holds an integer that corresponds to the vertex mode. */ 
 	attr_lightmode, /*!< Light Mode Attribute.  Holds an integer that corresponds to the light mode. */ 
 	attr_texture, /*!< Texture Attribute.  Holds a Texture structure but ignores the bump map information. */ 
@@ -1376,12 +1374,6 @@ struct BoundingBox {
 	Vector3 radius; /*!< A vector containing the radius of this box in the direction of each axis, X, Y, and Z. */
 };
 
-/*! Holds an integer that may or may not be used. */
-struct ConditionalInt {
-	bool isUsed; /*!< Determines whether the integer contained within this structure is used or not.  If this value is true, the integer is significant.  If false, it is ignored. */ 
-	int unknownInt; /*!< The integer value which may or may not be in use.  Its function is unknown. */ 
-};
-
 /*! Stores texture source data.  Specifies where to find the image data; in an external file, or within a NiPixelData block. */
 struct TexSource {
 	bool useExternal; /*!< Specifies whether to use an external file for the texture or not.  If true, an external file is used.  If false, the image data is stored within a NiPixelData block.  This block can be retrieved by using the asLink function on the same attribute. */ 
@@ -1662,9 +1654,6 @@ public:
 	 */
 	virtual string GetName() const = 0;
 
-	virtual void Read( istream& in, unsigned int version ) = 0;
-	virtual void Write( ostream& out, unsigned int version ) const = 0;
-
 	//--Getters--//
 
 	/*!
@@ -1734,12 +1723,6 @@ public:
 	 */
 	virtual BoundingBox asBoundingBox() const = 0;
 
-	/*!
-	 * Used to get a copy of the ConditionalInt structure stored in an attribute.  Raises an exception if the attribute does not store this type of value.
-	 * \return A copy of the ConditionalInt structure stored in this attribute.
-	 */
-	virtual ConditionalInt asConditionalInt() const = 0;
-
 	/*!
 	 * Used to retrieve a list of all the blocks linked through this attribute to its owner block.  Raises an exception if the attribute does not store this type of value.
 	 * \return A list of all the blocks linked through this attribute to its owner block. The list will be empty if no blocks are linked through this attribute.
@@ -1831,12 +1814,6 @@ public:
 	 */
 	virtual void Set( BoundingBox const & val ) = 0;
 
-	/*!
-	 * Used to change the value stored in an attribute.  Raises an exception if the attribute does not store the type of value that the Set function is called on.
-	 * \param val This value will be copied into the attribute and stored.
-	 */
-	virtual void Set( ConditionalInt const & val ) = 0;
-
 	//--Link functions--//
 
 	/*!
@@ -3045,15 +3022,6 @@ public:
 		return *this;
 	}
 
-	/*! The assignment operators are shorthand for using the IAttr::Set function.  They allow you to set the value contained by the attribute pointed to by this reference by using the = operator instead of calling their Set function through the -> operator.
-	 * \param n The new value to set the IAttr attribute to using its Set function.
-	 * \return a reference to this attr_ref object.
-	 */
-	attr_ref & operator=(ConditionalInt const & n) {
-		_attr->Set(n);
-		return *this;
-	}
-
 	//--Conversion fuctions--//
 
 	/*! The type operators are shorthand for using the IAttr::AsType functions.  They allow you to retrieve the value contained by the attribute pointed to by this reference by using the = operator instead of calling their asType function through the -> operator.
@@ -3101,11 +3069,6 @@ public:
 	 */
 	operator BoundingBox() const;
 
-	/*! The type operators are shorthand for using the IAttr::AsType functions.  They allow you to retrieve the value contained by the attribute pointed to by this reference by using the = operator instead of calling their asType function through the -> operator.
-	 * \return the value stored in the attribute stored in this reference by calling its asType function.
-	 */
-	operator ConditionalInt() const;
-
 	/*! The type operators are shorthand for using the IAttr::AsType functions.  They allow you to retrieve the value contained by the attribute pointed to by this reference by using the = operator instead of calling their asType function through the -> operator.
 	 * \return the value stored in the attribute stored in this reference by calling its asType function.
 	 */
@@ -3385,12 +3348,6 @@ public:
 			throw std::out_of_range("Tried to set an attribute via [] that does not exist in this block.");
 		attr->Set(value);
 	}
-	void __setitem__(string index, ConditionalInt const & value) {
-		attr_ref attr = _block->GetAttr(index);
-		if ( attr.is_null() == true )
-			throw std::out_of_range("Tried to set an attribute via [] that does not exist in this block.");
-		attr->Set(value);
-	}
 protected:
 	int _index;
 	IBlock * _block;
@@ -3402,7 +3359,7 @@ struct TexDesc {
 	TexDesc() : isUsed(false), clampMode(WRAP_S_WRAP_T), filterMode(FILTER_TRILERP), textureSet(0),
 		PS2_L(0), PS2_K(0xFFB5), unknownShort(0x0101),
 		hasTextureTransform(false), translation(0.0, 0.0), tiling(0.0, 0.0),
-		w_rotation(0.0), transform_type(0), center_offset(0.0, 0.0) {}
+		wRotation(0.0), transformType(0), centerOffset(0.0, 0.0) {}
 	string asString() const;
 	bool isUsed; /*!< Determines whether this texture description is used or not.  If this value is true, the other members of this structure are significant.  If false, they are ignored. */ 
 	blk_ref source; /*!< The NiTextureSource block which points to the texture data. > */
@@ -3415,9 +3372,9 @@ struct TexDesc {
 	bool hasTextureTransform; /*!< Determines whether or not the texture's coordinates are transformed. */ 
 	TexCoord translation; /*!< The amount to translate the texture coordinates in each direction?. */ 
 	TexCoord tiling; /*!< Number of times the texture is tiled in each direction? */ 
-	float w_rotation; /*!< Rotation of the texture image around the W axis? */ 
-	int transform_type; /*!< The texture transform type? Doesn't seem to do anything. */ 
-	TexCoord center_offset; /*!< The offset from the origin? */ 
+	float wRotation; /*!< Rotation of the texture image around the W axis? */ 
+	int transformType; /*!< The texture transform type? Doesn't seem to do anything. */ 
+	TexCoord centerOffset; /*!< The offset from the origin? */ 
 };
 
 //--USER GUIDE DOCUMENTATION--//
@@ -3554,7 +3511,6 @@ Float3<br>
 Matrix33<br>
 TexSource<br>
 BoundingBox<br>
-ConditionalInt<br>
 TexDesc<br>
 </td></tr></table>
 
@@ -3578,7 +3534,6 @@ There are several types of attributes, more than the list above, and each type s
 <tr><td>attr_bumpmap</td><td>TexDesc & blk_ref</td></tr>
 <tr><td>attr_byte</td><td>int</td></tr>
 <tr><td>attr_color3</td><td>Float3</td></tr>
-<tr><td>attr_condint</td><td>ConditionalInt</td></tr>
 <tr><td>attr_controllertarget</td><td>Automatic.</td></tr>
 <tr><td>attr_flags</td><td>int</td></tr>
 <tr><td>attr_float</td><td>float</td></tr>
diff --git a/niflib.vcproj b/niflib.vcproj
index c55a158337b7bd40c6975722fd9327babad8438d..1ec8629fda50b7c22dfadee82fc5edc597ff2055 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -155,6 +155,9 @@
 						RuntimeLibrary="3"/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath=".\niflib_internal.cpp">
+			</File>
 			<File
 				RelativePath=".\xml_extract.cpp">
 			</File>