From 27bc63bf1df7b58090be2fdae65424c7e9abf80f Mon Sep 17 00:00:00 2001
From: Amorilia <amorilia@users.sourceforge.net>
Date: Fri, 9 Dec 2005 02:35:42 +0000
Subject: [PATCH] Added const correctness; fixed a few GCC compilation
 problems.

---
 Makefile.am    |   4 +-
 NIF_Blocks.cpp | 255 ++++++++++++++++++------------
 NIF_Blocks.h   | 414 ++++++++++++++++++++++++++++---------------------
 NIF_IO.cpp     |  58 +++----
 NIF_IO.h       |  84 +++++-----
 nif_attrs.h    | 151 +++++++++---------
 nif_math.cpp   |  22 +--
 nif_math.h     |  22 +--
 niflib.cpp     | 106 +++++++++----
 niflib.h       | 202 +++++++++++++-----------
 pyniflib.i     |  54 ++++---
 11 files changed, 782 insertions(+), 590 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 1c6072ab..9f60fd8b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,7 +31,7 @@ AM_CPPFLAGS = -I$(srcdir) -ggdb
 #libniflib_la_LDFLAGS = -version-info 0:0:0 -shared -no-undefined
 
 BUILT_SOURCES = swig_wrap.cpp
-SWIG_SOURCES = pyniflib.i
+SWIG_SOURCES = pyniflib.i niflib.h
 pkgpython_PYTHON = niflib.py
 pkgpyexec_LTLIBRARIES = _niflib.la
 _niflib_la_SOURCES = \
@@ -43,7 +43,7 @@ docsys_extract.cpp \
 swig_wrap.cpp \
 $(SWIG_SOURCES)
 _niflib_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS)
-_niflib_la_LDFLAGS = -module -shared -no-undefined
+_niflib_la_LDFLAGS = -module -shared #-no-undefined
 
 swig_wrap.cpp: $(SWIG_SOURCES)
 	$(SWIG) $(SWIG_PYTHON_OPT) -o $@ $<
diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp
index f47075f5..4d006c0d 100644
--- a/NIF_Blocks.cpp
+++ b/NIF_Blocks.cpp
@@ -64,7 +64,7 @@ ABlock::~ABlock() {
 	}
 }
 
-void ABlock::AddAttr( AttrType type, string name, unsigned int first_ver, unsigned int last_ver ) {
+void ABlock::AddAttr( AttrType type, string const & name, unsigned int first_ver, unsigned int last_ver ) {
 	IAttr * attr;
 	if ( type == attr_int ) {
 		attr = new IntAttr( name, this, first_ver, last_ver );
@@ -133,8 +133,8 @@ void ABlock::AddAttr( AttrType type, string name, unsigned int first_ver, unsign
 	_attr_vect.push_back(attr_ref(attr));
 }
 
-attr_ref ABlock::GetAttr(string attr_name) {
-	map<string, attr_ref>::iterator it;
+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;
@@ -146,11 +146,11 @@ attr_ref ABlock::GetAttr(string attr_name) {
 }
 
 
-vector<attr_ref> ABlock::GetAttrs() {
+vector<attr_ref> ABlock::GetAttrs() const {
 	return _attr_vect;
 }
 
-blk_ref ABlock::GetParent() {
+blk_ref ABlock::GetParent() const {
 	if (_parents.size() > 0 )
 		return blk_ref(_parents[0]);
 	else
@@ -176,7 +176,7 @@ void ABlock::Read( ifstream& in, unsigned int version ) {
 	//}
 }
 
-void ABlock::Write( ofstream& out, unsigned int version ) {
+void ABlock::Write( ofstream& out, unsigned int version ) const {
 
 	//Write Attributes
 	for (unsigned int i = 0; i < _attr_vect.size(); ++i ) {
@@ -185,7 +185,7 @@ void ABlock::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string ABlock::asString() {
+string ABlock::asString() const {
 	// Create a stringstream and set the floating point format
 	// fixed notation with one decimal place
 	stringstream out;
@@ -218,11 +218,11 @@ void ABlock::SubtractRef() {
 	}
 }
 
-list<blk_ref> ABlock::GetLinks() {
+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>::iterator it;
+	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();
@@ -302,7 +302,18 @@ void * ANode::QueryInterface( int id ) {
 	}
 }
 
-Matrix44 ANode::GetLocalTransform() {
+void const * ANode::QueryInterface( int id ) const {
+	// Contains INode Interface
+	if ( id == ID_NODE ) {
+		return (void const *)static_cast<INode const *>(this);
+	} else if (id == NodeInternal ) {
+		return (void const *)static_cast<INodeInternal const *>(this);
+	} else {
+		return ABlock::QueryInterface( id );
+	}
+}
+
+Matrix44 ANode::GetLocalTransform() const {
 	//Get transform data from atributes
 	Matrix33 f = GetAttr("Rotation")->asMatrix33();
 	Float3 tran = GetAttr("Translation")->asFloat3();
@@ -326,7 +337,7 @@ Matrix44 ANode::GetLocalTransform() {
 	return MultMatrix44(rt, s);
 }
 
-Matrix44 ANode::GetWorldTransform() {
+Matrix44 ANode::GetWorldTransform() const {
 	//Get Parent Transform if there is one
 	blk_ref par = GetParent();
 	INode * node;
@@ -346,7 +357,7 @@ Matrix44 ANode::GetWorldTransform() {
 	}
 }
 
-Matrix44 ANode::GetBindPosition() {
+Matrix44 ANode::GetBindPosition() const {
 	return bindPosition;
 	//for (int i = 0; i < 4; ++i) {
 	//	for (int j = 0; j < 4; ++j) {
@@ -355,7 +366,7 @@ Matrix44 ANode::GetBindPosition() {
 	//}
 }
 
-Matrix44 ANode::GetLocalBindPos() {
+Matrix44 ANode::GetLocalBindPos() const {
 	//Get Parent Transform if there is one
 	blk_ref par = GetParent();
 	INode * node;
@@ -373,7 +384,7 @@ Matrix44 ANode::GetLocalBindPos() {
 	}
 }
 
-void ANode::SetBindPosition( Matrix44 & m ) {
+void ANode::SetBindPosition( Matrix44 const & m ) {
 	bindPosition = m;
 	//for (int i = 0; i < 4; ++i) {
 	//	for (int j = 0; j < 4; ++j) {
@@ -445,7 +456,7 @@ ANode::~ANode() {
  * NiNode methods
  **********************************************************/
 
-string NiNode::asString() {
+string NiNode::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -551,7 +562,7 @@ string NiNode::asString() {
 	if (skin_refs.size() > 0) {
 		out << "Influenced Skins:" << endl;
 
-		list<IBlock*>::iterator it;
+		list<IBlock*>::const_iterator it;
 		for (it = skin_refs.begin(); it != skin_refs.end(); ++it ) {
 			out << "   " << blk_ref(*it) << endl;
 		}
@@ -637,7 +648,7 @@ void AShapeData::Read( ifstream& in, unsigned int version ){
 	}
 }
 
-string AShapeData::asString() {
+string AShapeData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -721,7 +732,7 @@ string AShapeData::asString() {
 /**
  * AShapeData::Write
  */
-void AShapeData::Write( ofstream& out, unsigned int version ){
+void AShapeData::Write( ofstream& out, unsigned int version ) const {
 
 	WriteUShort( ushort(vertices.size()), out );
 
@@ -785,6 +796,15 @@ void * AShapeData::QueryInterface( int id ) {
 	}
 }
 
+void const * AShapeData::QueryInterface( int id ) const {
+	// Contains ShapeData Interface
+	if ( id == ID_SHAPE_DATA ) {
+		return (void const *)static_cast<IShapeData const *>(this);
+	} else {
+		return AData::QueryInterface( id );
+	}
+}
+
 void AShapeData::SetVertexCount(int n) {
 	if ( n > 65535 || n < 0 )
 		throw runtime_error("Invalid Vertex Count: must be between 0 and 65535.");
@@ -873,7 +893,7 @@ void AParticlesData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void AParticlesData::Write( ofstream& out, unsigned int version ) {
+void AParticlesData::Write( ofstream& out, unsigned int version ) const {
 	AShapeData::Write( out, version );
 
 	//numActive exists up to version 4.0.0.2
@@ -900,7 +920,7 @@ void AParticlesData::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string AParticlesData::asString() {
+string AParticlesData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -948,7 +968,7 @@ void ARotatingParticlesData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void ARotatingParticlesData::Write( ofstream& out, unsigned int version ) {
+void ARotatingParticlesData::Write( ofstream& out, unsigned int version ) const {
 	AParticlesData::Write( out, version );
 
 	WriteBool( hasRotations, out, version );
@@ -963,7 +983,7 @@ void ARotatingParticlesData::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string ARotatingParticlesData::asString() {
+string ARotatingParticlesData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -996,13 +1016,13 @@ void NiParticleMeshesData::Read( ifstream& in, unsigned int version ) {
 	GetAttr("Unknown Link")->Read( in, version );
 }
 
-void NiParticleMeshesData::Write( ofstream& out, unsigned int version ) {
+void NiParticleMeshesData::Write( ofstream& out, unsigned int version ) const {
 	ARotatingParticlesData::Write( out, version );
 
 	GetAttr("Unknown Link")->Write( out, version );
 }
 
-string NiParticleMeshesData::asString() {
+string NiParticleMeshesData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -1054,7 +1074,7 @@ void NiTriShapeData::Read( ifstream& in, unsigned int version ){
 	}
 }
 
-string NiTriShapeData::asString() {
+string NiTriShapeData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -1088,7 +1108,7 @@ string NiTriShapeData::asString() {
 /**
  * NiTriShapeData::Write - Writes block name to out, in addition to data.
  */
-void NiTriShapeData::Write( ofstream& out, unsigned int version ){
+void NiTriShapeData::Write( ofstream& out, unsigned int version ) const {
 
 	AShapeData::Write( out, version );
 
@@ -1140,6 +1160,15 @@ void * NiTriShapeData::QueryInterface( int id ) {
 	}
 }
 
+void const * NiTriShapeData::QueryInterface( int id ) const {
+	// Contains TriShapeData Interface
+	if ( id == ID_TRI_SHAPE_DATA ) {
+		return (void const *)static_cast<ITriShapeData const *>(this);
+	} else {
+		return AShapeData::QueryInterface( id );
+	}
+}
+
 void NiTriShapeData::SetTriangleCount(int n) {
 	if ( n > 65535 || n < 0 )
 		throw runtime_error("Invalid Triangle Count: must be between 0 and 65535.");
@@ -1193,7 +1222,7 @@ void NiTriStripsData::Read( ifstream& in, unsigned int version ){
 	}
 }
 
-void NiTriStripsData::Write( ofstream& out, unsigned int version ){
+void NiTriStripsData::Write( ofstream& out, unsigned int version ) const {
 
 	AShapeData::Write( out, version );
 
@@ -1220,7 +1249,7 @@ void NiTriStripsData::Write( ofstream& out, unsigned int version ){
 	}
 }
 
-string NiTriStripsData::asString() {
+string NiTriStripsData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -1253,7 +1282,16 @@ void * NiTriStripsData::QueryInterface( int id ) {
 	}
 }
 
-short NiTriStripsData::GetStripCount() {
+void const * NiTriStripsData::QueryInterface( int id ) const {
+	// Contains TriShapeData Interface
+	if ( id == ID_TRI_STRIPS_DATA ) {
+		return (void const *)static_cast<ITriStripsData const *>(this);
+	} else {
+		return AShapeData::QueryInterface( id );
+	}
+}
+
+short NiTriStripsData::GetStripCount() const {
 	return short(strips.size());
 }
 
@@ -1262,18 +1300,18 @@ void NiTriStripsData::SetStripCount(int n) {
 }
 
 //Getters
-vector<short> NiTriStripsData::GetStrip( int index ) {
+vector<short> NiTriStripsData::GetStrip( int index ) const {
 	return strips[index];
 }
 
-vector<Triangle> NiTriStripsData::GetTriangles() {
+vector<Triangle> NiTriStripsData::GetTriangles() const {
 
 	//Create a vector to hold the triangles
 	vector<Triangle> triangles( GetTriangleCount() );
 	int n = 0; // Current triangle
 
 	//Cycle through all strips
-	vector< vector<short> >::iterator it;
+	vector< vector<short> >::const_iterator it;
 	for (it = strips.begin(); it != strips.end(); ++it ) {
 		//The first three values in the strip are the first triangle
 		triangles[n].Set( (*it)[0], (*it)[1], (*it)[2] );
@@ -1302,7 +1340,7 @@ void NiTriStripsData::SetStrip( int index, const vector<short> & in ) {
 	strips[index] = in;
 }
 
-short NiTriStripsData::GetTriangleCount() {
+short NiTriStripsData::GetTriangleCount() const {
 
 	//Calculate number of triangles
 	//Sum of length of each strip - 2
@@ -1344,7 +1382,7 @@ void NiCollisionData::Read( ifstream& in, unsigned int version ){
 	} 
 }
 
-void NiCollisionData::Write( ofstream& out, unsigned int version ){
+void NiCollisionData::Write( ofstream& out, unsigned int version ) const {
 
 	//Write Parent node number
 	WriteUInt( GetParent().get_index(), out );
@@ -1369,7 +1407,7 @@ void NiCollisionData::Write( ofstream& out, unsigned int version ){
 	} 
 }
 
-string NiCollisionData::asString() {
+string NiCollisionData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -1440,9 +1478,9 @@ void NiSkinData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiSkinData::Write( ofstream& out, unsigned int version ) {
+void NiSkinData::Write( ofstream& out, unsigned int version ) const {
 	//Calculate offset matrices prior to writing data
-	CalculateBoneOffsets();
+	//CalculateBoneOffsets(); // non-const! (we should calculate the data on the fly while writing, without actually storing it in the class)
 
 	for (int c = 0; c < 3; ++c) {
 		for (int r = 0; r < 3; ++r) {
@@ -1458,7 +1496,7 @@ void NiSkinData::Write( ofstream& out, unsigned int version ) {
 		WriteByte( unknownByte, out );
 	}
 
-	map<IBlock*, Bone>::iterator it;
+	map<IBlock *, Bone>::const_iterator it;
 	for( it = bone_map.begin(); it != bone_map.end(); ++it ) {		
 		for (int c = 0; c < 3; ++c) {
 			for (int r = 0; r < 3; ++r) {
@@ -1475,7 +1513,7 @@ void NiSkinData::Write( ofstream& out, unsigned int version ) {
 		//WriteFloat( 0.0f, out );
 		WriteUShort( short(it->second.weights.size() ), out );
 		
-		map<int, float>::iterator it2;
+		map<int, float>::const_iterator it2;
 		for ( it2 = it->second.weights.begin(); it2 != it->second.weights.end(); ++it2 ){
 			WriteUShort( it2->first, out );
 			WriteFloat( it2->second, out );
@@ -1521,13 +1559,13 @@ void NiSkinData::Write( ofstream& out, unsigned int version ) {
 //	}
 //}
 
-string NiSkinData::asString() {
+string NiSkinData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
 
 	//Calculate bone offsets pior to printing readout
-	CalculateBoneOffsets();
+	//CalculateBoneOffsets(); // non-const!
 
 	out << "Rotate:" << endl
 		<< "   |" << setw(6) << rotation[0][0] << "," << setw(6) << rotation[0][1] << "," << setw(6) << rotation[0][2] << " |" << endl
@@ -1540,16 +1578,16 @@ string NiSkinData::asString() {
 		<< "Unknown Byte:  " << int(unknownByte) << endl
 		<< "Bones:" << endl;
 
-	map<IBlock*, Bone>::iterator it;
+	map<IBlock *, Bone>::const_iterator it;
 	//vector<Bone>::iterator it;
 	int num = 0;
 	for( it = bone_map.begin(); it != bone_map.end(); ++it ) {
 		//Friendlier name
-		Bone & bone = it->second;
+		Bone const & bone = it->second;
 
 		num++;
 		out << "Bone " << num << ":" << endl
-			<< "   Block:  " << blk_ref(it->first) << endl
+			<< "   Block:  " << it->first->GetBlockNum() << endl //blk_ref(it->first) << endl
 			<< "   Bone Offset Transforms:" << endl
 			<< "      Rotation:" << endl
 			<< "         |" << setw(6) << bone.rotation[0][0] << "," << setw(6) << bone.rotation[0][1] << "," << setw(6) << bone.rotation[0][2] << " |" << endl
@@ -1568,7 +1606,7 @@ string NiSkinData::asString() {
 		out << "   Weights:  " << uint(bone.weights.size()) << endl;
 
 		if (verbose) {
-			map<int, float>::iterator it2;
+			map<int, float>::const_iterator it2;
 			for ( it2 = bone.weights.begin(); it2 != bone.weights.end(); ++it2 ){
 				out << "   Vertex: " << it2->first << "\tWeight: " << it2->second << endl;
 			}
@@ -1593,20 +1631,31 @@ void * NiSkinData::QueryInterface( int id ) {
 	}
 }
 
+void const * NiSkinData::QueryInterface( int id ) const {
+	// Contains ISkinData Interface
+	if ( id == ID_SKIN_DATA ) {
+		return (void const *)static_cast<ISkinData const *>(this);
+	} else if ( id == SkinDataInternal ) {
+		return (void const *)static_cast<ISkinDataInternal const *>(this);
+	} else {
+		return ABlock::QueryInterface( id );
+	}
+}
+
 void NiSkinData::SetBones( vector<blk_ref> bone_blocks ) {
 	//Move bones from temproary vector to map, sorted by blk_ref
 	for (uint i = 0; i < bones.size(); ++i) {
-			//Make sure bone is a node
-			INodeInternal * node_int = (INodeInternal*)bone_blocks[i]->QueryInterface(NodeInternal);
+		//Make sure bone is a node
+		INodeInternal * node_int = (INodeInternal*)bone_blocks[i]->QueryInterface(NodeInternal);
 
-			if (node_int == NULL)
-				throw runtime_error("Attempted to add a block as a bone that is not a node.");
+		if (node_int == NULL)
+			throw runtime_error("Attempted to add a block as a bone that is not a node.");
 
-			//move the data
-			bone_map.insert( pair<IBlock*, Bone>(bone_blocks[i].get_block(), bones[i]) );
-			
-			//Increment reference at bone node site
-			node_int->IncSkinRef(this);
+		//move the data
+		bone_map.insert( pair<IBlock *, Bone>(bone_blocks[i].get_block(), bones[i]) );
+
+		//Increment reference at bone node site
+		node_int->IncSkinRef(this);
 	}
 
 	//Clear temporary vector data
@@ -1630,7 +1679,7 @@ void NiSkinData::StraightenSkeleton() {
 	//}
 
 	//Loop through all bones
-	map<IBlock*, Bone>::iterator it;
+	map<IBlock *, Bone>::iterator it;
 	for ( it = bone_map.begin(); it != bone_map.end(); ++it ) {
 		//Friendlier name for current bone
 		Bone & bone = it->second;
@@ -1644,7 +1693,7 @@ void NiSkinData::StraightenSkeleton() {
 			bone.translation[0], bone.translation[1], bone.translation[2], 1.0f
 		); 
 		//Loop through all bones again, checking for any that have this bone as a parent
-		map<IBlock*, Bone>::iterator it2;
+		map<IBlock *, Bone>::iterator it2;
 		for ( it2 = bone_map.begin(); it2 != bone_map.end(); ++it2 ) {
 			if ( it2->first->GetParent() == it->first ) {
 				//Block 2 has block 1 as a parent
@@ -1695,7 +1744,7 @@ void NiSkinData::RepositionTriShape() {
 		//--End Position--//
 
 		//Get first bone
-		blk_ref bone_blk = bone_map.begin()->first;
+		IBlock * bone_blk = bone_map.begin()->first;
 		Bone & bone = bone_map.begin()->second;
 
 
@@ -1765,21 +1814,23 @@ vector<blk_ref> NiSkinData::GetBones() {
 	//Put all the valid bones from the map into a vector to return
 	vector<blk_ref> bone_blks( bone_map.size() );
 
-	map<IBlock*, Bone>::iterator it;
+	map<IBlock *, Bone>::const_iterator it;
 	int count = 0;
 	for (it = bone_map.begin(); it != bone_map.end(); ++it ) {
-		bone_blks[count] = blk_ref(it->first);
+		bone_blks[count] = it->first;
 		count++;
 	}
 
 	return bone_blks;
 }
 
-map<int, float> NiSkinData::GetWeights( blk_ref bone ) {
-	return bone_map[bone.get_block()].weights;
+map<int, float> NiSkinData::GetWeights( blk_ref const & bone ) const {
+	// since operator[] might insert a new element, it can't be const
+	// so we need the find function
+	return bone_map.find(bone.get_block())->second.weights;
 }
 
-void NiSkinData::AddBone( blk_ref bone, map<int, float> in ) {
+void NiSkinData::AddBone( blk_ref const & bone, map<int, float> const & in ) {
 	//Make sure bone is a node
 	INodeInternal * node_int = (INodeInternal*)bone->QueryInterface(NodeInternal);
 
@@ -1793,14 +1844,14 @@ void NiSkinData::AddBone( blk_ref bone, map<int, float> in ) {
 	node_int->IncSkinRef(this);
 }
 
-void NiSkinData::RemoveBoneByPtr( IBlock * bone ) {
+void NiSkinData::RemoveBoneByPtr( blk_ref const & bone ) {
 	//Remove bone from internal list
-	bone_map.erase( bone );
+	bone_map.erase( bone.get_block() );
 
 	//Do not decrement bone node locatoin because it is already dead
 }
 
-void NiSkinData::RemoveBone( blk_ref bone ) {
+void NiSkinData::RemoveBone( blk_ref const & bone ) {
 	//Remove bone from internal list
 	bone_map.erase( bone.get_block() );
 
@@ -1811,7 +1862,7 @@ void NiSkinData::RemoveBone( blk_ref bone ) {
 
 NiSkinData::~NiSkinData() {
 	//Inform all linked bone nodes that this NiSkinData block is dying
-	map<IBlock*, Bone>::iterator it;
+	map<IBlock *, Bone>::iterator it;
 	for (it = bone_map.begin(); it != bone_map.end(); ++it) {
 		INodeInternal * node_int = (INodeInternal*)it->first->QueryInterface(NodeInternal);
 		node_int->DecSkinRef(this);
@@ -1836,7 +1887,7 @@ void NiSkinData::CalculateBoneOffsets() {
 
 
 	//Cycle through all bones, calculating their offsets and storing the values
-	map<IBlock*, Bone>::iterator it;
+	map<IBlock *, Bone>::iterator it;
 	for( it = bone_map.begin(); it != bone_map.end(); ++it ) {
 		//--Get Bone Bind Pose--//
 
@@ -1890,7 +1941,7 @@ void NiSkinData::CalculateBoneOffsets() {
  * NiGeomMorpherController methods
  **********************************************************/
 
-string NiGeomMorpherController::asString() {
+string NiGeomMorpherController::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -1985,7 +2036,7 @@ void NiKeyframeData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiKeyframeData::Write( ofstream& file, unsigned int version ) {
+void NiKeyframeData::Write( ofstream& file, unsigned int version ) const {
 
 	//--Rotation--//
 	WriteUInt( uint(rotKeys.size()) , file );
@@ -2036,7 +2087,7 @@ void NiKeyframeData::Write( ofstream& file, unsigned int version ) {
 	}
 }
 
-string NiKeyframeData::asString() {
+string NiKeyframeData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2140,7 +2191,7 @@ void NiColorData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiColorData::Write( ofstream& file, unsigned int version ) {
+void NiColorData::Write( ofstream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -2149,7 +2200,7 @@ void NiColorData::Write( ofstream& file, unsigned int version ) {
 	}
 }
 
-string NiColorData::asString() {
+string NiColorData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2158,7 +2209,7 @@ string NiColorData::asString() {
 		<< "Key Type:  " << _type << endl;
 
 	if (verbose) {
-		vector< Key<Color> >::iterator it;
+		vector< Key<Color> >::const_iterator it;
 		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
 			out << "Key Time:  " <<  it->time << "  Color:  " << it->data.r << ", " << it->data.g << ", " << it->data.b << ", " << it->data.a << endl;
 		}
@@ -2183,7 +2234,7 @@ void NiFloatData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiFloatData::Write( ofstream& file, unsigned int version ) {
+void NiFloatData::Write( ofstream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -2192,7 +2243,7 @@ void NiFloatData::Write( ofstream& file, unsigned int version ) {
 	}
 }
 
-string NiFloatData::asString() {
+string NiFloatData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2201,7 +2252,7 @@ string NiFloatData::asString() {
 		<< "Key Type:  " << _type << endl;
 
 	if (verbose) {
-		vector< Key<float> >::iterator it;
+		vector< Key<float> >::const_iterator it;
 		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
 			out << "Key Time:  " <<  it->time << "  Float Value:  " << it->data << endl;
 		}
@@ -2229,7 +2280,7 @@ void NiStringExtraData::Read( ifstream& in, unsigned int version ) {
 	GetAttr("String Data")->Read( in, version );
 }
 
-void NiStringExtraData::Write( ofstream& out, unsigned int version ) {
+void NiStringExtraData::Write( ofstream& out, unsigned int version ) const {
 	GetAttr("Name")->Write( out, version );
 	GetAttr("Next Extra Data")->Write( out, version );
 
@@ -2243,7 +2294,7 @@ void NiStringExtraData::Write( ofstream& out, unsigned int version ) {
 	string_data->Write( out, version );
 }
 
-string NiStringExtraData::asString() {
+string NiStringExtraData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2310,7 +2361,7 @@ void NiMorphData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiMorphData::Write( ofstream& out, unsigned int version ) {
+void NiMorphData::Write( ofstream& out, unsigned int version ) const {
 	WriteUInt( uint(morphs.size()), out );
 	WriteUInt( vertCount, out );
 
@@ -2353,7 +2404,7 @@ void NiMorphData::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string NiMorphData::asString() {
+string NiMorphData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2428,7 +2479,7 @@ void NiPalette::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiPalette::Write( ofstream& out, unsigned int version ) {
+void NiPalette::Write( ofstream& out, unsigned int version ) const {
 	//Write 5 unknown bytes
 	for (int i = 0; i < 5; ++i) {
 		WriteByte( unknownBytes[i], out );
@@ -2443,7 +2494,7 @@ void NiPalette::Write( ofstream& out, unsigned int version ) {
 }
 
 
-string NiPalette::asString() {
+string NiPalette::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2558,11 +2609,11 @@ void NiSkinPartition::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiSkinPartition::Write( ofstream& file, unsigned int version ) {
+void NiSkinPartition::Write( ofstream& file, unsigned int version ) const {
 
 	WriteUInt( uint(partitions.size()), file );
 
-	vector<SkinPartition>::iterator it;
+	vector<SkinPartition>::const_iterator it;
 	for (it = partitions.begin(); it != partitions.end(); ++it ) {
 		//Write counts
 		WriteUShort( ushort( it->vertexMap.size()), file );
@@ -2620,13 +2671,13 @@ void NiSkinPartition::Write( ofstream& file, unsigned int version ) {
 }
 
 
-string NiSkinPartition::asString() {
+string NiSkinPartition::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
 
 	int count = 0;
-	vector<SkinPartition>::iterator it;
+	vector<SkinPartition>::const_iterator it;
 	for (it = partitions.begin(); it != partitions.end(); ++it ) {
 		count++;
 		//Write counts
@@ -2717,7 +2768,7 @@ void NiPixelData::Read( ifstream& in, unsigned int version ) {
 	in.read( (char *)data, dataSize);
 }
 
-void NiPixelData::Write( ofstream& out, unsigned int version ) {
+void NiPixelData::Write( ofstream& out, unsigned int version ) const {
 	WriteUInt( unknownInt, out );
 	WriteUInt( rMask, out );
 	WriteUInt( gMask, out );
@@ -2744,7 +2795,7 @@ void NiPixelData::Write( ofstream& out, unsigned int version ) {
 	out.write( (char *)data, dataSize);
 }
 
-string NiPixelData::asString() {
+string NiPixelData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2795,7 +2846,7 @@ void NiPosData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiPosData::Write( ofstream& file, unsigned int version ) {
+void NiPosData::Write( ofstream& file, unsigned int version ) const {
 	WriteUInt( uint(_keys.size()), file );
 	NifStream( _type, file );
 
@@ -2804,7 +2855,7 @@ void NiPosData::Write( ofstream& file, unsigned int version ) {
 	}
 }
 
-string NiPosData::asString() {
+string NiPosData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2813,7 +2864,7 @@ string NiPosData::asString() {
 		<< "Key Type:  " << _type << endl;
 
 	if (verbose) {
-		vector< Key<Vector3> >::iterator it;
+		vector< Key<Vector3> >::const_iterator it;
 		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
 			out << "Key Time:  " <<  it->time << "  Position:  " << it->data.x << ", " << it->data.y << ", " << it->data.z << endl;
 		}
@@ -2841,7 +2892,7 @@ void NiTextKeyExtraData::Read( ifstream& file, unsigned int version ) {
 	}
 }
 
-void NiTextKeyExtraData::Write( ofstream& file, unsigned int version ) {
+void NiTextKeyExtraData::Write( ofstream& file, unsigned int version ) const {
 
 	GetAttr("Name")->Write( file, version );
 	GetAttr("Next Extra Data")->Write( file, version );
@@ -2854,7 +2905,7 @@ void NiTextKeyExtraData::Write( ofstream& file, unsigned int version ) {
 	}
 }
 
-string NiTextKeyExtraData::asString() {
+string NiTextKeyExtraData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2865,7 +2916,7 @@ string NiTextKeyExtraData::asString() {
 		<< "Key Count:  " << uint(_keys.size()) << endl;
 
 	if (verbose) {
-		vector< Key<string> >::iterator it;
+		vector< Key<string> >::const_iterator it;
 		for ( it = _keys.begin(); it != _keys.end(); ++it ) {
 			out << "Key Time:  " <<  it->time << "  Key Text:  " << it->data << endl;
 		}
@@ -2901,7 +2952,7 @@ void NiUVData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiUVData::Write( ofstream& out, unsigned int version ) {	
+void NiUVData::Write( ofstream& out, unsigned int version ) const {
 	for (uint i = 0; i < 4; ++i) {
 		WriteUInt( uint(groups[i].keys.size()), out );
 
@@ -2921,7 +2972,7 @@ void NiUVData::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string NiUVData::asString() {
+string NiUVData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -2967,7 +3018,7 @@ void NiVertWeightsExtraData::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiVertWeightsExtraData::Write( ofstream& out, unsigned int version ) {
+void NiVertWeightsExtraData::Write( ofstream& out, unsigned int version ) const {
 	ABlock::Write( out, version );
 
 	WriteUInt( bytes, out );
@@ -2978,7 +3029,7 @@ void NiVertWeightsExtraData::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string NiVertWeightsExtraData::asString() {
+string NiVertWeightsExtraData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -3013,7 +3064,7 @@ void NiVisData ::Read( ifstream& in, unsigned int version ) {
 	}
 }
 
-void NiVisData ::Write( ofstream& out, unsigned int version ) {
+void NiVisData ::Write( ofstream& out, unsigned int version ) const {
 	WriteUInt( uint(keys.size()), out );
 
 	for (uint i = 0; i < keys.size(); ++i) {
@@ -3022,7 +3073,7 @@ void NiVisData ::Write( ofstream& out, unsigned int version ) {
 	}
 }
 
-string NiVisData::asString() {
+string NiVisData::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -3052,7 +3103,7 @@ void UnknownMixIn::Read( ifstream &in, unsigned int version ) {
 	in.read((char*)data, len);
 }
 
-string UnknownMixIn::asString() {
+string UnknownMixIn::asString() const {
 	stringstream out;
 	out.setf(ios::fixed, ios::floatfield);
 	out << setprecision(1);
@@ -3081,7 +3132,7 @@ string UnknownMixIn::asString() {
 	return out.str();
 }
 
-void UnknownMixIn::Write( ofstream& out, unsigned int version ) {
+void UnknownMixIn::Write( ofstream& out, unsigned int version ) const {
 	out.write( (const char*)data, len );
 }
 
diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index 78ff2226..9a8f8a79 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -72,24 +72,24 @@ public:
 
 	//File I/O
 	virtual void Read( ifstream& in, unsigned int version ) = 0;
-	virtual void Write( ofstream& out, unsigned int version ) = 0;	
+	virtual void Write( ofstream& out, unsigned int version ) const = 0;	
 };
 
 class ABlock : public IBlock, public IBlockInternal {
 public:
 	ABlock();
 	~ABlock();
-	void AddAttr( AttrType type, string name, unsigned int first_ver = 0, unsigned int last_ver = 0xFFFFFFFF );
-	attr_ref GetAttr(string attr_name);
-	vector<attr_ref> GetAttrs();
-	int GetBlockNum() { return _block_num; }
-	bool IsControllable() { return false; }
-	bool IsController() { return false; }
-	string asString();
+	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();
-	list<blk_ref> GetLinks();
+	blk_ref GetParent() const;
+	list<blk_ref> GetLinks() const;
 
 	//Reference Counting
 	void AddRef();
@@ -104,6 +104,14 @@ public:
 		}
 	}
 
+	void const * QueryInterface( int id ) const {
+		if ( id == BlockInternal ) {
+			return (void const *)static_cast<IBlockInternal const *>(this);;
+		} else {
+			return NULL;
+		}
+	}
+
 	//--Internal Functions--//
 	void AddParent( blk_ref parent);
 	void RemoveParent( IBlock * match );
@@ -111,7 +119,7 @@ public:
 	void FixUpLinks( const vector<blk_ref> & blocks );
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
+	void Write( ofstream& out, unsigned int version ) const;
 protected:
 	map<string, attr_ref> _attr_map;
 	vector<attr_ref> _attr_vect;
@@ -141,6 +149,7 @@ public:
 	~ANode();
 	void InitAttrs();
 	void * QueryInterface( int id );
+	void const * QueryInterface( int id ) const;
 	void Read( ifstream& in, unsigned int version ) {
 		ABlock::Read( in, version );
 		Matrix44 transform;
@@ -149,11 +158,11 @@ public:
 	}
 
 	//INode Functions
-	Matrix44 GetLocalTransform();
-	Matrix44 GetWorldTransform();
-	Matrix44 GetBindPosition();
-	Matrix44 GetLocalBindPos();
-	void SetBindPosition( Matrix44 & m );
+	Matrix44 GetLocalTransform() const;
+	Matrix44 GetWorldTransform() const;
+	Matrix44 GetBindPosition() const;
+	Matrix44 GetLocalBindPos() const;
+	void SetBindPosition( Matrix44 const & m );
 
 	//INodeInternal Functions
 	void IncSkinRef( IBlock * skin_data );
@@ -247,8 +256,8 @@ public:
 	NiNode();
 	void Init() {}
 	~NiNode() {}
-	string GetBlockType() { return "NiNode"; }
-	string asString();
+	string GetBlockType() const { return "NiNode"; }
+	string asString() const;
 };
 
 /**
@@ -261,7 +270,7 @@ public:
 	void Init() {}
 	~RootCollisionNode() {}
 
-	string GetBlockType() { return "RootCollisionNode"; }
+	string GetBlockType() const { return "RootCollisionNode"; }
 };
 
 /**
@@ -274,7 +283,7 @@ public:
 	void Init() {}
 	~AvoidNode() {}
 
-	string GetBlockType() { return "AvoidNode"; }
+	string GetBlockType() const { return "AvoidNode"; }
 };
 
 /**
@@ -286,7 +295,7 @@ public:
 	void Init() {}
 	~NiBillboardNode() {}
 
-	string GetBlockType() { return "NiBillboardNode"; }
+	string GetBlockType() const { return "NiBillboardNode"; }
 };
 
 /**
@@ -298,7 +307,7 @@ public:
 	void Init() {}
 	~NiBSAnimationNode() {}
 
-	string GetBlockType() { return "NiBSAnimationNode"; }
+	string GetBlockType() const { return "NiBSAnimationNode"; }
 };
 
 /**
@@ -310,7 +319,7 @@ public:
 	void Init() {}
 	~NiBSParticleNode() {}
 
-	string GetBlockType() { return "NiBSParticleNode"; }
+	string GetBlockType() const { return "NiBSParticleNode"; }
 };
 
 /**
@@ -322,7 +331,7 @@ public:
 	void Init() {}
 	~NiLODNode() {}
 
-	string GetBlockType() { return "NiLODNode"; }
+	string GetBlockType() const { return "NiLODNode"; }
 };
 
 /**
@@ -334,7 +343,7 @@ public:
 	void Init() {}
 	~NiZBufferProperty() {}
 
-	string GetBlockType() { return "NiZBufferProperty"; }
+	string GetBlockType() const { return "NiZBufferProperty"; }
 };
 
 /**
@@ -347,7 +356,7 @@ public:
 	void Init() {}
 	~NiShadeProperty() {}
 
-	string GetBlockType() { return "NiShadeProperty"; }
+	string GetBlockType() const { return "NiShadeProperty"; }
 };
 
 /**
@@ -360,7 +369,7 @@ public:
 	void Init() {}
 	~NiWireframeProperty() {}
 
-	string GetBlockType() { return "NiWireframeProperty"; }
+	string GetBlockType() const { return "NiWireframeProperty"; }
 };
 
 /**
@@ -373,7 +382,7 @@ public:
 	void Init() {}
 	~NiDitherProperty() {}
 
-	string GetBlockType() { return "NiDitherProperty"; }
+	string GetBlockType() const { return "NiDitherProperty"; }
 };
 
 /**
@@ -386,7 +395,7 @@ public:
 	void Init() {}
 	~NiSequenceStreamHelper () {}
 
-	string GetBlockType() { return "NiSequenceStreamHelper"; }
+	string GetBlockType() const { return "NiSequenceStreamHelper"; }
 };
 
 /**
@@ -399,7 +408,7 @@ public:
 	void Init() {}
 	~NiVertexColorProperty() {}
 
-	string GetBlockType() { return "NiVertexColorProperty"; }
+	string GetBlockType() const { return "NiVertexColorProperty"; }
 };
 
 
@@ -413,7 +422,7 @@ public:
 	void Init() {}
 	~NiTriShape() {}
 
-	string GetBlockType() { return "NiTriShape"; }
+	string GetBlockType() const { return "NiTriShape"; }
 };
 
 /**
@@ -425,7 +434,7 @@ public:
 	void Init() {}
 	~NiTriStrips() {}
 
-	string GetBlockType() { return "NiTriStrips"; }
+	string GetBlockType() const { return "NiTriStrips"; }
 };
 
 /**
@@ -436,7 +445,7 @@ public:
 	NiTexturingProperty( );
 	void Init() {}
 	~NiTexturingProperty() {}
-	string GetBlockType() { return "NiTexturingProperty"; }
+	string GetBlockType() const { return "NiTexturingProperty"; }
 };
 
 /**
@@ -447,7 +456,7 @@ public:
 	NiSourceTexture();
 	void Init() {}
 	~NiSourceTexture() {}
-	string GetBlockType() { return "NiSourceTexture"; }
+	string GetBlockType() const { return "NiSourceTexture"; }
 };
 
 
@@ -463,9 +472,9 @@ public:
 	~NiPixelData() { if (data != NULL) delete [] data; }
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiPixelData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiPixelData"; }
 
 private:
 	struct MipMap {
@@ -488,7 +497,7 @@ public:
 	NiMaterialProperty();
 	void Init() {}
 	~NiMaterialProperty() {}
-	string GetBlockType() { return "NiMaterialProperty"; };
+	string GetBlockType() const { return "NiMaterialProperty"; };
 };
 
 /**
@@ -499,7 +508,7 @@ public:
 	NiSpecularProperty();
 	void Init() {}
 	~NiSpecularProperty() {}
-	string GetBlockType() { return "NiSpecularProperty"; };
+	string GetBlockType() const { return "NiSpecularProperty"; };
 };
 
 /**
@@ -510,7 +519,7 @@ public:
 	NiStencilProperty();
 	void Init() {}
 	~NiStencilProperty() {}
-	string GetBlockType() { return "NiStencilProperty"; };
+	string GetBlockType() const { return "NiStencilProperty"; };
 };
 
 /**
@@ -521,7 +530,7 @@ public:
 	NiAlphaProperty();
 	void Init() {}
 	~NiAlphaProperty() {}
-	string GetBlockType() { return "NiAlphaProperty"; }
+	string GetBlockType() const { return "NiAlphaProperty"; }
 };
 
 /**
@@ -535,10 +544,11 @@ public:
 	}
 	~AShapeData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 
 	void * QueryInterface( int id );
+	void const * QueryInterface( int id ) const;
 
 	//--IShapeData--//
 	//Counts
@@ -575,8 +585,8 @@ public:
 	}
 	~AParticlesData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 protected:
 	bool hasSizes;
 	short numActive, numValid;
@@ -592,8 +602,8 @@ public:
 	ARotatingParticlesData() {}
 	~ARotatingParticlesData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 protected:
 	bool hasRotations;
 	vector<Quaternion> rotations;
@@ -610,10 +620,10 @@ public:
 	}
 	~NiParticleMeshesData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 
-	string GetBlockType() { return "NiParticleMeshesData"; }
+	string GetBlockType() const { return "NiParticleMeshesData"; }
 protected:
 	
 };
@@ -626,7 +636,7 @@ class NiAutoNormalParticlesData : public AParticlesData {
 public:
 	NiAutoNormalParticlesData() {}
 	~NiAutoNormalParticlesData() {}
-	string GetBlockType() { return "NiAutoNormalParticlesData"; }
+	string GetBlockType() const { return "NiAutoNormalParticlesData"; }
 };
 
 /**
@@ -637,20 +647,21 @@ public:
 	NiTriShapeData() : match_group_mode(false) {}
 	~NiTriShapeData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiTriShapeData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiTriShapeData"; }
 	void * QueryInterface( int id );
+	void const * QueryInterface( int id ) const;
 
 	//--ITriShapeData--//
 	//Counts
-	short GetTriangleCount() { return short(triangles.size()); }
+	short GetTriangleCount() const { return short(triangles.size()); }
 	void SetTriangleCount(int n);
 	//Match Detection
 	void SetMatchDetectionMode(bool choice) { match_group_mode = choice; }
-	bool GetMatchDetectionMode() { return match_group_mode; }
+	bool GetMatchDetectionMode() const { return match_group_mode; }
 	//Getters
-	vector<Triangle> GetTriangles() { return triangles; }
+	vector<Triangle> GetTriangles() const { return triangles; }
 	//Setters
 	void SetTriangles( const vector<Triangle> & in );
 
@@ -667,21 +678,22 @@ public:
 	NiTriStripsData() {}
 	~NiTriStripsData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 
-	string GetBlockType() { return "NiTriStripsData"; }
+	string GetBlockType() const { return "NiTriStripsData"; }
 
 	void * QueryInterface( int id );
+	void const * QueryInterface( int id ) const;
 
 	//--ITriStripsData--//
 	//Counts
-	short GetStripCount();
+	short GetStripCount() const;
 	void SetStripCount(int n);
-	short GetTriangleCount();
+	short GetTriangleCount() const;
 	//Getters
-	vector<short> GetStrip( int index );
-	vector<Triangle> GetTriangles();
+	vector<short> GetStrip( int index ) const;
+	vector<Triangle> GetTriangles() const;
 	//Setter
 	void SetStrip( int index, const vector<short> & in );
 
@@ -697,10 +709,10 @@ public:
 	NiCollisionData() {}
 	~NiCollisionData() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 
-	string GetBlockType() { return "NiCollisionData"; }
+	string GetBlockType() const { return "NiCollisionData"; }
 private:
 	int unknownInt1, collisionType, unknownInt2;
 	byte unknownByte;
@@ -719,7 +731,7 @@ public:
 	NiKeyframeController();
 	void Init() {}
 	~NiKeyframeController() {}
-	string GetBlockType() { return "NiKeyframeController"; }
+	string GetBlockType() const { return "NiKeyframeController"; }
 };
 
 /**
@@ -730,7 +742,7 @@ public:
 	NiLookAtController();
 	void Init() {}
 	~NiLookAtController() {}
-	string GetBlockType() { return "NiLookAtController"; }
+	string GetBlockType() const { return "NiLookAtController"; }
 };
 
 /**
@@ -741,7 +753,7 @@ public:
 	NiAlphaController();
 	void Init() {}
 	~NiAlphaController() {}
-	string GetBlockType() { return "NiAlphaController"; }
+	string GetBlockType() const { return "NiAlphaController"; }
 };
 
 /**
@@ -752,7 +764,7 @@ public:
 	NiFlipController();
 	void Init() {}
 	~NiFlipController() {}
-	string GetBlockType() { return "NiFlipController"; }
+	string GetBlockType() const { return "NiFlipController"; }
 };
 
 /**
@@ -763,7 +775,7 @@ public:
 	NiVisController();
 	void Init() {}
 	~NiVisController() {}
-	string GetBlockType() { return "NiVisController"; }
+	string GetBlockType() const { return "NiVisController"; }
 };
 
 /**
@@ -774,7 +786,7 @@ public:
 	NiMaterialColorController();
 	void Init() {}
 	~NiMaterialColorController() {}
-	string GetBlockType() { return "NiMaterialColorController"; }
+	string GetBlockType() const { return "NiMaterialColorController"; }
 };
 
 /**
@@ -785,7 +797,7 @@ public:
 	NiUVController();
 	void Init() {}
 	~NiUVController() {}
-	string GetBlockType() { return "NiUVController"; }
+	string GetBlockType() const { return "NiUVController"; }
 };
 
 /**
@@ -797,7 +809,7 @@ public:
 	NiPathController();
 	void Init() {}
 	~NiPathController() {}
-	string GetBlockType() { return "NiPathController"; }
+	string GetBlockType() const { return "NiPathController"; }
 };
 
 /**
@@ -809,7 +821,7 @@ public:
 	NiAmbientLight();
 	void Init() {}
 	~NiAmbientLight() {}
-	string GetBlockType() { return "NiAmbientLight"; }
+	string GetBlockType() const { return "NiAmbientLight"; }
 };
 
 /**
@@ -821,7 +833,7 @@ public:
 	NiDirectionalLight();
 	void Init() {}
 	~NiDirectionalLight() {}
-	string GetBlockType() { return "NiDirectionalLight"; }
+	string GetBlockType() const { return "NiDirectionalLight"; }
 };
 
 /**
@@ -833,7 +845,7 @@ public:
 	NiAutoNormalParticles();
 	void Init() {}
 	~NiAutoNormalParticles() {}
-	string GetBlockType() { return "NiAutoNormalParticles"; }
+	string GetBlockType() const { return "NiAutoNormalParticles"; }
 };
 
 /**
@@ -845,7 +857,7 @@ public:
 	NiRotatingParticles();
 	void Init() {}
 	~NiRotatingParticles() {}
-	string GetBlockType() { return "NiRotatingParticles"; }
+	string GetBlockType() const { return "NiRotatingParticles"; }
 }; 
 
 /**
@@ -857,7 +869,7 @@ public:
 	NiTextureEffect();
 	void Init() {}
 	~NiTextureEffect() {}
-	string GetBlockType() { return "NiTextureEffect"; }
+	string GetBlockType() const { return "NiTextureEffect"; }
 }; 
 
 /**
@@ -869,7 +881,7 @@ public:
 	NiCamera();
 	void Init() {}
 	~NiCamera() {}
-	string GetBlockType() { return "NiCamera"; }
+	string GetBlockType() const { return "NiCamera"; }
 }; 
 
 /**
@@ -881,7 +893,7 @@ public:
 	NiParticleMeshes();
 	void Init() {}
 	~NiParticleMeshes() {}
-	string GetBlockType() { return "NiParticleMeshes"; }
+	string GetBlockType() const { return "NiParticleMeshes"; }
 }; 
 
 /**
@@ -893,7 +905,7 @@ public:
 	NiGravity();
 	void Init() {}
 	~NiGravity() {}
-	string GetBlockType() { return "NiGravity"; }
+	string GetBlockType() const { return "NiGravity"; }
 }; 
 
 /**
@@ -905,7 +917,7 @@ public:
 	NiParticleBomb();
 	void Init() {}
 	~NiParticleBomb() {}
-	string GetBlockType() { return "NiParticleBomb"; }
+	string GetBlockType() const { return "NiParticleBomb"; }
 }; 
 
 /**
@@ -917,7 +929,7 @@ public:
 	NiPlanarCollider();
 	void Init() {}
 	~NiPlanarCollider() {}
-	string GetBlockType() { return "NiPlanarCollider"; }
+	string GetBlockType() const { return "NiPlanarCollider"; }
 }; 
 
 /**
@@ -929,7 +941,7 @@ public:
 	NiSphericalCollider();
 	void Init() {}
 	~NiSphericalCollider() {}
-	string GetBlockType() { return "NiSphericalCollider"; }
+	string GetBlockType() const { return "NiSphericalCollider"; }
 }; 
 
 /**
@@ -941,7 +953,7 @@ public:
 	NiParticleGrowFade();
 	void Init() {}
 	~NiParticleGrowFade() {}
-	string GetBlockType() { return "NiParticleGrowFade"; }
+	string GetBlockType() const { return "NiParticleGrowFade"; }
 }; 
 
 /**
@@ -953,7 +965,7 @@ public:
 	NiParticleMeshModifier();
 	void Init() {}
 	~NiParticleMeshModifier() {}
-	string GetBlockType() { return "NiParticleMeshModifier"; }
+	string GetBlockType() const { return "NiParticleMeshModifier"; }
 }; 
 
 /**
@@ -965,7 +977,7 @@ public:
 	NiParticleColorModifier();
 	void Init() {}
 	~NiParticleColorModifier() {}
-	string GetBlockType() { return "NiParticleColorModifier"; }
+	string GetBlockType() const { return "NiParticleColorModifier"; }
 }; 
 
 /**
@@ -977,7 +989,7 @@ public:
 	NiParticleRotation();
 	void Init() {}
 	~NiParticleRotation() {}
-	string GetBlockType() { return "NiParticleRotation"; }
+	string GetBlockType() const { return "NiParticleRotation"; }
 }; 
 
 /**
@@ -991,9 +1003,9 @@ class NiKeyframeData : public AData, public IKeyframeData {
 		~NiKeyframeData() {}
 
 		void Read( ifstream& in, unsigned int version );
-		void Write( ofstream& out, unsigned int version );
-		string asString();
-		string GetBlockType() { return "NiKeyframeData"; }
+		void Write( ofstream& out, unsigned int version ) const;
+		string asString() const;
+		string GetBlockType() const { return "NiKeyframeData"; }
 		
 		void * QueryInterface( int id ) {
 			if ( id == ID_KEYFRAME_DATA ) {
@@ -1002,21 +1014,28 @@ class NiKeyframeData : public AData, public IKeyframeData {
 				return ABlock::QueryInterface( id );
 			}
 		}
+		void const * QueryInterface( int id ) const {
+			if ( id == ID_KEYFRAME_DATA ) {
+				return (void const *)static_cast<IKeyframeData const *>(this);;
+			} else {
+				return ABlock::QueryInterface( id );
+			}
+		}
 
 		//--IKeyframeData Functions--//
-		KeyType GetRotateType() { return rotationType; }
+		KeyType GetRotateType() const { return rotationType; }
 		void SetRotateType( KeyType t ) { rotationType = t; }
-		vector< Key<Quaternion> > GetRotateKeys() { return rotKeys; }
+		vector< Key<Quaternion> > GetRotateKeys() const { return rotKeys; }
 		void SetRotateKeys( vector< Key<Quaternion> > const & keys ) { rotKeys = keys; }
 		//Translate
-		KeyType GetTranslateType() { return translationType; }
+		KeyType GetTranslateType() const { return translationType; }
 		void SetTranslateType( KeyType t ) { translationType = t; }
-		vector< Key<Vector3> > GetTranslateKeys() { return transKeys; }
+		vector< Key<Vector3> > GetTranslateKeys() const { return transKeys; }
 		void SetTranslateKeys( vector< Key<Vector3> > const & keys ) { transKeys = keys; }
 		//Scale
-		KeyType GetScaleType() { return scaleType; }
+		KeyType GetScaleType() const { return scaleType; }
 		void SetScaleType( KeyType t ) { scaleType = t; }
-		vector< Key<float> > GetScaleKeys() { return scaleKeys; }
+		vector< Key<float> > GetScaleKeys() const { return scaleKeys; }
 		void SetScaleKeys( vector< Key<float> > const & keys ) { scaleKeys = keys; }
 
 	private:
@@ -1043,10 +1062,10 @@ public:
 	void Init() {}
 	~NiPalette() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 
-	string GetBlockType() { return "NiPalette"; }
+	string GetBlockType() const { return "NiPalette"; }
 private:
 	byte unknownBytes[5];
 	byte palette[256][4];
@@ -1062,10 +1081,10 @@ public:
 	void Init() {}
 	~NiSkinPartition() {}
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
 
-	string GetBlockType() { return "NiSkinPartition"; }
+	string GetBlockType() const { return "NiSkinPartition"; }
 private:
 	struct SkinPartition {
 		vector<ushort> bones;
@@ -1086,7 +1105,7 @@ private:
 //Non-Public interface to allow NiSkinData to get the bone list read by NiSkinInstance
 class ISkinInstInternal {
 public:
-	virtual vector<int> GetBoneList() = 0;
+	virtual vector<int> GetBoneList() const = 0;
 	virtual void ReadBoneList( ifstream& in ) = 0;
 };
 
@@ -1098,7 +1117,7 @@ public:
 		AddAttr( attr_bones, "Bones" );
 	}
 	~NiSkinInstance() {}
-	string GetBlockType() { return "NiSkinInstance"; }
+	string GetBlockType() const { return "NiSkinInstance"; }
 
 	void * QueryInterface( int id ) {
 		if ( id == SkinInstInternal ) {
@@ -1107,10 +1126,17 @@ public:
 			return ABlock::QueryInterface( id );
 		}
 	}
+	void const * QueryInterface( int id ) const {
+		if ( id == SkinInstInternal ) {
+			return (void const *)static_cast<ISkinInstInternal const *>(this);;
+		} else {
+			return ABlock::QueryInterface( id );
+		}
+	}
 
 	//ISkinInstInternal
 
-	vector<int> GetBoneList() { return bones; }
+	vector<int> GetBoneList() const { return bones; }
 
 	void ReadBoneList( ifstream& in ) {
 		int len = ReadUInt( in );
@@ -1128,7 +1154,7 @@ public:
 	virtual void SetBones( vector<blk_ref> bone_blocks ) = 0;
 	virtual void RepositionTriShape() = 0;
 	virtual void StraightenSkeleton() = 0;
-	virtual void RemoveBoneByPtr( IBlock * bone ) = 0;
+	virtual void RemoveBoneByPtr( blk_ref const & bone ) = 0;
 };
 
 class NiSkinData : public AData, public ISkinData, public ISkinDataInternal {
@@ -1148,22 +1174,23 @@ class NiSkinData : public AData, public ISkinData, public ISkinDataInternal {
 		~NiSkinData();
 
 		void Read( ifstream& in, unsigned int version );
-		void Write( ofstream& out, unsigned int version );
-		string asString();
-		string GetBlockType() { return "NiSkinData"; }
+		void Write( ofstream& out, unsigned int version ) const;
+		string asString() const;
+		string GetBlockType() const { return "NiSkinData"; }
 		void * QueryInterface( int id );
+		void const * QueryInterface( int id ) const;
 
 		//ISkinDataInternal
-		void SetBones( vector<blk_ref> bone_blocks );
+		void SetBones( vector<blk_ref> bone_blocks ); // not vector<blk_ref> const &, since we must cast the blk_ref's into (non-constant) IBlock * pointers
 		void RepositionTriShape();
 		void StraightenSkeleton();
-		void RemoveBoneByPtr( IBlock * bone );
+		void RemoveBoneByPtr( blk_ref const & bone );
 
         //ISkinData
-		vector<blk_ref> GetBones();
-		map<int, float> GetWeights( blk_ref bone );
-		void AddBone( blk_ref bone, map<int, float> in );
-		void RemoveBone( blk_ref bone );
+		vector<blk_ref> GetBones(); // cannot be const, since this changes the reference counts for the bone blocks!
+		map<int, float> GetWeights( blk_ref const & bone ) const;
+		void AddBone( blk_ref const & bone, map<int, float> const & in );
+		void RemoveBone( blk_ref const & bone );
 	private:
 		struct Bone {
 			Matrix33 rotation;
@@ -1179,8 +1206,8 @@ class NiSkinData : public AData, public ISkinData, public ISkinDataInternal {
 		float  scale;
 		int unknownInt;
 		byte unknownByte;
-		map<IBlock*, Bone> bone_map;
-		vector<Bone> bones;		
+		map<IBlock *, Bone> bone_map;
+		vector<Bone> bones;
 };
 
 //-- New Nodes--//
@@ -1191,8 +1218,8 @@ public:
 	void Init() {}
 	~NiGeomMorpherController() {}
 
-	string asString();
-	string GetBlockType() { return "NiGeomMorpherController"; }
+	string asString() const;
+	string GetBlockType() const { return "NiGeomMorpherController"; }
 };
 
 class NiColorData : public AData, public IColorData {
@@ -1201,9 +1228,9 @@ public:
 	~NiColorData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiColorData"; };
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiColorData"; };
 
 	void * QueryInterface( int id ) {
 		if ( id == ID_COLOR_DATA ) {
@@ -1212,11 +1239,18 @@ public:
 			return AData::QueryInterface( id );
 		}
 	}
+	void const * QueryInterface( int id ) const {
+		if ( id == ID_COLOR_DATA ) {
+			return (void const *)static_cast<IColorData const *>(this);;
+		} else {
+			return AData::QueryInterface( id );
+		}
+	}
 
 	//--IColorData Functions--//
-	KeyType GetKeyType() { return _type; }
+	KeyType GetKeyType() const { return _type; }
 	void SetKeyType( KeyType t ) { _type = t; }
-	vector< Key<Color> > GetKeys() { return _keys; }
+	vector< Key<Color> > GetKeys() const { return _keys; }
 	void SetKeys( vector< Key<Color> > const & keys ) { _keys = keys; }
 
 private:
@@ -1234,7 +1268,7 @@ public:
 	}
 	~NiControllerSequence() {}
 
-	string GetBlockType() { return "NiControllerSequence"; }
+	string GetBlockType() const { return "NiControllerSequence"; }
 private:
 	vector< pair< string, blk_ref> > controllers;
 };
@@ -1245,9 +1279,9 @@ public:
 	~NiFloatData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiFloatData"; };
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiFloatData"; };
 
 	void * QueryInterface( int id ) {
 		if ( id == ID_FLOAT_DATA ) {
@@ -1256,11 +1290,18 @@ public:
 			return AData::QueryInterface( id );
 		}
 	}
+	void const * QueryInterface( int id ) const {
+		if ( id == ID_FLOAT_DATA ) {
+			return (void const *)static_cast<IFloatData const *>(this);;
+		} else {
+			return AData::QueryInterface( id );
+		}
+	}
 
 	//--IFloatData Functions--//
-	KeyType GetKeyType() { return _type; }
+	KeyType GetKeyType() const { return _type; }
 	void SetKeyType( KeyType t ) { _type = t; }
-	vector< Key<float> > GetKeys() { return _keys; }
+	vector< Key<float> > GetKeys() const { return _keys; }
 	void SetKeys( vector< Key<float> > const & keys ) { _keys = keys; }
 
 private:
@@ -1276,9 +1317,9 @@ public:
 	~NiStringExtraData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiStringExtraData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiStringExtraData"; }
 };
 
 class NiBooleanExtraData : public AExtraData {
@@ -1288,7 +1329,7 @@ public:
 	}
 	~NiBooleanExtraData() {}
 
-	string GetBlockType() { return "NiBooleanExtraData"; };
+	string GetBlockType() const { return "NiBooleanExtraData"; };
 };
 
 class NiIntegerExtraData : public AExtraData {
@@ -1298,7 +1339,7 @@ public:
 	}
 	~NiIntegerExtraData() {}
 
-	string GetBlockType() { return "NiIntegerExtraData"; };
+	string GetBlockType() const { return "NiIntegerExtraData"; };
 };
 
 class NiMorphData : public AData, public IMorphData {
@@ -1309,9 +1350,9 @@ public:
 	~NiMorphData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiMorphData"; };
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiMorphData"; };
 
 	void * QueryInterface( int id ) {
 		if ( id == ID_MORPH_DATA ) {
@@ -1320,15 +1361,22 @@ public:
 			return ABlock::QueryInterface( id );
 		}
 	}
+	void const * QueryInterface( int id ) const {
+		if ( id == ID_MORPH_DATA ) {
+			return (void const *)static_cast<IMorphData const *>(this);;
+		} else {
+			return ABlock::QueryInterface( id );
+		}
+	}
 
 	//--IMorphData Functions --//
-	int GetVertexCount() { return vertCount; }
+	int GetVertexCount() const { return vertCount; }
 	void SetVertexCount( int n );
-	int GetMorphCount() { return int(morphs.size()); }
+	int GetMorphCount() const { return int(morphs.size()); }
 	void SetMorphCount( int n ) { morphs.resize( n ); }
-	vector< Key<float> > GetMorphKeys( int n ) { return morphs[n].keys; }
-	void SetMorphKeys( int n, vector< Key<float> > & keys ) { morphs[n].keys = keys; }
-	vector<Vector3> GetMorphVerts( int n) { return morphs[n].morph; }
+	vector< Key<float> > GetMorphKeys( int n ) const { return morphs[n].keys; }
+	void SetMorphKeys( int n, vector< Key<float> > const & keys ) { morphs[n].keys = keys; }
+	vector<Vector3> GetMorphVerts( int n) const { return morphs[n].morph; }
 	void SetMorphVerts( int n, const vector<Vector3> & in );
 
 private:
@@ -1350,9 +1398,9 @@ public:
 	~NiPosData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiPosData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiPosData"; }
 
 	void * QueryInterface( int id ) {
 		if ( id == ID_POS_DATA ) {
@@ -1361,11 +1409,18 @@ public:
 			return AData::QueryInterface( id );
 		}
 	}
+	void const * QueryInterface( int id ) const {
+		if ( id == ID_POS_DATA ) {
+			return (void const *)static_cast<IPosData const *>(this);;
+		} else {
+			return AData::QueryInterface( id );
+		}
+	}
 
 	//--IPosData Functions--//
-	KeyType GetKeyType() { return _type; }
+	KeyType GetKeyType() const { return _type; }
 	void SetKeyType( KeyType t ) { _type = t; }
-	vector< Key<Vector3> > GetKeys() { return _keys; }
+	vector< Key<Vector3> > GetKeys() const { return _keys; }
 	void SetKeys( vector< Key<Vector3> > const & keys ) { _keys = keys; }
 
 private:
@@ -1378,7 +1433,7 @@ public:
 	NiRotatingParticlesData() {}
 	~NiRotatingParticlesData() {}
 
-	string GetBlockType() { return "NiRotationparticlesData"; }
+	string GetBlockType() const { return "NiRotationparticlesData"; }
 };
 
 class NiTextKeyExtraData : public AExtraData, public ITextKeyExtraData {
@@ -1389,9 +1444,9 @@ public:
 	~NiTextKeyExtraData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiTextKeyExtraData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiTextKeyExtraData"; }
 
 	void * QueryInterface( int id ) {
 		if ( id == ID_TEXT_KEY_EXTRA_DATA ) {
@@ -1400,9 +1455,16 @@ public:
 			return AExtraData::QueryInterface( id );
 		}
 	}
+	void const * QueryInterface( int id ) const {
+		if ( id == ID_TEXT_KEY_EXTRA_DATA ) {
+			return (void const *)static_cast<ITextKeyExtraData const *>(this);;
+		} else {
+			return AExtraData::QueryInterface( id );
+		}
+	}
 
 	//--ITextKeyExtraData Functions--//
-	virtual vector< Key<string> > GetKeys() { return _keys; }
+	virtual vector< Key<string> > GetKeys() const { return _keys; }
 	virtual void SetKeys( vector< Key<string> > const & keys ) { _keys = keys; }
 
 private:
@@ -1415,9 +1477,9 @@ public:
 	~NiUVData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiUVData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiUVData"; }
 
 private:
 	struct UVGroup {
@@ -1433,9 +1495,9 @@ public:
 	~NiVertWeightsExtraData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiVertWeightsExtraData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiVertWeightsExtraData"; }
 
 private:
 	uint bytes;
@@ -1448,9 +1510,9 @@ public:
 	~NiVisData() {}
 
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return "NiVisData"; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return "NiVisData"; }
 
 private:
 	vector<Key<byte> > keys;
@@ -1464,9 +1526,9 @@ public:
 	}
 	~UnknownMixIn() { if (data != NULL) delete [] data; }
 	void Read( ifstream& in, unsigned int version );
-	void Write( ofstream& out, unsigned int version );
-	string asString();
-	string GetBlockType() { return _block_type; }
+	void Write( ofstream& out, unsigned int version ) const;
+	string asString() const;
+	string GetBlockType() const { return _block_type; }
 
 private:
 	string _block_type;
@@ -1483,7 +1545,7 @@ public:
 		ABlock::Read( in, version );
 		UnknownMixIn::Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) {
+	void Write( ofstream& out, unsigned int version ) const {
 		ABlock::Write( out, version );
 		UnknownMixIn::Write( out, version );
 	}
@@ -1491,7 +1553,7 @@ public:
 		out << ABlock::asString();
 		out << UnknownMixIn::asString();
 	}
-	string GetBlockType() { return UnknownMixIn::GetBlockType(); }
+	string GetBlockType() const { return UnknownMixIn::GetBlockType(); }
 };
 
 class UnknownControllerBlock : public AController, public UnknownMixIn {
@@ -1502,7 +1564,7 @@ public:
 		ABlock::Read( in, version );
 		UnknownMixIn::Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) {
+	void Write( ofstream& out, unsigned int version ) const {
 		ABlock::Write( out, version );
 		UnknownMixIn::Write( out, version );
 	}
@@ -1516,7 +1578,7 @@ public:
 
 		return out.str();
 	}
-	string GetBlockType() { return UnknownMixIn::GetBlockType(); }
+	string GetBlockType() const { return UnknownMixIn::GetBlockType(); }
 };
 
 class UnknownPropertyBlock : public AProperty, public UnknownMixIn {
@@ -1527,7 +1589,7 @@ public:
 		ABlock::Read( in, version );
 		UnknownMixIn::Read( in, version );
 	}
-	void Write( ofstream& out, unsigned int version ) {
+	void Write( ofstream& out, unsigned int version ) const {
 		ABlock::Write( out, version );
 		UnknownMixIn::Write( out, version );
 	}
@@ -1541,7 +1603,7 @@ public:
 
 		return out.str();
 	}
-	string GetBlockType() { return UnknownMixIn::GetBlockType(); }
+	string GetBlockType() const { return UnknownMixIn::GetBlockType(); }
 };
 
 /**
@@ -1552,7 +1614,7 @@ public:
 	NiParticleSystemController();
 	void Init() {}
 	~NiParticleSystemController() {}
-	string GetBlockType() { return "NiParticleSystemController"; }
+	string GetBlockType() const { return "NiParticleSystemController"; }
 };
 
 /**
@@ -1563,7 +1625,7 @@ public:
 	NiBSPArrayController();
 	void Init() {}
 	~NiBSPArrayController() {}
-	string GetBlockType() { return "NiBSPArrayController"; }
+	string GetBlockType() const { return "NiBSPArrayController"; }
 };
 
 #endif
diff --git a/NIF_IO.cpp b/NIF_IO.cpp
index ae0235c6..b823d189 100644
--- a/NIF_IO.cpp
+++ b/NIF_IO.cpp
@@ -104,23 +104,23 @@ int BlockSearch( ifstream& in ) {
 
 //--IO Stream Functions--//
 
-ostream & operator<<(ostream & lh, fVector2 & rh) {
+ostream & operator<<(ostream & lh, fVector2 const & rh) {
 	return lh << "(" << setw(5) << rh[0] << ", " << setw(5) << rh[1] << ")";
 }
 
-ostream & operator<<(ostream & lh, fVector3 & rh) {
+ostream & operator<<(ostream & lh, fVector3 const & rh) {
 	return lh << "(" << setw(5) << rh[0] << ", " << setw(5) << rh[1] << ", " << setw(5) << rh[2] << ")";
 }
 
-ostream & operator<<(ostream & lh, fVector4 & rh) {
+ostream & operator<<(ostream & lh, fVector4 const & rh) {
 	return lh << "(" << setw(5) << rh[0] << ", " << setw(5) << rh[1] << ", " << setw(5) << rh[2] << ", " << setw(5) << rh[3] << ")";
 }
 
-ostream & operator<<(ostream & lh, usVector3 & rh) {
+ostream & operator<<(ostream & lh, usVector3 const & rh) {
 	return lh << "(" << setw(4) << rh[0] << ", " << setw(4) << rh[1] << ", " << setw(4) << rh[2] << ")";
 }
 
-ostream & operator<<(ostream & lh, nifApplyMode & rh) {
+ostream & operator<<(ostream & lh, nifApplyMode const & rh) {
 	switch (int(rh)) {
 		case 0: return lh << "Replace (0)";
 		case 1: return lh << "Decal (1)";
@@ -131,7 +131,7 @@ ostream & operator<<(ostream & lh, nifApplyMode & rh) {
 	return lh;
 }
 
-ostream & operator<<(ostream & lh, nifPixelLayout & rh) {
+ostream & operator<<(ostream & lh, nifPixelLayout const & rh) {
 	switch (int(rh)) {
 		case 0: return lh << "Palettised (0)";
 		case 1: return lh << "16-bit High Color (1)";
@@ -143,7 +143,7 @@ ostream & operator<<(ostream & lh, nifPixelLayout & rh) {
 	return lh;
 }
 
-ostream & operator<<(ostream & lh, nifMipMapFormat & rh) {
+ostream & operator<<(ostream & lh, nifMipMapFormat const & rh) {
 	switch (int(rh)) {
 		case 0: return lh << "No (0)";
 		case 1: return lh << "Yes (1)";
@@ -152,7 +152,7 @@ ostream & operator<<(ostream & lh, nifMipMapFormat & rh) {
 	return lh;
 }
 
-ostream & operator<<(ostream & lh, nifAlphaFormat & rh) {
+ostream & operator<<(ostream & lh, nifAlphaFormat const & rh) {
 	switch (int(rh)) {
 		case 0: return lh << "None (0)";
 		case 1: return lh << "Binary (1)";
@@ -259,7 +259,7 @@ void WriteByte( byte val, ofstream& out ){
 	out.write( (char*)&val, 1 );
 }
 
-void WriteUSVector3( usVector3& vec, ofstream& out ){
+void WriteUSVector3( usVector3 const & vec, ofstream& out ){
 
 	WriteUShort( vec[0], out );
 	WriteUShort( vec[1], out );
@@ -271,20 +271,20 @@ void WriteFloat( float val, ofstream& out ){
 	out.write( reinterpret_cast<char*>(&val), sizeof(val) );
 }
 
-void WriteFVector2( fVector2& fvec, ofstream& out ){
+void WriteFVector2( fVector2 const & fvec, ofstream& out ){
 
 	WriteFloat( fvec[0], out );
 	WriteFloat( fvec[1], out );
 }
 
-void WriteFVector3( fVector3& fvec, ofstream& out ){
+void WriteFVector3( fVector3 const & fvec, ofstream& out ){
 
 	WriteFloat( fvec[0], out );
 	WriteFloat( fvec[1], out );
 	WriteFloat( fvec[2], out );
 }
 
-void WriteFVector4( fVector4& fvec, ofstream& out ){
+void WriteFVector4( fVector4 const & fvec, ofstream& out ){
 
 	WriteFloat( fvec[0], out );
 	WriteFloat( fvec[1], out );
@@ -292,7 +292,7 @@ void WriteFVector4( fVector4& fvec, ofstream& out ){
 	WriteFloat( fvec[3], out );
 }
 
-void WriteString( string val, ofstream& out ) {
+void WriteString( string const & val, ofstream& out ) {
 	WriteUInt( uint(val.size()), out );
 	out.write( val.c_str(), std::streamsize(val.size()) );
 }
@@ -319,7 +319,7 @@ void WriteBlockName( const char* name, uint nameLength, ofstream& out ){
 	out.write( name, nameLength );
 }
 
-ostream & operator<<(ostream & lh, nifIndex & rh) {
+ostream & operator<<(ostream & lh, nifIndex const & rh) {
 	if (rh._index != -1) {
 		lh << "Block " << rh._index;
 	} else {
@@ -328,7 +328,7 @@ ostream & operator<<(ostream & lh, nifIndex & rh) {
 	return lh;
 }
 
-ostream & operator<<(ostream & lh, Str & rh) {
+ostream & operator<<(ostream & lh, Str const & rh) {
 	//Fix string
 	char * s = new char[rh._n + 1];
 	strncpy(s, rh._c, rh._n);
@@ -338,18 +338,18 @@ ostream & operator<<(ostream & lh, Str & rh) {
 	return lh;
 }
 
-ostream & operator<<(ostream & lh, Hex & rh) {
+ostream & operator<<(ostream & lh, Hex const & rh) {
 	return lh << dec << rh._n << " (0x" << hex << uppercase << rh._n << ")" << dec;
 }
 
-ostream & operator<<(ostream & lh, Index & rh) {
+ostream & operator<<(ostream & lh, Index const & rh) {
 	if (int(rh._n) != -1)
 		return lh << "Block " << rh._n;
 	else
 		return lh << "None";
 }
 
-ostream & operator<<(ostream & lh, Bin & rh) {
+ostream & operator<<(ostream & lh, Bin const & rh) {
 	uint x = rh._n;
 	for (uint i = 0; i < rh._w; i++) {
 		if((x & 0x80) !=0) {
@@ -400,31 +400,31 @@ void NifStream( Triangle & val, ifstream& in ) {
 
 
 
-void NifStream( uint & val, ofstream& out ) { WriteUInt( val, out ); }
-void NifStream( ushort & val, ofstream& out ) { WriteUShort( val, out ); }
-void NifStream( byte & val, ofstream& out ) { WriteByte( val, out ); }
-void NifStream( float & val, ofstream& out ) { WriteFloat( val, out ); }
-void NifStream( string & val, ofstream& out ) { WriteString( val, out ); }
-void NifStream( KeyType & val, ofstream& out ) { WriteUInt( val, out ); }
-void NifStream( Vector3 & val, ofstream& out ) {
+void NifStream( uint const & val, ofstream& out ) { WriteUInt( val, out ); }
+void NifStream( ushort const & val, ofstream& out ) { WriteUShort( val, out ); }
+void NifStream( byte const & val, ofstream& out ) { WriteByte( val, out ); }
+void NifStream( float const & val, ofstream& out ) { WriteFloat( val, out ); }
+void NifStream( string const & val, ofstream& out ) { WriteString( val, out ); }
+void NifStream( KeyType const & val, ofstream& out ) { WriteUInt( val, out ); }
+void NifStream( Vector3 const & val, ofstream& out ) {
 	WriteFloat( val.x, out );
 	WriteFloat( val.y, out );
 	WriteFloat( val.z, out );
 };
-void NifStream( Quaternion & val, ofstream& out ) {
+void NifStream( Quaternion const & val, ofstream& out ) {
 	WriteFloat( val.w, out );
 	WriteFloat( val.x, out );
 	WriteFloat( val.y, out );
 	WriteFloat( val.z, out );
 };
-void NifStream( Color & val, ofstream& out ) {
+void NifStream( Color const & val, ofstream& out ) {
 	WriteFloat( val.r, out );
 	WriteFloat( val.g, out );
 	WriteFloat( val.b, out );
 	WriteFloat( val.a, out );
 };
-void NifStream( Triangle & val, ofstream& out ) {
+void NifStream( Triangle const & val, ofstream& out ) {
 	WriteUShort( val.v1, out );
 	WriteUShort( val.v2, out );
 	WriteUShort( val.v3, out );
-};
\ No newline at end of file
+};
diff --git a/NIF_IO.h b/NIF_IO.h
index eaa67538..29ce271f 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -137,7 +137,7 @@ int BlockSearch( ifstream& in );
 class Str {
 public:
 	Str(const char * c, int n) { _c = c; _n = n; }
-	friend ostream & operator<<(ostream & lh, Str & rh);
+	friend ostream & operator<<(ostream & lh, Str const & rh);
 private:
 	const char * _c;
 	uint _n;
@@ -145,44 +145,44 @@ private:
 
 class Hex {
 public:
-	Hex(uint & n) { _n = n; }
-	Hex(ushort & n) { _n = uint(n); }
-	Hex(byte & n) { _n = uint(n); }
-	friend ostream & operator<<(ostream & lh, Hex & rh);
+	Hex(uint const & n) { _n = n; }
+	Hex(ushort const & n) { _n = uint(n); }
+	Hex(byte const & n) { _n = uint(n); }
+	friend ostream & operator<<(ostream & lh, Hex const & rh);
 private:
 	uint _n;
 };
 
 class Index {
 public:
-	Index(uint & n) { _n = n; }
-	Index(ushort & n) { _n = uint(n); }
-	Index(byte & n) { _n = uint(n); }
-	friend ostream & operator<<(ostream & lh, Index & rh);
+	Index(uint const & n) { _n = n; }
+	Index(ushort const & n) { _n = uint(n); }
+	Index(byte const & n) { _n = uint(n); }
+	friend ostream & operator<<(ostream & lh, Index const & rh);
 private:
 	uint _n;
 };
 
 class Bin {
 public:
-	Bin(uint &  n) { _n = n; _w = 32; }
-	Bin(ushort & n) {_n = uint(n); _w = 16; }
-	Bin(byte & n) { _n = uint(n); _w = 8; }
-	friend ostream & operator<<(ostream & lh, Bin & rh);
+	Bin(uint const &  n) { _n = n; _w = 32; }
+	Bin(ushort const & n) {_n = uint(n); _w = 16; }
+	Bin(byte const & n) { _n = uint(n); _w = 8; }
+	friend ostream & operator<<(ostream & lh, Bin const & rh);
 private:
 	uint _n;
 	uint _w;
 };
 
-ostream & operator<<(ostream & lh, fVector2 & rh);
-ostream & operator<<(ostream & lh, fVector3 & rh);
-ostream & operator<<(ostream & lh, fVector4 & rh);
-ostream & operator<<(ostream & lh, usVector3 & rh);
-ostream & operator<<(ostream & lh, nifApplyMode & rh);
+ostream & operator<<(ostream & lh, fVector2 const & rh);
+ostream & operator<<(ostream & lh, fVector3 const & rh);
+ostream & operator<<(ostream & lh, fVector4 const & rh);
+ostream & operator<<(ostream & lh, usVector3 const & rh);
+ostream & operator<<(ostream & lh, nifApplyMode const & rh);
 
-ostream & operator<<(ostream & lh, nifPixelLayout & rh);
-ostream & operator<<(ostream & lh, nifMipMapFormat & rh);
-ostream & operator<<(ostream & lh, nifAlphaFormat & rh);
+ostream & operator<<(ostream & lh, nifPixelLayout const & rh);
+ostream & operator<<(ostream & lh, nifMipMapFormat const & rh);
+ostream & operator<<(ostream & lh, nifAlphaFormat const & rh);
 
 /**
  * Read utility functions
@@ -251,36 +251,36 @@ void WriteUShort( ushort val, ofstream& out );
 
 void WriteByte( byte val, ofstream& out );
 
-void WriteUSVector3( usVector3& fvec, ofstream& out );
+void WriteUSVector3( usVector3 const & fvec, ofstream& out );
 
 void WriteFloat( float val, ofstream& out );
 
-void WriteString( string val, ofstream& out );
+void WriteString( string const & val, ofstream& out );
 
 void WriteBool( bool val, ofstream& out, unsigned int version );
 
-void WriteFVector2( fVector2& fvec, ofstream& out );
+void WriteFVector2( fVector2 const & fvec, ofstream& out );
 
-void WriteFVector3( fVector3& fvec, ofstream& out );
+void WriteFVector3( fVector3 const & fvec, ofstream& out );
 
-void WriteFVector4( fVector4& fvec, ofstream& out );
+void WriteFVector4( fVector4 const & fvec, ofstream& out );
 
 void WriteBlockName( const char* name, uint nameLength, ofstream& out );
 
 //Write
-void NifStream( uint & val, ofstream& out );
-void NifStream( ushort & val, ofstream& out );
-void NifStream( byte & val, ofstream& out );
-void NifStream( float & val, ofstream& out );
-void NifStream( string & val, ofstream& out );
-void NifStream( Vector3 & val, ofstream& out );
-void NifStream( Quaternion & val, ofstream& out );
-void NifStream( KeyType & val, ofstream& out );
-void NifStream( Color & val, ofstream& out );
-void NifStream( Triangle & val, ofstream& out );
+void NifStream( uint const & val, ofstream& out );
+void NifStream( ushort const & val, ofstream& out );
+void NifStream( byte const & val, ofstream& out );
+void NifStream( float const & val, ofstream& out );
+void NifStream( string const & val, ofstream& out );
+void NifStream( Vector3 const & val, ofstream& out );
+void NifStream( Quaternion const & val, ofstream& out );
+void NifStream( KeyType const & val, ofstream& out );
+void NifStream( Color const & val, ofstream& out );
+void NifStream( Triangle const & val, ofstream& out );
 
 template <class T> 
-void NifStream( Key<T> & key, ofstream& file, KeyType type ) {
+void NifStream( Key<T> const & key, ofstream& file, KeyType type ) {
 	WriteFloat( key.time, file );
 
 	//If key type is not 1, 2, or 3, throw an exception
@@ -303,8 +303,8 @@ void NifStream( Key<T> & key, ofstream& file, KeyType type ) {
 }
 
 template <class T>
-void NifStream( vector<T> & val, ofstream& file ) {
-	typename vector<T>::iterator it;
+void NifStream( vector<T> const & val, ofstream& file ) {
+	typename vector<T>::const_iterator it;
 	for ( it = val.begin(); it != val.end(); ++it ) {
 		NifStream( *it, file );
 	}
@@ -316,17 +316,17 @@ class nifIndex {
 public:
 	nifIndex(){}
 	~nifIndex() {};
-	uint GetIndex() { return _index; }
+	uint GetIndex() const { return _index; }
 	uint SetIndex( int index ) {
 		_index = index;
 	}
 	void Read( ifstream &in ) {
 		_index = ReadUInt( in );
 	}
-	void Write( ofstream &out ) {
+	void Write( ofstream &out ) const {
 		WriteUInt( _index, out );
 	}
-	friend ostream & operator<<(ostream & lh, nifIndex & rh);
+	friend ostream & operator<<(ostream & lh, nifIndex const & rh);
 
 private:
 	int _index;
diff --git a/nif_attrs.h b/nif_attrs.h
index 75a6f9a2..93108db1 100644
--- a/nif_attrs.h
+++ b/nif_attrs.h
@@ -46,7 +46,7 @@ const char ATTRERR[] = "Attribute type Missmatch.";
 
 class AAttr : public IAttr {
 public:
-	AAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : _name(name), _owner(owner), _first_ver(first_ver), _last_ver(last_ver) {}
+	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() {}
 	string GetName() const { return _name; }
 	//Getters
@@ -63,28 +63,28 @@ public:
 	//Setters
 	void Set(int) { throw runtime_error(ATTRERR); }
 	void Set(float) { throw runtime_error(ATTRERR); }
-	void Set(Float3&) { throw runtime_error(ATTRERR); }
-	void Set(string&) { throw runtime_error(ATTRERR); }
-	void Set(Matrix33&) { throw runtime_error(ATTRERR); }
-	void Set(blk_ref&) { throw runtime_error(ATTRERR); }
-	void Set(TextureSource&) { throw runtime_error(ATTRERR); }
-	void Set(BoundingBox&) { throw runtime_error(ATTRERR); }
-	void Set(ConditionalInt&) { throw runtime_error(ATTRERR); }
-	void Set(Texture&) { throw runtime_error(ATTRERR); }
+	void Set(Float3 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(TextureSource const &) { throw runtime_error(ATTRERR); }
+	void Set(BoundingBox const &) { throw runtime_error(ATTRERR); }
+	void Set(ConditionalInt const &) { throw runtime_error(ATTRERR); }
+	void Set(Texture const &) { throw runtime_error(ATTRERR); }
 	//Link functions
-	bool HasLinks() { return false; }
-	void AddLink( blk_ref block ) { cout << "AddLink" << endl; throw runtime_error(ATTRERR); }
-	void AddLinks( list<blk_ref> new_links ) { cout << "AddLinkS" << endl; throw runtime_error(ATTRERR); }
+	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 block ) { cout << "RemoveLinks" << endl; throw runtime_error(ATTRERR); }
-	blk_ref FindLink( string block_type ) { cout << "FindLink" << 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( ifstream& in, unsigned int version ) {
 		if ( version >= _first_ver && version <= _last_ver ) {
 			this->ReadAttr( in, version );
 		}
 	}
-	void Write( ofstream& out, unsigned int version ) {
+	void Write( ofstream& out, unsigned int version ) const {
 		if ( version >= _first_ver && version <= _last_ver ) {
 			this->WriteAttr( out, version );
 		}
@@ -92,7 +92,7 @@ public:
 protected:
 	//Internal Read/Write Functions
 	virtual void ReadAttr( ifstream& in, unsigned int version ) = 0;
-	virtual void WriteAttr( ofstream& out, unsigned int version ) = 0;
+	virtual void WriteAttr( ofstream& out, unsigned int version ) const = 0;
 
 	string _name;
 	IBlock * _owner;
@@ -176,11 +176,11 @@ private:
 
 class IntAttr : public AAttr {
 public:
-	IntAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
+	IntAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~IntAttr() {}
 	AttrType GetType() const { return attr_int; }
 	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadUInt( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) { WriteUInt( data, out ); }
+	void WriteAttr( ofstream& out, unsigned int version ) const { WriteUInt( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -198,11 +198,11 @@ protected:
 
 class ShortAttr : public AAttr {
 public:
-	ShortAttr( string 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, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~ShortAttr() {}
 	AttrType GetType() const { return attr_short; }
 	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadUShort( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) { WriteUShort( data, out ); }
+	void WriteAttr( ofstream& out, unsigned int version ) const { WriteUShort( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -220,11 +220,11 @@ private:
 
 class ByteAttr : public AAttr {
 public:
-	ByteAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
+	ByteAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~ByteAttr() {}
 	AttrType GetType() const { return attr_byte; }
 	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadByte( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) { WriteByte( data, out ); }
+	void WriteAttr( ofstream& out, unsigned int version ) const { WriteByte( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -242,11 +242,11 @@ private:
 
 class FloatAttr : public AAttr {
 public:
-	FloatAttr( string 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, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0.0f) {}
 	~FloatAttr() {}
 	AttrType GetType() const { return attr_float; }
 	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadFloat( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) { WriteFloat( data, out ); }
+	void WriteAttr( ofstream& out, unsigned int version ) const { WriteFloat( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -264,7 +264,7 @@ private:
 
 class Float3Attr : public AAttr {
 public:
-	Float3Attr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : AAttr(name, owner, first_ver, last_ver) {
+	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;
@@ -276,7 +276,7 @@ public:
 		data[1] = ReadFloat( in );
 		data[2] = ReadFloat( in );
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteFloat( data[0], out );
 		WriteFloat( data[1], out );
 		WriteFloat( data[2], out );
@@ -298,25 +298,25 @@ private:
 
 class Vector3Attr : public Float3Attr {
 public:
-	Vector3Attr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float3Attr(name, owner, first_ver, last_ver) {}
+	Vector3Attr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float3Attr(name, owner, first_ver, last_ver) {}
 	~Vector3Attr() {}
 	AttrType GetType() const { return attr_vector3; }
 };
 
 class Color3Attr : public Float3Attr {
 public:
-	Color3Attr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver) : Float3Attr(name, owner, first_ver, last_ver) {}
+	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; }
 };
 
 class StringAttr : public AAttr {
 public:
-	StringAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
+	StringAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
 	~StringAttr() {}
 	AttrType GetType() const { return attr_string; }
 	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadString( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) { WriteString( data, out ); }
+	void WriteAttr( ofstream& out, unsigned int version ) const { WriteString( data, out ); }
 	string asString() const { return data; }
 	void Set(string & n) { data = n; }
 private:
@@ -325,7 +325,7 @@ private:
 
 class LinkAttr : public AAttr {
 public:
-	LinkAttr( string 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, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), link( owner ) {}
 	~LinkAttr() {}
 	AttrType GetType() const { return attr_link; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
@@ -341,7 +341,7 @@ public:
 		//Set block index only
 		link.set_index( ReadUInt( in ) );
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteUInt( link.get_index(), out );
 	}
 	string asString() const {
@@ -353,7 +353,7 @@ public:
 
 		return out.str();
 	}
-	bool HasLinks() { return true; }
+	bool HasLinks() const { return true; }
 	list<blk_ref> asLinkList() const { 
 		list<blk_ref> out;
 
@@ -375,11 +375,11 @@ private:
 
 class FlagsAttr : public AAttr {
 public:
-	FlagsAttr( string 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, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ), data(0) {}
 	~FlagsAttr() {}
 	AttrType GetType() const { return attr_flags; }
 	void ReadAttr( ifstream& in, unsigned int version ) { data = ReadUShort( in ); }
-	void WriteAttr( ofstream& out, unsigned int version ) { WriteUShort( data, out ); }
+	void WriteAttr( ofstream& out, unsigned int version ) const { WriteUShort( data, out ); }
 	string asString() const {
 		stringstream out;
 		out.setf(ios::fixed, ios::floatfield);
@@ -404,7 +404,7 @@ private:
 
 class MatrixAttr : public AAttr {
 public:
-	MatrixAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
+	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;
@@ -418,7 +418,7 @@ public:
 			}
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		for (int c = 0; c < 3; ++c) {
 			for (int r = 0; r < 3; ++r) {
 				WriteFloat( data[r][c], out );
@@ -445,7 +445,7 @@ public:
 		//	}
 		//}
 	}
-	void Set( Matrix33 & n ) {
+	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];
@@ -474,7 +474,7 @@ private:
 
 class BoneAttr : public AAttr {
 public:
-	BoneAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	BoneAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~BoneAttr() {}
 	AttrType GetType() const { return attr_bones; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
@@ -485,7 +485,7 @@ public:
 			throw runtime_error ("Attempted to use a bone list attribute on a block that doesn't support it.");
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		ISkinInstInternal * data = (ISkinInstInternal*)_owner->QueryInterface( SkinInstInternal );
 		blk_ref data_blk = _owner->GetAttr("Data")->asLink();
 		if ( data_blk.is_null() == false )  {
@@ -535,10 +535,11 @@ public:
 
 typedef list<lnk_ref> LinkSetList;
 typedef LinkSetList::iterator LinkSetIt;
+typedef LinkSetList::const_iterator LinkSetConstIt;
 
 class LinkGroupAttr : public AAttr {
 public:
-	LinkGroupAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
+	LinkGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {}
 	~LinkGroupAttr() {}
 	AttrType GetType() const { return attr_linkgroup; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
@@ -555,7 +556,7 @@ public:
 				AddLink( blk_ref( index ) );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		//Write the number of links
 		WriteUInt( uint(links.size()), out );
 		//cout << "Link Group Size:  " << uint(links.size()) << endl;
@@ -565,7 +566,7 @@ public:
 		}
 
 		//Write the block indices
-		for (LinkSetIt it = links.begin(); it != links.end(); ++it ) {
+		for (LinkSetConstIt it = links.begin(); it != links.end(); ++it ) {
 			WriteUInt( it->get_index(), out );
 		}
 	}
@@ -584,7 +585,7 @@ public:
 		return out.str();
 	}
 
-	bool HasLinks() { return true; }
+	bool HasLinks() const { return true; }
 
 	list<blk_ref> asLinkList() const { 
 		list<blk_ref> out;
@@ -614,7 +615,7 @@ public:
 		}
 	}
 
-	blk_ref FindLink( string block_type ) {
+	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 )
@@ -627,7 +628,7 @@ public:
 
 	void ClearLinks() { links.clear(); }
 
-	void RemoveLinks( blk_ref block ) {
+	void RemoveLinks( blk_ref const & block ) {
 		//Remove all links that match this block
 		links.remove( lnk_ref( _owner, block ) );
 	}
@@ -637,7 +638,7 @@ private:
 
 class BBoxAttr : public AAttr {
 public:
-	BBoxAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
+	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;
@@ -671,7 +672,7 @@ public:
 			data.radius.z = ReadFloat( in );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteBool( data.isUsed, out, version );
 		if ( data.isUsed ){
 			WriteUInt( data.unknownInt, out );
@@ -719,7 +720,7 @@ private:
 
 class CIntAttr : public AAttr {
 public:
-	CIntAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr( name, owner, first_ver, last_ver ) {
+	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;
 	}
@@ -731,7 +732,7 @@ public:
 			data.unknownInt = ReadUInt( in );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) { 
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteBool( data.isUsed, out, version );
 		if (data.isUsed) {
 			WriteUInt( data.unknownInt, out );
@@ -762,7 +763,7 @@ private:
 
 class VertModeAttr : public IntAttr {
 public:
-	VertModeAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
+	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; }
 
@@ -792,7 +793,7 @@ public:
 
 class LightModeAttr : public IntAttr {
 public:
-	LightModeAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
+	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 {
@@ -829,7 +830,7 @@ public:
 
 class TextureAttr : public LinkAttr {
 public:
-	TextureAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver) {
+	TextureAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver) {
 		memset( &data, 0, sizeof(data) );
 	}
 	~TextureAttr() {}
@@ -865,7 +866,7 @@ public:
 			}
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteBool( data.isUsed, out, version );
 		if ( data.isUsed ) {
 			//Write link
@@ -983,7 +984,7 @@ protected:
 
 class BumpMapAttr : public TextureAttr {
 public:
-	BumpMapAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : TextureAttr(name, owner, first_ver, last_ver) {}
+	BumpMapAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : TextureAttr(name, owner, first_ver, last_ver) {}
 	~BumpMapAttr() {}
 	AttrType GetType() const { return attr_bumpmap; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
@@ -997,7 +998,7 @@ public:
 			data.bmMatrix[1][1] = ReadFloat( in );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		TextureAttr::WriteAttr( out, version );
 
 		if ( data.isUsed ) {
@@ -1047,7 +1048,7 @@ public:
 
 class ApplyModeAttr : public IntAttr {
 public:
-	ApplyModeAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
+	ApplyModeAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
 	~ApplyModeAttr() {}
 	AttrType GetType() const { return attr_applymode; }
 	string asString() const {
@@ -1089,7 +1090,7 @@ public:
 
 class TexSourceAttr : public LinkAttr {
 public:
-	TexSourceAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver) {}
+	TexSourceAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : LinkAttr(name, owner, first_ver, last_ver) {}
 	~TexSourceAttr() {
 		memset(&data, 0, sizeof(data) );
 	}
@@ -1105,7 +1106,7 @@ public:
 			LinkAttr::ReadAttr( in, version );
 		}
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteByte( byte(data.useExternal), out );
 		if ( data.useExternal ) {
 			WriteString( data.fileName, out );
@@ -1144,7 +1145,7 @@ private:
 
 class PixelLayoutAttr : public IntAttr {
 public:
-	PixelLayoutAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
+	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; }
 
@@ -1192,7 +1193,7 @@ public:
 
 class MipMapFormatAttr : public IntAttr {
 public:
-	MipMapFormatAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
+	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; }
 
@@ -1228,7 +1229,7 @@ public:
 
 class AlphaFormatAttr : public IntAttr {
 public:
-	AlphaFormatAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : IntAttr( name, owner, first_ver, last_ver ) {}
+	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; }
 
@@ -1261,13 +1262,13 @@ public:
 
 class ControllerTargetAttr : public AAttr {
 public:
-	ControllerTargetAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	ControllerTargetAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ControllerTargetAttr() {}
 	AttrType GetType() const { return attr_controllertarget; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
 		ReadUInt(in);
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		//WriteUInt( FindTarget()->GetBlockNum(), out );
 		WriteUInt( FindTarget().get_index(), out ); // we need get_index(), GetBlockNum() chokes on null block references
 	}
@@ -1305,19 +1306,19 @@ public:
 		return out.str();
 	}
 	blk_ref asLink() const { return FindTarget(); }
-	void Set(blk_ref&) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
+	void Set(blk_ref const &) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
 
 };
 
 class SkeletonRootAttr : public AAttr {
 public:
-	SkeletonRootAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	SkeletonRootAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~SkeletonRootAttr() {}
 	AttrType GetType() const { return attr_skeletonroot; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
 		original_root = ReadUInt( in );  //Read data but do nothing with it
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteUInt( FindRoot().get_index(), out );
 	}
 	blk_ref FindRoot() const {
@@ -1361,7 +1362,7 @@ public:
 		return out.str();
 	}
 	blk_ref asLink() const { return FindRoot(); }
-	void Set(blk_ref&) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
+	void Set(blk_ref const &) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
 
 private:
 	int original_root;
@@ -1369,13 +1370,13 @@ private:
 
 class ParentAttr : public AAttr {
 public:
-	ParentAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	ParentAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ParentAttr() {}
 	AttrType GetType() const { return attr_parent; }
 	void ReadAttr( ifstream& in, unsigned int version ) {
 		ReadUInt(in);
 	}
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteUInt( _owner->GetParent()->GetBlockNum(), out );
 	}
 	string asString() const {
@@ -1388,12 +1389,12 @@ public:
 		return out.str();
 	}
 	blk_ref asLink() const { return _owner->GetParent(); }
-	void Set(blk_ref&) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
+	void Set(blk_ref const &) { throw runtime_error("The attribute you tried to set is calculated automatically.  You cannot change it directly."); }
 };
 
 class ParticleGroupAttr : public AAttr {
 public:
-	ParticleGroupAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	ParticleGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~ParticleGroupAttr() {}
 	AttrType GetType() const { return attr_particlegroup; }
 
@@ -1413,7 +1414,7 @@ public:
 		}
 	}
 
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteUShort( num_particles, out );
 		WriteUShort( num_valid, out );
 
@@ -1466,7 +1467,7 @@ private:
 
 class LODRangeGroupAttr : public AAttr {
 public:
-	LODRangeGroupAttr( string name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
+	LODRangeGroupAttr( string const & name, IBlock * owner, unsigned int first_ver, unsigned int last_ver ) : AAttr(name, owner, first_ver, last_ver) {}
 	~LODRangeGroupAttr() {}
 	AttrType GetType() const { return attr_lodrangegroup; }
 
@@ -1479,7 +1480,7 @@ public:
 		}
 	}
 
-	void WriteAttr( ofstream& out, unsigned int version ) {
+	void WriteAttr( ofstream& out, unsigned int version ) const {
 		WriteUInt( uint(ranges.size()), out );
 
 		for ( uint i = 0; i < ranges.size(); ++i ) {
diff --git a/nif_math.cpp b/nif_math.cpp
index 3eb496f8..64f9658f 100644
--- a/nif_math.cpp
+++ b/nif_math.cpp
@@ -33,14 +33,14 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 #include "nif_math.h"
 
-void PrintMatrix( Matrix33 & m, ostream & out ) {
+void PrintMatrix( Matrix33 const & m, ostream & out ) {
 	out << endl
 		<< "      |" << setw(8) << m[0][0] << "," << setw(8) << m[0][1] << "," << setw(8) << m[0][2] << " |" << endl
 		<< "      |" << setw(8) << m[1][0] << "," << setw(8) << m[1][1] << "," << setw(8) << m[1][2] << " |" << endl
 		<< "      |" << setw(8) << m[2][0] << "," << setw(8) << m[2][1] << "," << setw(8) << m[2][2] << " |" <<endl;
 }
 
-Vector3 MultVector3( Vector3 & a, Vector3 & b ) {
+Vector3 MultVector3( Vector3 const & a, Vector3 const & b ) {
 	Vector3 answer;
 	answer.x = a.y * b.z - a.z * b.y;
 	answer.y = a.z * b.x - a.x * b.z;
@@ -64,7 +64,7 @@ void SetIdentity44( Matrix44 & m ) {
 
 //Vector3 MatrixToEuler( Matrix33 & m ) {}
 
-Quaternion MatrixToQuat( Matrix33 & m ) {
+Quaternion MatrixToQuat( Matrix33 const & m ) {
 	Quaternion quat;
 	float tr, s, q[4];
 	int i, j, k;
@@ -108,7 +108,7 @@ Quaternion MatrixToQuat( Matrix33 & m ) {
 	return quat;
 }
 
-Matrix33 MultMatrix33( Matrix33 & a, Matrix33 & b ) {
+Matrix33 MultMatrix33( Matrix33 const & a, Matrix33 const & b ) {
 	Matrix33 result;
 	for (int i = 0; i < 3; i++) {
 		for (int j = 0; j < 3; j++) {
@@ -122,7 +122,7 @@ Matrix33 MultMatrix33( Matrix33 & a, Matrix33 & b ) {
 	return result;
 }
 
-Matrix44 MultMatrix44( Matrix44 & a, Matrix44 & b ) {
+Matrix44 MultMatrix44( Matrix44 const & a, Matrix44 const & b ) {
 	Matrix44 result;
 	for (int i = 0; i < 4; i++) {
 		for (int j = 0; j < 4; j++) {
@@ -136,13 +136,13 @@ Matrix44 MultMatrix44( Matrix44 & a, Matrix44 & b ) {
 	return result;
 }
 
-float DetMatrix33( Matrix33 & m ) {
+float DetMatrix33( Matrix33 const & m ) {
 	return  m[0][0]*(m[1][1]*m[2][2]-m[1][2]*m[2][1])
 		  - m[0][1]*(m[1][0]*m[2][2]-m[1][2]*m[2][0])
 		  + m[0][2]*(m[1][0]*m[2][1]-m[1][1]*m[2][0]);
 }
 
-float DetMatrix44( Matrix44 & m ) {
+float DetMatrix44( Matrix44 const & m ) {
 	Matrix33 sub1(
 		m[1][1], m[1][2], m[1][3],
 		m[2][1], m[2][2], m[2][3],
@@ -173,7 +173,7 @@ float DetMatrix44( Matrix44 & m ) {
 	      - m[0][3] * DetMatrix33( sub4 );
 }
 
-float AdjMatrix44(Matrix44 & m, int skip_r, int skip_c) {
+float AdjMatrix44(Matrix44 const & m, int skip_r, int skip_c) {
 	Matrix33 sub;
 	int i = 0, j = 0;
 	for (int r = 0; r < 4; r++) {
@@ -192,7 +192,7 @@ float AdjMatrix44(Matrix44 & m, int skip_r, int skip_c) {
 	return pow(-1.0f, float(skip_r + skip_c)) * DetMatrix33( sub );
 }
 
-Matrix44 InverseMatrix44( Matrix44 & m ) {
+Matrix44 InverseMatrix44( Matrix44 const & m ) {
 	Matrix44 result;
 	float det = DetMatrix44(m);
 	for (int r = 0; r < 4; r++) {
@@ -203,7 +203,7 @@ Matrix44 InverseMatrix44( Matrix44 & m ) {
 	return result;
 }
 
-void QuatToMatrix( Quaternion & quat, ostream & out ) {
+void QuatToMatrix( Quaternion const & quat, ostream & out ) {
 	Matrix33 m;
 
 	float w = quat.w;
@@ -240,7 +240,7 @@ void QuatToMatrix( Quaternion & quat, ostream & out ) {
 		<< "         Z:  " << atan2( m[0][1], m[0][0] ) / pi * 180.0 << endl;
 }
 
-void QuatToEuler( Quaternion & quat, ostream & out ) {
+void QuatToEuler( Quaternion const & quat, ostream & out ) {
 	float w = quat.w;
 	float x = quat.x;
 	float y = quat.y;
diff --git a/nif_math.h b/nif_math.h
index 67d53ef6..b07db031 100644
--- a/nif_math.h
+++ b/nif_math.h
@@ -44,18 +44,18 @@ using namespace std;
 //	float w, x, y, z;
 //};
 
-void QuatToMatrix( Quaternion & quat, ostream & out );
-void QuatToEuler( Quaternion & quat, ostream & out );
-Vector3 MultVector3( Vector3 & a, Vector3 & b);
-Matrix33 MultMatrix33( Matrix33 & a, Matrix33 & b );
-Matrix44 MultMatrix44( Matrix44 & a, Matrix44 & b );
-float DetMatrix33( Matrix33 & m );
-float DetMatrix44( Matrix44 & m );
-float AdjMatrix44( Matrix44 & m, int r, int c );
-Matrix44 InverseMatrix44( Matrix44 & m );
+void QuatToMatrix( Quaternion const & quat, ostream & out );
+void QuatToEuler( Quaternion const & quat, ostream & out );
+Vector3 MultVector3( Vector3 const & a, Vector3 const & b);
+Matrix33 MultMatrix33( Matrix33 const & a, Matrix33 const & b );
+Matrix44 MultMatrix44( Matrix44 const & a, Matrix44 const & b );
+float DetMatrix33( Matrix33 const & m );
+float DetMatrix44( Matrix44 const & m );
+float AdjMatrix44( Matrix44 const & m, int r, int c );
+Matrix44 InverseMatrix44( Matrix44 const & m );
 void SetIdentity33( Matrix33 & m );
 void SetIdentity44( Matrix44 & m );
-void PrintMatrix33( Matrix33 & m, ostream & out );
-Quaternion MatrixToQuat( Matrix33 & m );
+void PrintMatrix33( Matrix33 const & m, ostream & out );
+Quaternion MatrixToQuat( Matrix33 const & m );
 
 #endif
diff --git a/niflib.cpp b/niflib.cpp
index 123a5c9d..d9c68cf6 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -49,9 +49,9 @@ map<string, blk_factory_func> global_block_map;
 unsigned int blocks_in_memory = 0;
 
 //Utility Functions
-void ReorderNifTree( vector<blk_ref> & blk_list, blk_ref block );
-void BuildUpBindPositions( blk_ref block );
-blk_ref FindRoot( vector<blk_ref> & blocks );
+void ReorderNifTree( vector<blk_ref> & blk_list, blk_ref const & block );
+void BuildUpBindPositions( blk_ref const & block );
+blk_ref FindRoot( vector<blk_ref> const & blocks );
 void RegisterBlockFactories ();
 
 //--Function Bodies--//
@@ -83,13 +83,13 @@ blk_ref CreateBlock( string block_type ) {
 }
 
 //Reads the given file by file name and returns a reference to the root block
-blk_ref ReadNifTree( string file_name ) {
+blk_ref ReadNifTree( string const & file_name ) {
 	//Read block list
 	vector<blk_ref> blocks = ReadNifList( file_name );
 	return FindRoot( blocks );
 }
 
-blk_ref FindRoot( vector<blk_ref> & blocks ) {
+blk_ref FindRoot( vector<blk_ref> const & blocks ) {
 	//--Look for a NiNode that has no parents--//
 
 	//Find the first Node
@@ -114,7 +114,7 @@ blk_ref FindRoot( vector<blk_ref> & blocks ) {
 }
 
 //Reads the given file by file name and returns a vector of block references
-vector<blk_ref> ReadNifList( string file_name ) {
+vector<blk_ref> ReadNifList( string const & file_name ) {
 
 	//--Open File--//
 	ifstream in( file_name.c_str(), ifstream::binary );
@@ -323,7 +323,7 @@ vector<blk_ref> ReadNifList( string file_name ) {
 }
 
 // Writes a valid Nif File given a file name, a pointer to the root block of a file tree
-void WriteRawNifTree( string file_name, blk_ref & root_block, unsigned int version ) {
+void WriteRawNifTree( string const & file_name, blk_ref const & root_block, unsigned int version ) {
 	// Walk tree, resetting all block numbers
 	//int block_count = ResetBlockNums( 0, root_block );
 	
@@ -378,7 +378,7 @@ void WriteRawNifTree( string file_name, blk_ref & root_block, unsigned int versi
 	out.close();
 }
 
-void ReorderNifTree( vector<blk_ref> & blk_list, blk_ref block ) {
+void ReorderNifTree( vector<blk_ref> & blk_list, blk_ref const & block ) {
 	//Get internal interface
 	IBlockInternal * bk_intl = (IBlockInternal*)block->QueryInterface( BlockInternal );
 
@@ -414,7 +414,7 @@ void ReorderNifTree( vector<blk_ref> & blk_list, blk_ref block ) {
 //	
 //}
 
-void BuildUpBindPositions( blk_ref block ) {
+void BuildUpBindPositions( blk_ref const & block ) {
 
 	//Return if this is not a node
 	INode * blk_node = (INode*)block->QueryInterface(ID_NODE);
@@ -449,7 +449,7 @@ void BuildUpBindPositions( blk_ref block ) {
 }
 
 // Searches for the first block in the hierarchy of type block_name.
-blk_ref SearchNifTree( blk_ref & root_block, string block_name ) {
+blk_ref SearchNifTree( blk_ref const & root_block, string const & block_name ) {
 	if ( root_block->GetBlockType() == block_name ) return root_block;
 	list<blk_ref> links = root_block->GetLinks();
 	for (list <blk_ref>::iterator it = links.begin(); it != links.end(); ++it) {
@@ -465,31 +465,35 @@ blk_ref SearchNifTree( blk_ref & root_block, string block_name ) {
 };
 
 // Returns all blocks in the tree of type block_name.
-list<blk_ref> SearchAllNifTree( blk_ref & root_block, string block_name ) {
+list<blk_ref> SearchAllNifTree( blk_ref const & root_block, string block_name ) {
 	list<blk_ref> result;
 	if ( root_block->GetBlockType() == block_name ) result.push_back( root_block );
 	list<blk_ref> links = root_block->GetLinks();
 	for (list<blk_ref>::iterator it = links.begin(); it != links.end(); ++it ) {
-		if ( it->is_null() == false && (*it)->GetParent() == root_block )
-			result.merge( SearchAllNifTree( *it, block_name ) );
+		if ( it->is_null() == false && (*it)->GetParent() == root_block ) {
+			list<blk_ref> childresult = SearchAllNifTree( *it, block_name );
+			result.merge( childresult );
+		};
 	};
 	return result;
 };
 
-list<blk_ref> GetNifTree( blk_ref & root_block ) {
+list<blk_ref> GetNifTree( blk_ref const & root_block ) {
 	list<blk_ref> result;
 	result.push_back( root_block );
 	list<blk_ref> links = root_block->GetLinks();
 	for (list<blk_ref>::iterator it = links.begin(); it != links.end(); ++it ) {
-		if ( it->is_null() == false && (*it)->GetParent() == root_block )
-			result.merge( GetNifTree( *it ) );
+		if ( it->is_null() == false && (*it)->GetParent() == root_block ) {
+			list<blk_ref> childresult = GetNifTree( *it );
+			result.merge( childresult );
+		};
 	};
 	return result;
 };
 
 // Writes valid XNif & XKf Files given a file name, and a pointer to the root block of the Nif file tree.
 // (XNif and XKf file blocks are automatically extracted from the Nif tree if there are animation groups.)
-void WriteNifTree( string file_name, blk_ref & root_block, unsigned int version ) {
+void WriteNifTree( string const & file_name, blk_ref const & root_block, unsigned int version ) {
 	// Write the full Nif file.
 	WriteRawNifTree( file_name, root_block, version );
 	
@@ -518,7 +522,7 @@ void WriteNifTree( string file_name, blk_ref & root_block, unsigned int version
 		blk_ref xkf_txtkey_block = CreateBlock("NiTextKeyExtraData");
 		xkf_root["Extra Data"] = xkf_txtkey_block;
 		
-		ITextKeyExtraData *itxtkey_block = QueryTextKeyExtraData(txtkey_block);
+		ITextKeyExtraData const *itxtkey_block = QueryTextKeyExtraData(txtkey_block);
 		ITextKeyExtraData *ixkf_txtkey_block = QueryTextKeyExtraData(xkf_txtkey_block);
 		ixkf_txtkey_block->SetKeys(itxtkey_block->GetKeys());
 		
@@ -532,7 +536,7 @@ void WriteNifTree( string file_name, blk_ref & root_block, unsigned int version
 		};
 		
 		blk_ref last_block = xkf_txtkey_block;
-		for ( list<blk_ref>::iterator it = nodes.begin(); it != nodes.end(); ++it ) {
+		for ( list<blk_ref>::const_iterator it = nodes.begin(); it != nodes.end(); ++it ) {
 			blk_ref nodextra = CreateBlock("NiStringExtraData");
 			nodextra["String Data"] = (*it)["Name"]->asString();
 			last_block["Next Extra Data"] = nodextra;
@@ -541,7 +545,7 @@ void WriteNifTree( string file_name, blk_ref & root_block, unsigned int version
 		
 		// Add controllers & controller data.
 		last_block = xkf_root;
-		for ( list<blk_ref>::iterator it = nodes.begin(); it != nodes.end(); ++it ) {
+		for ( list<blk_ref>::const_iterator it = nodes.begin(); it != nodes.end(); ++it ) {
 			blk_ref controller = (*it)->GetAttr("Controller")->asLink();
 			blk_ref xkf_controller = CreateBlock("NiKeyframeController");
 			xkf_controller["Flags"] = controller["Flags"]->asInt();
@@ -552,8 +556,8 @@ void WriteNifTree( string file_name, blk_ref & root_block, unsigned int version
 			
 			blk_ref xkf_data = CreateBlock("NiKeyframeData");
 			xkf_controller["Data"] = xkf_data;
-			IKeyframeData *ikfdata = QueryKeyframeData(controller["Data"]->asLink());
-			IKeyframeData *ixkfdata = QueryKeyframeData(xkf_controller["Data"]->asLink());
+			IKeyframeData const *ikfdata = QueryKeyframeData(controller["Data"]->asLink());
+			IKeyframeData *ixkfdata = QueryKeyframeData(xkf_data);
 			ixkfdata->SetRotateType(ikfdata->GetRotateType());
 			ixkfdata->SetTranslateType(ikfdata->GetTranslateType());
 			ixkfdata->SetScaleType(ikfdata->GetScaleType());
@@ -586,11 +590,11 @@ unsigned int BlocksInMemory() {
 
 //--Attribute Reference Functions--//
 
-attr_ref::operator blk_ref() { return _attr->asLink(); }
-attr_ref::operator TextureSource() { return _attr->asTextureSource(); }
-attr_ref::operator BoundingBox() { return _attr->asBoundingBox(); }
-attr_ref::operator ConditionalInt() { return _attr->asConditionalInt(); }
-attr_ref::operator Texture() { return _attr->asTexture(); }
+attr_ref::operator blk_ref() const { return _attr->asLink(); }
+attr_ref::operator TextureSource() const { return _attr->asTextureSource(); }
+attr_ref::operator BoundingBox() const { return _attr->asBoundingBox(); }
+attr_ref::operator ConditionalInt() const { return _attr->asConditionalInt(); }
+attr_ref::operator Texture() const { return _attr->asTexture(); }
 
 //--Query Functions--//
 
@@ -598,42 +602,86 @@ IShapeData * QueryShapeData( blk_ref & block ) {
 	return (IShapeData*)block->QueryInterface( ID_SHAPE_DATA );
 }
 
+IShapeData const * QueryShapeData( blk_ref const & block ) {
+	return (IShapeData const *)block->QueryInterface( ID_SHAPE_DATA );
+}
+
 ITriShapeData * QueryTriShapeData( blk_ref & block ) {
 	return (ITriShapeData*)block->QueryInterface( ID_TRI_SHAPE_DATA );
 }
 
+ITriShapeData const * QueryTriShapeData( blk_ref const & block ) {
+	return (ITriShapeData const *)block->QueryInterface( ID_TRI_SHAPE_DATA );
+}
+
 ISkinData * QuerySkinData( blk_ref & block ) {
 	return (ISkinData*)block->QueryInterface( ID_SKIN_DATA );
 }
 
+ISkinData const * QuerySkinData( blk_ref const & block ) {
+	return (ISkinData const *)block->QueryInterface( ID_SKIN_DATA );
+}
+
 INode * QueryNode( blk_ref & block ) {
 	return (INode*)block->QueryInterface( ID_NODE );
 }
 
+INode const * QueryNode( blk_ref const & block ) {
+	return (INode const *)block->QueryInterface( ID_NODE );
+}
+
 IKeyframeData * QueryKeyframeData( blk_ref & block ) {
 	return (IKeyframeData*)block->QueryInterface( ID_KEYFRAME_DATA );
 }
 
+IKeyframeData const * QueryKeyframeData( blk_ref const & block ) {
+	return (IKeyframeData const *)block->QueryInterface( ID_KEYFRAME_DATA );
+}
+
 ITextKeyExtraData * QueryTextKeyExtraData ( blk_ref & block ) {
 	return (ITextKeyExtraData*)block->QueryInterface( ID_TEXT_KEY_EXTRA_DATA );
 }
 
+ITextKeyExtraData const * QueryTextKeyExtraData ( blk_ref const & block ) {
+	return (ITextKeyExtraData const *)block->QueryInterface( ID_TEXT_KEY_EXTRA_DATA );
+}
+
 IMorphData * QueryMorphData ( blk_ref & block ) {
 	return (IMorphData*)block->QueryInterface( ID_MORPH_DATA );
 }
 
+IMorphData const * QueryMorphData ( blk_ref const & block ) {
+	return (IMorphData const *)block->QueryInterface( ID_MORPH_DATA );
+}
+
 ITriStripsData * QueryTriStripsData ( blk_ref & block ) {
 	return (ITriStripsData*)block->QueryInterface( ID_TRI_STRIPS_DATA );
 }
 
+ITriStripsData const * QueryTriStripsData ( blk_ref const & block ) {
+	return (ITriStripsData const *)block->QueryInterface( ID_TRI_STRIPS_DATA );
+}
+
 IColorData * QueryColorData ( blk_ref & block ) {
 	return (IColorData*)block->QueryInterface( ID_COLOR_DATA );
 }
 
+IColorData const * QueryColorData ( blk_ref const & block ) {
+	return (IColorData const *)block->QueryInterface( ID_COLOR_DATA );
+}
+
 IFloatData * QueryFloatData ( blk_ref & block ) {
-	return (IFloatData*)block->QueryInterface( ID_FLOAT_DATA );
+	return (IFloatData *)block->QueryInterface( ID_FLOAT_DATA );
+}
+
+IFloatData const * QueryFloatData ( blk_ref const & block ) {
+	return (IFloatData const *)block->QueryInterface( ID_FLOAT_DATA );
 }
 
 IPosData * QueryPosData ( blk_ref & block ) {
 	return (IPosData*)block->QueryInterface( ID_POS_DATA );
-}
\ No newline at end of file
+}
+
+IPosData const * QueryPosData ( blk_ref const & block ) {
+	return (IPosData const *)block->QueryInterface( ID_POS_DATA );
+}
diff --git a/niflib.h b/niflib.h
index 5ed6c022..a3c724b3 100644
--- a/niflib.h
+++ b/niflib.h
@@ -119,16 +119,16 @@ enum KeyType { LINEAR_KEY = 1, QUADRATIC_KEY = 2, TBC_KEY = 3, XYZ_ROTATION_KEY
 //--Main Functions--//
 
 //Reads the given file by file name and returns a vector of block references
-vector<blk_ref> ReadNifList( string file_name );
+vector<blk_ref> ReadNifList( string const & file_name );
 
 //Reads the given file by file name and returns a reference to the root block
-blk_ref ReadNifTree( string file_name );
+blk_ref ReadNifTree( string const & file_name );
 
 //Writes a valid Nif File given a file name, a pointer to the root block of a file tree
-void WriteNifTree( string file_name, blk_ref & root_block, unsigned int version = VER_4_0_0_2 );
+void WriteNifTree( string const & file_name, blk_ref const & root_block, unsigned int version = VER_4_0_0_2 );
 
 // Returns list of all blocks in the tree rooted by root block.
-list<blk_ref> GetNifTree( blk_ref & root_block );
+list<blk_ref> GetNifTree( blk_ref const & root_block );
 
 ////Returns the NIF spec version of a file, given a file name.
 //string GetFileVersion(string file_name);
@@ -145,16 +145,27 @@ unsigned int BlocksInMemory();
 //--Query Functions--//
 // These are shorthands for using QueryInterface, and required for scripting languages
 IShapeData * QueryShapeData( blk_ref & block );
+IShapeData const * QueryShapeData( blk_ref const & block );
 ITriShapeData * QueryTriShapeData( blk_ref & block );
+ITriShapeData const * QueryTriShapeData( blk_ref const & block );
 ISkinData * QuerySkinData( blk_ref & block );
+ISkinData const * QuerySkinData( blk_ref const & block );
 INode * QueryNode( blk_ref & block );
+INode const * QueryNode( blk_ref const & block );
 IKeyframeData * QueryKeyframeData( blk_ref & block );
+IKeyframeData const * QueryKeyframeData( blk_ref const & block );
 ITextKeyExtraData * QueryTextKeyExtraData ( blk_ref & block );
+ITextKeyExtraData const * QueryTextKeyExtraData ( blk_ref const & block );
 IMorphData * QueryMorphData ( blk_ref & block );
+IMorphData const * QueryMorphData ( blk_ref const & block );
 ITriStripsData * QueryTriStripsData ( blk_ref & block );
+ITriStripsData const * QueryTriStripsData ( blk_ref const & block );
 IColorData * QueryColorData ( blk_ref & block );
+IColorData const * QueryColorData ( blk_ref const & block );
 IFloatData * QueryFloatData ( blk_ref & block );
+IFloatData const * QueryFloatData ( blk_ref const & block );
 IPosData * QueryPosData ( blk_ref & block );
+IPosData const * QueryPosData ( blk_ref const & block );
 
 //--Simple Structures--//
 
@@ -340,6 +351,9 @@ struct Float4 {
 	float & operator[](int n) {
 		return data[n];
 	}
+	float operator[](int n) const {
+		return data[n];
+	}
 	Float4() {}
 	Float4( float f1, float f2, float f3, float f4 ) {
 		data[0] = f1;
@@ -371,6 +385,9 @@ struct Matrix44 {
 	Float4 & operator[](int n) {
 		return rows[n];
 	}
+	Float4 const & operator[](int n) const {
+		return rows[n];
+	}
 	Matrix44() {}
 	Matrix44(
 		float m11, float m12, float m13, float m14,
@@ -462,25 +479,26 @@ public:
 	IBlock( ){}
 	virtual ~IBlock() {}
 
-	virtual int GetBlockNum() = 0;
-	virtual blk_ref GetParent() = 0;
-	virtual string asString() = 0;
-	virtual string GetBlockType() = 0;
-	virtual bool IsControllable() = 0;
-	virtual bool IsController() = 0;
+	virtual int GetBlockNum() const = 0;
+	virtual blk_ref GetParent() const = 0;
+	virtual string asString() const = 0;
+	virtual string GetBlockType() const = 0;
+	virtual bool IsControllable() const = 0;
+	virtual bool IsController() const = 0;
 
 	//Attribute Functions
-	virtual attr_ref GetAttr(string attr_name) = 0;
-	virtual vector<attr_ref> GetAttrs() = 0;
+	virtual attr_ref GetAttr(string const & attr_name) const = 0;
+	virtual vector<attr_ref> GetAttrs() const = 0;
 
 	//Link Functions
-	virtual list<blk_ref> GetLinks() = 0;
+	virtual list<blk_ref> GetLinks() const = 0;
 
 	//To check for specialized Interfaces
 	virtual void * QueryInterface( int id ) = 0;
+	virtual void const * QueryInterface( int id ) const = 0;
 	
 	// Python Operator Overloads
-	string __str__() {
+	string __str__() const {
 		return asString();
 	};
 	
@@ -497,7 +515,7 @@ public:
 	virtual AttrType GetType() const = 0;
 	virtual string GetName() const = 0;
 	virtual void Read( ifstream& in, unsigned int version ) = 0;
-	virtual void Write( ofstream& out, unsigned int version ) = 0;
+	virtual void Write( ofstream& out, unsigned int version ) const = 0;
 	//Getters
 	virtual int asInt() const = 0;
 	virtual float asFloat() const = 0;
@@ -513,21 +531,21 @@ public:
 	//Setters
 	virtual void Set(int) = 0;
 	virtual void Set(float) = 0;
-	virtual void Set(Float3&) = 0;
-	virtual void Set(string&) = 0;
-	virtual void Set(Matrix33&) = 0;
-	virtual void Set( blk_ref & n ) = 0;
-	virtual void Set(TextureSource&) = 0;
-	virtual void Set(BoundingBox&) = 0;
-	virtual void Set(ConditionalInt&) = 0;
-	virtual void Set(Texture&) = 0;
+	virtual void Set(Float3 const &) = 0;
+	virtual void Set(string const &) = 0;
+	virtual void Set(Matrix33 const &) = 0;
+	virtual void Set( blk_ref const & n ) = 0;
+	virtual void Set(TextureSource const &) = 0;
+	virtual void Set(BoundingBox const &) = 0;
+	virtual void Set(ConditionalInt const &) = 0;
+	virtual void Set(Texture const &) = 0;
 	//Link functions
-	virtual bool HasLinks() = 0;
-	virtual void AddLink( blk_ref block ) = 0;
-	virtual void AddLinks( list<blk_ref> new_links ) = 0;
+	virtual bool HasLinks() const = 0;
+	virtual void AddLink( blk_ref const & block ) = 0;
+	virtual void AddLinks( list<blk_ref> const & new_links ) = 0;
 	virtual void ClearLinks() = 0;
-	virtual void RemoveLinks( blk_ref block ) = 0;
-	virtual blk_ref FindLink( string block_type ) = 0;
+	virtual void RemoveLinks( blk_ref const & block ) = 0;
+	virtual blk_ref FindLink( string const & block_type ) const = 0;
 
 	// Python Operator Overloads
 	string __str__() {
@@ -541,11 +559,11 @@ class INode {
 public:
 	INode() {}
 	virtual ~INode() {}
-	virtual Matrix44 GetLocalTransform() = 0;
-	virtual Matrix44 GetWorldTransform() = 0;
-	virtual Matrix44 GetBindPosition() = 0;
-	virtual void SetBindPosition( Matrix44 & m ) = 0;
-	virtual Matrix44 GetLocalBindPos() = 0;
+	virtual Matrix44 GetLocalTransform() const = 0;
+	virtual Matrix44 GetWorldTransform() const = 0;
+	virtual Matrix44 GetBindPosition() const = 0;
+	virtual void SetBindPosition( Matrix44 const & m ) = 0;
+	virtual Matrix44 GetLocalBindPos() const = 0;
 };
 
 class IShapeData {
@@ -574,13 +592,13 @@ public:
 	ITriShapeData() {}
 	virtual ~ITriShapeData () {}
 	//Counts
-	virtual short GetTriangleCount() = 0;
+	virtual short GetTriangleCount() const = 0;
 	virtual void SetTriangleCount(int n) = 0;
 	//Match Detection
 	virtual void SetMatchDetectionMode(bool choice) = 0;
-	virtual bool GetMatchDetectionMode() = 0;
+	virtual bool GetMatchDetectionMode() const = 0;
 	//Getters
-	virtual vector<Triangle> GetTriangles() = 0;
+	virtual vector<Triangle> GetTriangles() const = 0;
 	//Setters
 	virtual void SetTriangles( const vector<Triangle> & in ) = 0;
 };
@@ -590,12 +608,12 @@ public:
 	ITriStripsData() {}
 	virtual ~ITriStripsData () {}
 	//Counts
-	virtual short GetTriangleCount() = 0;
-	virtual short GetStripCount() = 0;
+	virtual short GetTriangleCount() const = 0;
+	virtual short GetStripCount() const = 0;
 	virtual void SetStripCount(int n) = 0;
 	//Getter
-	virtual vector<short> GetStrip( int index ) = 0;
-	virtual vector<Triangle> GetTriangles() = 0;
+	virtual vector<short> GetStrip( int index ) const = 0;
+	virtual vector<Triangle> GetTriangles() const = 0;
 	//Setter
 	virtual void SetStrip( int index, const vector<short> & in ) = 0;
 };
@@ -604,10 +622,10 @@ class ISkinData {
 public:
 	ISkinData() {}
 	virtual ~ISkinData () {}
-	virtual vector<blk_ref> GetBones() = 0;
-	virtual map<int, float> GetWeights( blk_ref bone ) = 0;
-	virtual void AddBone( blk_ref bone, map<int, float> in ) = 0;
-	virtual void RemoveBone( blk_ref bone ) = 0;
+	virtual vector<blk_ref> GetBones() = 0; // Can't be const, since it changes the bone blk_ref reference 
+	virtual map<int, float> GetWeights( blk_ref const & bone ) const = 0;
+	virtual void AddBone( blk_ref const & bone, map<int, float> const & in ) = 0;
+	virtual void RemoveBone( blk_ref const & bone ) = 0;
 };
 
 class IKeyframeData {
@@ -615,19 +633,19 @@ public:
 	IKeyframeData() {}
 	virtual ~IKeyframeData () {}
 	//Rotate
-	virtual KeyType GetRotateType() = 0;
+	virtual KeyType GetRotateType() const = 0;
 	virtual void SetRotateType( KeyType t ) = 0;
-	virtual vector< Key<Quaternion> > GetRotateKeys() = 0;
+	virtual vector< Key<Quaternion> > GetRotateKeys() const = 0;
 	virtual void SetRotateKeys( vector< Key<Quaternion> > const & keys ) = 0;
 	//Translate
-	virtual KeyType GetTranslateType() = 0;
+	virtual KeyType GetTranslateType() const = 0;
 	virtual void SetTranslateType( KeyType t ) = 0;
-	virtual vector< Key<Vector3> > GetTranslateKeys() = 0;
+	virtual vector< Key<Vector3> > GetTranslateKeys() const = 0;
 	virtual void SetTranslateKeys( vector< Key<Vector3> > const & keys ) = 0;
 	//Scale
-	virtual KeyType GetScaleType() = 0;
+	virtual KeyType GetScaleType() const = 0;
 	virtual void SetScaleType( KeyType t ) = 0;
-	virtual vector< Key<float> > GetScaleKeys() = 0;
+	virtual vector< Key<float> > GetScaleKeys() const = 0;
 	virtual void SetScaleKeys( vector< Key<float> > const & keys ) = 0;
 };
 
@@ -635,7 +653,7 @@ class ITextKeyExtraData {
 public:
 	ITextKeyExtraData() {}
 	virtual ~ITextKeyExtraData () {}
-	virtual vector< Key<string> > GetKeys() = 0;
+	virtual vector< Key<string> > GetKeys() const = 0;
 	virtual void SetKeys( vector< Key<string> > const & keys ) = 0;
 
 };
@@ -644,9 +662,9 @@ class IColorData {
 public:
 	IColorData() {}
 	virtual ~IColorData () {}
-	virtual KeyType GetKeyType() = 0;
+	virtual KeyType GetKeyType() const = 0;
 	virtual void SetKeyType( KeyType t ) = 0;
-	virtual vector< Key<Color> > GetKeys() = 0;
+	virtual vector< Key<Color> > GetKeys() const = 0;
 	virtual void SetKeys( vector< Key<Color> > const & keys ) = 0;
 };
 
@@ -654,9 +672,9 @@ class IFloatData {
 public:
 	IFloatData() {}
 	virtual ~IFloatData () {}
-	virtual KeyType GetKeyType() = 0;
+	virtual KeyType GetKeyType() const = 0;
 	virtual void SetKeyType( KeyType t ) = 0;
-	virtual vector< Key<float> > GetKeys() = 0;
+	virtual vector< Key<float> > GetKeys() const = 0;
 	virtual void SetKeys( vector< Key<float> > const & keys ) = 0;
 };
 
@@ -664,9 +682,9 @@ class IPosData {
 public:
 	IPosData() {}
 	virtual ~IPosData () {}
-	virtual KeyType GetKeyType() = 0;
+	virtual KeyType GetKeyType() const = 0;
 	virtual void SetKeyType( KeyType t ) = 0;
-	virtual vector< Key<Vector3> > GetKeys() = 0;
+	virtual vector< Key<Vector3> > GetKeys() const = 0;
 	virtual void SetKeys( vector< Key<Vector3> > const & keys ) = 0;
 };
 
@@ -675,14 +693,14 @@ class IMorphData {
 public:
 	IMorphData() {}
 	virtual ~IMorphData () {}
-	virtual int GetVertexCount() = 0;
+	virtual int GetVertexCount() const = 0;
 	virtual void SetVertexCount( int n ) = 0;
-	virtual int GetMorphCount() = 0;
+	virtual int GetMorphCount() const = 0;
 	virtual void SetMorphCount( int n ) = 0;
-	virtual vector< Key<float> > GetMorphKeys( int n ) = 0;
-	virtual void SetMorphKeys( int n, vector< Key<float> > & keys ) = 0;
-	virtual vector<Vector3> GetMorphVerts( int n) = 0;
-	virtual void SetMorphVerts( int n, const vector<Vector3> & in ) = 0;
+	virtual vector< Key<float> > GetMorphKeys( int n ) const = 0;
+	virtual void SetMorphKeys( int n, vector< Key<float> > const & keys ) = 0;
+	virtual vector<Vector3> GetMorphVerts( int n) const = 0;
+	virtual void SetMorphVerts( int n, vector<Vector3> const & in ) = 0;
 };
 
 //struct ComplexVertex {
@@ -815,7 +833,7 @@ class attr_ref {
 public:
 	attr_ref() : _attr(NULL) {}
 	attr_ref( IAttr * ptr ) : _attr(ptr) {}
-	IAttr * operator->() {
+	IAttr * operator->() const {
 		if ( _attr == NULL ) {
 			//pointer has not been fixed, throw exception
 			throw runtime_error("Attempted to dereference a null Attribute reference.");
@@ -823,29 +841,29 @@ public:
 			return _attr;
 		}
 	}
-	bool is_null() {
+	bool is_null() const {
 		if (_attr == NULL )
 			return true;
 		else
 			return false;
 	}
-	IAttr * ptr() {
+	IAttr * ptr() const {
 		return _attr;
 	}
 	//Comparison operators
-	bool operator==(attr_ref & rh) {
+	bool operator==(attr_ref & rh) const {
 		if (_attr == rh._attr)
 			return true;
 		else
 			return false;
 	}
-	bool operator!=(attr_ref & rh) {
+	bool operator!=(attr_ref & rh) const {
 		if (_attr != rh._attr)
 			return true;
 		else
 			return false;
 	}
-	bool operator<(attr_ref & rh) {
+	bool operator<(attr_ref & rh) const {
 		if (_attr < rh._attr)
 			return true;
 		else
@@ -861,11 +879,11 @@ public:
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(Float3 & n) {
+	attr_ref & operator=(Float3 const & n) {
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(string & n) {
+	attr_ref & operator=(string const & n) {
 		_attr->Set(n);
 		return *this;
 	}
@@ -873,44 +891,44 @@ public:
 		_attr->Set( string(n) );
 		return *this;
 	}
-	attr_ref & operator=(Matrix33 & n) {
+	attr_ref & operator=(Matrix33 const & n) {
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(blk_ref & n) {
+	attr_ref & operator=(blk_ref const & n) {
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(TextureSource & n) {
+	attr_ref & operator=(TextureSource const & n) {
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(BoundingBox & n) {
+	attr_ref & operator=(BoundingBox const & n) {
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(ConditionalInt & n) {
+	attr_ref & operator=(ConditionalInt const & n) {
 		_attr->Set(n);
 		return *this;
 	}
-	attr_ref & operator=(Texture & n) {
+	attr_ref & operator=(Texture const & n) {
 		_attr->Set(n);
 		return *this;
 	}
 
 	//Conversion fuctions
-	operator int() { return _attr->asInt(); }
-	operator float() { return _attr->asFloat(); }
-	operator Float3() { return _attr->asFloat3(); }
-	operator string() { return _attr->asString(); }
+	operator int() const { return _attr->asInt(); }
+	operator float() const { return _attr->asFloat(); }
+	operator Float3() const { return _attr->asFloat3(); }
+	operator string() const { return _attr->asString(); }
 	
-	operator Matrix33() { return _attr->asMatrix33(); }
-	operator blk_ref();
-	operator TextureSource();
-	operator BoundingBox();
-	operator ConditionalInt();
-	operator Texture();
-	operator list<blk_ref>() { return _attr->asLinkList(); }
+	operator Matrix33() const { return _attr->asMatrix33(); }
+	operator blk_ref() const;
+	operator TextureSource() const;
+	operator BoundingBox() const;
+	operator ConditionalInt() const;
+	operator Texture() const;
+	operator list<blk_ref>() const { return _attr->asLinkList(); }
 
 	//friend ostream & operator<<(ostream & lh, const attr_ref & rh) {
 	//	if ( rh._attr == NULL )
@@ -967,7 +985,7 @@ public:
 		return *this;
 	}
 	// Equality Operator
-	bool operator==(const blk_ref & rh) {
+	bool operator==(const blk_ref & rh) const {
 		if ( _block == rh._block && _index == rh._index )
 			return true;
 		else
@@ -981,10 +999,10 @@ public:
 			return false;
 	}
 	// Non-Equality Operator
-	bool operator!=(const blk_ref & rh) {
+	bool operator!=(const blk_ref & rh) const {
 		return !(*this == rh);
 	}
-	bool is_null() {
+	bool is_null() const {
 		if (_block == NULL && _index == -1)
 			return true;
 		else
@@ -1017,7 +1035,7 @@ public:
 			return _block;
 		}
 	}
-	attr_ref operator[] ( string index ) {
+	attr_ref operator[] ( string const & index ) const {
 		return _block->GetAttr(index);
 	}
 	int get_index() const {
diff --git a/pyniflib.i b/pyniflib.i
index 1985d3f6..01cacf7b 100644
--- a/pyniflib.i
+++ b/pyniflib.i
@@ -113,35 +113,47 @@ struct Key {
 %ignore Matrix33::operator[](int n) const;
 %ignore Matrix44::operator[](int n);
 %ignore Matrix44::operator[](int n) const;
-%ignore blk_ref::operator[](string index);
+%ignore blk_ref::operator[](string const & index) const;
 
 %ignore attr_ref::operator=(int n);
 %ignore attr_ref::operator=(float n);
-%ignore attr_ref::operator=(Float3 & n);
-%ignore attr_ref::operator=(string & n);
+%ignore attr_ref::operator=(Float3 const & n);
+%ignore attr_ref::operator=(string const & n);
 %ignore attr_ref::operator=(const char * n);
-%ignore attr_ref::operator=(Matrix33 & n);
-%ignore attr_ref::operator=(blk_ref & n);
-%ignore attr_ref::operator=(TextureSource & n);
-%ignore attr_ref::operator=(BoundingBox & n);
-%ignore attr_ref::operator=(ConditionalInt & n);
-%ignore attr_ref::operator=(Texture & n);
+%ignore attr_ref::operator=(Matrix33 const & n);
+%ignore attr_ref::operator=(blk_ref const & n);
+%ignore attr_ref::operator=(TextureSource const & n);
+%ignore attr_ref::operator=(BoundingBox const & n);
+%ignore attr_ref::operator=(ConditionalInt const & n);
+%ignore attr_ref::operator=(Texture const & n);
 
 %ignore blk_ref::operator=(const blk_ref & rh );
 
-%ignore attr_ref::operator int();
-%ignore attr_ref::operator float();
-%ignore attr_ref::operator Float3();
-%ignore attr_ref::operator std::string();
-
-%ignore attr_ref::operator Matrix33();
-%ignore attr_ref::operator blk_ref();
-%ignore attr_ref::operator TextureSource();
-%ignore attr_ref::operator BoundingBox();
-%ignore attr_ref::operator ConditionalInt();
-%ignore attr_ref::operator Texture();
-%ignore attr_ref::operator std::list<blk_ref>();
+%ignore attr_ref::operator int() const;
+%ignore attr_ref::operator float() const;
+%ignore attr_ref::operator Float3() const;
+%ignore attr_ref::operator std::string() const;
+%ignore attr_ref::operator Matrix33() const;
+%ignore attr_ref::operator blk_ref() const;
+%ignore attr_ref::operator TextureSource() const;
+%ignore attr_ref::operator BoundingBox() const;
+%ignore attr_ref::operator ConditionalInt() const;
+%ignore attr_ref::operator Texture() const;
+%ignore attr_ref::operator std::list<blk_ref>() const;
 
 %ignore blk_ref::operator<<(ostream & lh, const blk_ref & rh);
 
+%rename QueryShapeData( blk_ref & block ) QueryShapeData_const;
+%rename QueryTriShapeData( blk_ref const & block ) QueryTriShapeData_const;
+%rename QuerySkinData( blk_ref const & block ) QuerySkinData_const;
+%rename QueryNode( blk_ref const & block ) QueryNode_const;
+%rename QueryKeyframeData( blk_ref const & block ) QueryKeyframeData_const;
+%rename QueryTextKeyExtraData( blk_ref const & block ) QueryTextKeyExtraData_const;
+%rename QueryMorphData( blk_ref const & block ) QueryMorphData_const;
+%rename QueryTriStripsData( blk_ref const & block ) QueryTriStripsData_const;
+%rename QueryColorData( blk_ref const & block ) QueryColorData_const;
+%rename QueryFloatData( blk_ref const & block ) QueryFloatData_const;
+%rename QueryPosData( blk_ref const & block ) QueryPosData_const;
+
+
 %include "niflib.h"
-- 
GitLab