diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp
index ac863a8fac82b3ee53bcc808442be4b165d1c2fa..13344c7082cb39e1b2f2e8e97963b9ff1757a63c 100644
--- a/NIF_Blocks.cpp
+++ b/NIF_Blocks.cpp
@@ -451,6 +451,159 @@ void ABlock::RemoveParent( IBlock * match ) {
 	//}
 }
 
+//--Link Classes--//
+
+
+//Constructor
+//It is required for a LinkGroup to be aware of the block it is part of
+
+void Link::SetIndex( const int new_index ) {
+	//This function is for the initial file read.  It records the index of the block which
+	//will later be resolved to a link once all the blocks have been read
+
+	//If there is already a link, kill it
+	if ( link.is_null() == false ) {
+		KillLink();
+		link.nullify();
+	}
+
+	index = new_index;
+}
+
+void Link::SetLink( const blk_ref & new_link ) {
+	if ( link != new_link ) {
+		//Kill previous link
+		KillLink();
+		
+		//Set New Link
+		link = new_link;
+		InitLink();
+	}
+}
+
+void Link::Fix( const vector<blk_ref> & blocks ) {
+	//The purpouse of this function is to convert the block index to a link
+	//to the corresponding block.
+
+	//Ensure that there is an index to convert
+	if (index == -1 ) {
+		return;
+	}
+	
+	if ( index < int(blocks.size()) && index >= 0 ) {
+		link = blocks[index];
+		InitLink();
+	}
+}
+
+void Link::InitLink() {
+	//Add parent at new link site
+	IBlock * target = link.get_block();
+	if ( target != NULL ) {
+		//Get internal interface
+		((ABlock*)target)->AddParent( _owner );
+	}
+}
+void Link::KillLink() {
+	//Remove parent at previous location
+	IBlock * target = link.get_block();
+	if ( target != NULL ) {
+		((ABlock*)target)->RemoveParent( _owner );
+	}
+}
+
+void NifStream( Link & val, istream& in, uint version ) {
+	val.SetIndex( ReadInt( in ) );
+};
+
+void NifStream( Link const & val, ostream& out, uint version ) {
+	blk_ref ref = val.GetLink();
+	if ( ref.is_null() == false ) {
+		WriteInt( ref->GetBlockNum(), out );
+	} else {
+		WriteInt( -1, out );
+	}
+}
+
+ostream & operator<<( ostream & out, Link const & val ) {
+	return out << val.GetLink();
+}
+
+//--CrossRef Classes--//
+
+void CrossRef::SetIndex( const int new_index ) {
+	//This function is for the initial file read.  It records the index of the block which
+	//will later be resolved to a reference once all the blocks have been read
+
+	//If there is already a reference, kill it
+	if ( ref != NULL ) {
+		KillRef();
+		ref = NULL;
+	}
+
+	index = new_index;
+}
+
+void CrossRef::SetCrossRef( IBlock * new_ref ) {
+	if ( ref != new_ref ) {
+		//Kill previous link
+		KillRef();
+		
+		//Set New Link
+		ref = new_ref;
+		InitRef();
+	}
+}
+
+void CrossRef::Invalidate() {
+	//This function's purpouse is to inform this CrossRef that the block it is referencing has died
+	//Simply set it to NULL
+	ref = NULL;
+}
+
+void CrossRef::Fix( const vector<blk_ref> & blocks ) {
+	//The purpouse of this function is to convert the block index to a reference
+	//to the corresponding block.
+	
+	if (index < int(blocks.size()) && index >= 0 ) {
+		ref = blocks[index].get_block();
+		index = -1;
+		InitRef();
+	}
+}
+
+void CrossRef::InitRef() {
+	//Inform target block that it is being cross referenced
+	if ( ref != NULL ) {
+		//Get internal interface
+		((ABlock*)ref)->IncCrossRef( _owner );
+	}
+}
+void CrossRef::KillRef() {
+	//Inform target block that it is no longer being cross referenced
+	if ( ref != NULL ) {
+		((ABlock*)ref)->IncCrossRef( _owner );
+	}
+}
+
+
+void NifStream( CrossRef & val, istream& in, uint version ) {
+	val.SetIndex( ReadInt( in ) );
+};
+
+void NifStream( CrossRef const & val, ostream& out, uint version ) {
+	IBlock * ref = val.GetCrossRef();
+	if ( ref != NULL ) {
+		WriteInt( ref->GetBlockNum(), out );
+	} else {
+		WriteInt( -1, out );
+	}
+}
+
+ostream & operator<<( ostream & out, CrossRef const & val ) {
+	return out << blk_ref(val.GetCrossRef());
+}
+
 /***********************************************************
  * ANode methods
  **********************************************************/
diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index ddbbd3e8e9615f06c1bb9d8f03692b62da6e91d6..54d83ece5e4016aa7d992a6887bddfdfbcaf44d3 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -132,186 +132,23 @@ public:
 	//Constructor
 	//It is required for a LinkGroup to be aware of the block it is part of
 	Link ( IBlock * owner) : _owner(owner), index(-1) {}
-
 	//Destructor
 	~Link() { KillLink(); }
-
-	void SetIndex( const int new_index ) {
-		//This function is for the initial file read.  It records the index of the block which
-		//will later be resolved to a link once all the blocks have been read
-
-		//If there is already a link, kill it
-		if ( link.is_null() == false ) {
-			KillLink();
-			link.nullify();
-		}
-
-		index = new_index;
-	}
-
+	void SetIndex( const int new_index );
 	blk_ref GetLink() const { return link; }
-
-
-
-	void SetLink( const blk_ref & new_link ) {
-		if ( link != new_link ) {
-			//Kill previous link
-			KillLink();
-			
-			//Set New Link
-			link = new_link;
-			InitLink();
-		}
-	}
-
-	void Fix( const vector<blk_ref> & blocks ) {
-		//The purpouse of this function is to convert the block index to a link
-		//to the corresponding block.
-
-		//Ensure that there is an index to convert
-		if (index == -1 ) {
-			return;
-		}
-		
-		if ( index < int(blocks.size()) && index >= 0 ) {
-			link = blocks[index];
-			InitLink();
-		}
-	}
+	void SetLink( const blk_ref & new_link );
+	void Fix( const vector<blk_ref> & blocks );
 private:
 	IBlock * _owner;
 	blk_ref link;
 	int index;
-	void InitLink() {
-		//Add parent at new link site
-		IBlock * target = link.get_block();
-		if ( target != NULL ) {
-			//Get internal interface
-			((ABlock*)target)->AddParent( _owner );
-		}
-	}
-	void KillLink() {
-		//Remove parent at previous location
-		IBlock * target = link.get_block();
-		if ( target != NULL ) {
-			((ABlock*)target)->RemoveParent( _owner );
-		}
-	}
+	void InitLink();
+	void KillLink();
 };
 
-class LinkGroup {
-public:
-	//Constructor
-	//It is required for a LinkGroup to be aware of the block it is part of
-	LinkGroup(IBlock * owner) : _owner(owner) {}
-
-	//Destructor
-	~LinkGroup() { 
-		//Remove all links
-		ClearLinks();
-	}
-
-	void SetIndices( const list<int> new_indices ) {
-		//This function is for the initial file read.  It records the indices of the blocks which
-		//will later be resolved to links once all the blocks have been read
-
-		//If there are already links, kill them
-		ClearLinks();
-
-		indices = new_indices;
-	}
-
-	list<blk_ref> GetLinks() const { 
-		return links;
-	}
-
-	void AddLink( blk_ref const & block ) {
-		InitLink( block );
-		links.push_back( block );
-	}
-
-	void AddLinks( list<blk_ref> const & new_links ) {
-		//Initiate all of the new links
-		list<blk_ref>::const_iterator it;
-		for (it = new_links.begin(); it != new_links.end(); ++it ) {
-			InitLink( *it );
-			links.push_back( *it );
-		}
-	}
-
-	blk_ref FindLink( string const & block_type ) const {
-		//Find the first link with the requested block type
-		for ( list<blk_ref>::const_iterator it = links.begin(); it != links.end(); ++it ) {
-			if ( (*it)->GetBlockType() == block_type )
-				return blk_ref(*it);
-		}
-
-		//No block was found, so return a null one
-		return blk_ref(-1);
-	}
-
-	void ClearLinks() { 
-		//Kill all the links
-		list<blk_ref>::iterator it;
-		for (it = links.begin(); it != links.end(); ++it ) {
-			KillLink( *it );
-		}
-
-		//Clear the list
-		links.clear();
-	}
-
-	void RemoveLinks( blk_ref const & block ) {
-		//Remove all links that match this block
-		//Kill the links first
-		list<blk_ref>::iterator it;
-		for (it = links.begin(); it != links.end(); ++it ) {
-			if ( *it == block ) {
-				KillLink( *it );
-			}
-		}
-		
-		//Now remove them from the list
-		links.remove( block );
-	}
-
-	void Fix( const vector<blk_ref> & blocks ) {
-		//The purpouse of this function is to convert the block indices to a links
-		//to the corresponding blocks.
-		
-		list<int>::iterator it;
-		for (it = indices.begin(); it != indices.end(); ++it ) {
-			if ( *it < int(blocks.size()) && *it >= 0 ) {
-				blk_ref new_link = blocks[*it];
-				InitLink( new_link );
-				links.push_back( new_link );
-			}
-		}
-
-		//Clear indices
-		indices.clear();
-	}
-
-private:
-	IBlock * _owner;
-	list<blk_ref> links;
-	list<int> indices;
-	void InitLink( const blk_ref & link ) {
-		//Add parent at new link site
-		IBlock * target = link.get_block();
-		if ( target != NULL ) {
-			//Get internal interface
-			((ABlock*)target)->AddParent( _owner );
-		}
-	}
-	void KillLink( const blk_ref & link ) {
-		//Remove parent at previous location
-		IBlock * target = link.get_block();
-		if ( target != NULL ) {
-			((ABlock*)target)->RemoveParent( _owner );
-		}
-	}
-};
+void NifStream( Link & val, istream& in, uint version = 0 );
+void NifStream( Link const & val, ostream& out, uint version = 0 );
+ostream & operator<<( ostream & out, Link const & val );
 
 //--CrossRef Classes--//
 
@@ -320,191 +157,23 @@ public:
 	//Constructor
 	//It is required for a CrossRef to be aware of the block it is part of
 	CrossRef ( IBlock * owner) : _owner(owner), ref(NULL), index(-1) {}
-
 	//Destructor
 	~CrossRef() { KillRef(); }
-
-	void SetIndex( const int new_index ) {
-		//This function is for the initial file read.  It records the index of the block which
-		//will later be resolved to a reference once all the blocks have been read
-
-		//If there is already a reference, kill it
-		if ( ref != NULL ) {
-			KillRef();
-			ref = NULL;
-		}
-
-		index = new_index;
-	}
-
-	IBlock * GetCrossRef() { return ref; }
-
-	void SetCrossRef( IBlock * new_ref ) {
-		if ( ref != new_ref ) {
-			//Kill previous link
-			KillRef();
-			
-			//Set New Link
-			ref = new_ref;
-			InitRef();
-		}
-	}
-
-	void RemoveCrossLink( IBlock * block_to_remove ) {
-		//This function's purpouse is to inform this CrossRef that the block it is referencing has died
-		//Simply set it to NULL
-		ref = NULL;
-	}
-
-	void Fix( const vector<blk_ref> & blocks ) {
-		//The purpouse of this function is to convert the block index to a reference
-		//to the corresponding block.
-		
-		if (index < int(blocks.size()) && index >= 0 ) {
-			ref = blocks[index].get_block();
-			index = -1;
-			InitRef();
-		}
-	}
-
+	void SetIndex( const int new_index );
+	IBlock * GetCrossRef() const { return ref; }
+	void SetCrossRef( IBlock * new_ref );
+	void Invalidate();
+	void Fix( const vector<blk_ref> & blocks );
 private:
 	IBlock * _owner;
 	IBlock * ref;
 	int index;
-	void InitRef() {
-		//Inform target block that it is being cross referenced
-		if ( ref != NULL ) {
-			//Get internal interface
-			((ABlock*)ref)->IncCrossRef( _owner );
-		}
-	}
-	void KillRef() {
-		//Inform target block that it is no longer being cross referenced
-		if ( ref != NULL ) {
-			((ABlock*)ref)->IncCrossRef( _owner );
-		}
-	}
-};
-
-class CrossRefGroup {
-public:
-	//Constructor
-	//It is required for a LinkGroup to be aware of the block it is part of
-	CrossRefGroup(IBlock * owner) : _owner(owner) {}
-
-	//Destructor
-	~CrossRefGroup() { 
-		//Remove all links
-		ClearRefs();
-	}
-
-	void SetIndices( const list<int> new_indices ) {
-		//This function is for the initial file read.  It records the indices of the blocks which
-		//will later be resolved to links once all the blocks have been read
-
-		//If there are already links, kill them
-		ClearRefs();
-
-		indices = new_indices;
-	}
-
-	list<IBlock *> GetRefs() const { 
-		return refs;
-	}
-
-	void AddRef( IBlock * const & new_ref ) {
-		InitRef( new_ref );
-		refs.push_back( new_ref );
-	}
-
-	void AddRefs( list<IBlock *> const & new_refs ) {
-		//Initiate all of the new links
-		list<IBlock *>::const_iterator it;
-		for (it = new_refs.begin(); it != new_refs.end(); ++it ) {
-			InitRef( *it );
-			refs.push_back( *it );
-		}
-	}
-
-	IBlock * FindRef( string const & block_type ) const {
-		//Find the first reference with the requested block type
-		for ( list<IBlock *>::const_iterator it = refs.begin(); it != refs.end(); ++it ) {
-			if ( (*it)->GetBlockType() == block_type )
-				return *it;
-		}
-
-		//No block was found, so return NULL
-		return NULL;
-	}
-
-	void ClearRefs() { 
-		//Kill all the refs
-		list<IBlock *>::iterator it;
-		for (it = refs.begin(); it != refs.end(); ++it ) {
-			KillRef( *it );
-		}
-
-		//Clear the list
-		refs.clear();
-	}
-
-	void RemoveRefs( IBlock * const block ) {
-		//Remove all refs that match this block
-		//Kill the refs first
-		list<IBlock *>::iterator it;
-		for (it = refs.begin(); it != refs.end(); ++it ) {
-			if ( *it == block ) {
-				KillRef( *it );
-			}
-		}
-		
-		//Now remove them from the list
-		refs.remove( block );
-	}
-
-	void Fix( const vector<blk_ref> & blocks ) {
-		//The purpouse of this function is to convert the block indices to a links
-		//to the corresponding blocks.
-		
-		list<int>::iterator it;
-		for (it = indices.begin(); it != indices.end(); ++it ) {
-			if ( *it < int(blocks.size()) && *it >= 0 ) {
-				IBlock * new_ref = blocks[*it].get_block();
-				InitRef( new_ref );
-				refs.push_back( new_ref );
-			}
-		}
-
-		//Clear indices
-		indices.clear();
-	}
-
-	void RemoveCrossLink( IBlock * block_to_remove ) {
-		//This function's purpouse is to inform this CrossRefGroup that one of the blocks
-		//it is referencing has died
-
-		//Remove matching refs
-		RemoveRefs( block_to_remove );
-	}
-
-private:
-	IBlock * _owner;
-	list<IBlock *> refs;
-	list<int> indices;
-	void InitRef( IBlock * ref ) {
-		//Inform target block that it is being cross referenced
-		if ( ref != NULL ) {
-			//Get internal interface
-			((ABlock*)ref)->IncCrossRef( _owner );
-		}
-	}
-	void KillRef( IBlock * ref ) {
-		//Inform target block that it is no longer being cross referenced
-		if ( ref != NULL ) {
-			((ABlock*)ref)->IncCrossRef( _owner );
-		}
-	}
+	void InitRef();
+	void KillRef();
 };
+void NifStream( CrossRef & val, istream& in, uint version  = 0);
+void NifStream( CrossRef const & val, ostream& out, uint version = 0 );
+ostream & operator<<( ostream & out, CrossRef const & val );
 
 class AControllable : public ABlock {
 public:
diff --git a/NIF_IO.cpp b/NIF_IO.cpp
index 15075a779d561a2ca5ecf143e8203f5dc039104c..e3b490bed6a157a9fe19adfdf9913102418d9bfb 100644
--- a/NIF_IO.cpp
+++ b/NIF_IO.cpp
@@ -315,32 +315,6 @@ void NifStream( float const & val, ostream& out, uint version ) { WriteFloat( va
 void NifStream( string & val, istream& in, uint version ) { val = ReadString( in ); };
 void NifStream( string const & val, ostream& out, uint version ) { WriteString( val, out ); }
 
-//--Link Types--//
-
-//There is intentionally no function to read directly to blk_ref
-
-void NifStream( blk_ref const & val, ostream& out, uint version ) {
-	if ( val.is_null() == false ) {
-		WriteInt( val->GetBlockNum(), out );
-	} else {
-		WriteInt(-1, out );
-	}
-}
-
-//There is intentionally no function to read directly to IBlock *
-
-void NifStream( IBlock * const & val, ostream& out, uint version ) {
-	if ( val != NULL ) {
-		WriteInt( val->GetBlockNum(), out );
-	} else {
-		WriteInt( -1, out );
-	}
-}
-
-ostream & operator<<( ostream & out, IBlock * const & val ) {
-	return out << blk_ref(val);
-}
-
 //--Structs--//
 
 //HeaderString
diff --git a/NIF_IO.h b/NIF_IO.h
index 1f9da5d648c6b1986dba31a8585795981ff9332a..30630752db59280079d3816f36a77c081c30bc07 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -138,18 +138,6 @@ void NifStream( float const & val, ostream& out, uint version = 0  );
 void NifStream( string & val, istream& in, uint version = 0 );
 void NifStream( string const & val, ostream& out, uint version = 0  );
 
-//--Link Types--//
-
-//blk_ref
-//There is intentionally no function to read directly to blk_ref
-void NifStream( blk_ref const & val, ostream& out, uint version );
-ostream & operator<<( ostream & out, blk_ref const & val );
-
-//IBlock *
-//There is intentionally no function to read directly to IBlock *
-void NifStream( IBlock * const & val, ostream& out, uint version );
-ostream & operator<<( ostream & out, IBlock * const & val );
-
 //--Structs--//
 
 //HeaderString