diff --git a/NIF_IO.h b/NIF_IO.h
index b2401cdbd1e8660cc82dbab08dbe4a30cfe66b68..234b592387e577e7f1b288beef7316b3bc35400f 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -34,25 +34,6 @@ const unsigned int VER_20_0_0_5    = 0x14000005; /*!< Nif Version 20.0.0.4 */
 const unsigned int VER_UNSUPPORTED = 0xFFFFFFFF; /*!< Unsupported Nif Version */
 const unsigned int VER_INVALID     = 0xFFFFFFFE; /*!< Not a Nif file */
 
-
-
-/*! Keyframe trees are game dependent, so here we define a few games. */
-enum NifGame {
-	KF_MW = 0, /*!< keyframe files: NiSequenceStreamHelper header, .kf extension */
-	KF_DAOC = 1, /*!< keyframe files: NiNode header, .kfa extension */
-	KF_CIV4 = 2 /*!< keyframe files: NiControllerSequence header, .kf extension */
-};
-
-/*! Export options. */
-enum ExportOptions { 
-	EXPORT_NIF = 0, /*!< NIF */
-	EXPORT_NIF_KF = 1, /*!< NIF + single KF + KFM */
-	EXPORT_NIF_KF_MULTI = 2, /*!< NIF + multiple KF + KFM */
-	EXPORT_KF = 3, /*!< single KF */
-	EXPORT_KF_MULTI = 4 /*!< multiple KF */
-};
-
-
 //--Non-mathematical Basic Types--//
 
 typedef unsigned char	byte;
diff --git a/Ref.h b/Ref.h
index fc153ff0dc1aae385b73186065dfa560c2c98f36..12552a67984c2dd0affbea2e9488383431934f30 100644
--- a/Ref.h
+++ b/Ref.h
@@ -5,7 +5,6 @@ All rights reserved.  Please see niflib.h for licence. */
 #define _REF_H_
 
 #include <ostream>
-#include "dll_export.h"
 namespace Niflib {
 
 /**
diff --git a/gen/NodeGroup.h b/gen/NodeGroup.h
index ea55a26e25a8d2278727ecb00e88d33e90828bf9..5ed963d09e4d10d927a08e85a47edac116584008 100644
--- a/gen/NodeGroup.h
+++ b/gen/NodeGroup.h
@@ -5,14 +5,12 @@ All rights reserved.  Please see niflib.h for licence. */
 #define _NODEGROUP_H_
 
 #include "../NIF_IO.h"
+#include "../obj/NiNode.h"
 
 // Include structures
 #include "../Ref.h"
 namespace Niflib {
 
-// Forward define of referenced blocks
-class NiNode;
-
 /*!
  * A group of NiNodes references.
  */
diff --git a/kfm.cpp b/kfm.cpp
index f76a66fbc2fcda90cf9d787aad60eee0cc016c16..8a4f655ebd61eb747f4087425bef99835425d01e 100644
--- a/kfm.cpp
+++ b/kfm.cpp
@@ -1,7 +1,11 @@
 //--Kfm Functions--//
 
 #include "kfm.h"
+#include "niflib.h"
 #include "NIF_IO.h"
+#include "obj/NiObject.h"
+
+namespace Niflib {
 
 void KfmEventString::Read( istream & in, unsigned int version ) {
 	unk_int = ReadUInt(in);
@@ -115,13 +119,13 @@ void Kfm::Write( ostream & out, uint version ) {
 };
 */
 
-blk_ref Kfm::MergeActions( string const & path ) {
+Ref<NiObject> Kfm::MergeActions( string const & path ) {
 	// Read NIF file
 	cout << path + '\\' + nif_filename << endl;
-	blk_ref nif = ReadNifTree( path + '\\' + nif_filename);
+	NiObjectRef nif = ReadNifTree( path + '\\' + nif_filename);
 	
 	// Read Kf files
-	vector<blk_ref> kf;
+	vector<NiObjectRef> kf;
 	for ( vector<KfmAction>::iterator it = actions.begin(); it != actions.end(); it++ ) {
 		string action_filename = path + '\\' + it->action_filename;
 		// Check if the file exists.
@@ -138,3 +142,5 @@ blk_ref Kfm::MergeActions( string const & path ) {
 	// TODO: merge everything into the nif file
 	return nif;
 }
+
+}
diff --git a/kfm.h b/kfm.h
index e1689fe28d69518e92b748b556435f8ad7f733c0..96c9cfd5b7be90d345cbaaaaff3f39c9dde3cd2e 100644
--- a/kfm.h
+++ b/kfm.h
@@ -1,11 +1,17 @@
 #ifndef _KFM_H
 #define _KFM_H
 
-#include "niflib.h"
-namespace NifLib {
+#include <iostream>
+#include <string>
+#include <vector>
+#include "Ref.h"
+namespace Niflib {
 
 using namespace std;
 
+//Classes used
+class NiObject;
+
 //--KFM File Format--//
 
 //KFM Versions
@@ -60,11 +66,11 @@ struct Kfm {
 	vector<KfmAction> actions;
 	
 	// Reads the given file and returns the KFM version.
-	unsigned int Read( string const & file_name ); // returns Kfm version
+	unsigned int Read( const string & file_name ); // returns Kfm version
 	unsigned int Read( istream & in ); // returns Kfm version
 
 	// Reads the NIF file and all KF files referred to in this KFM, and returns the root block of the resulting NIF tree.
-	blk_ref Kfm::MergeActions( string const & path );
+	Ref<NiObject> MergeActions( const string & path );
 	//void Write( string const & file_name, unsigned int version );
 	//void Write( ostream & out, unsigned int version );
 };
diff --git a/niflib.cpp b/niflib.cpp
index 4a9ec523bcd174b167652df91348b6a99db984ba..c64a44ff79cb0db6c4be560fdba35336019220b0 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -8,14 +8,23 @@ All rights reserved.  Please see niflib.h for licence. */
 //#define DEBUG_HEADER_FOOTER
 
 #include "niflib.h"
-#include "obj/NiAVObject.h"
+#include "NIF_IO.h"
+#include "kfm.h"
+#include "obj/NiObject.h"
 #include "obj/NiNode.h"
+#include "obj/NiAVObject.h"
 #include "obj/NiTextKeyExtraData.h"
+#include "obj/NiSequenceStreamHelper.h"
+#include "obj/NiTimeController.h"
+#include "obj/NiKeyframeController.h"
+#include "obj/NiKeyframeData.h"
+#include "obj/NiStringExtraData.h"
 #include "gen/header.h"
+
 namespace Niflib {
 
 //Stores the mapping between block names and factory function pointers to create them
-typedef IBlock * (*blk_factory_func)();
+typedef NiObject * (*blk_factory_func)();
 bool global_block_map_init = false;
 map<string, blk_factory_func> global_block_map;
 
@@ -35,7 +44,7 @@ NiObjectRef CreateBlock( string block_type ) {
 		global_block_map_init = true;
 	}
 
-	IBlock * block = NULL;
+	NiObject * block = NULL;
 
 	map<string, blk_factory_func>::iterator it;
 	it = global_block_map.find(block_type);
@@ -460,91 +469,103 @@ list<NiObjectRef> GetAllObjectsByType( NiObjectRef const & root, const Type & ty
  * \param kfm The KFM structure (if required by style).
  * \param kf_type What type of keyframe tree to write (Morrowind style, DAoC style, ...).
  */
-//void SplitNifTree( NiObjectRef const & root_block, NiObjectRef & xnif_root, NiObjectRef & xkf_root, Kfm & kfm, int kf_type ) {
-//	// Do we have animation groups (a NiTextKeyExtraData block)?
-//	// If so, create XNif and XKf trees.
-//	NiObjectRef txtkey_block = GetObjectByType( root_block, NiTextKeyExtraData::TypeConst() ); 
-//	if ( txtkey_block != NULL ) {
-//		if ( kf_type == KF_MW ) {
-//			// Construct the XNif file...
-//			// We are lazy. (TODO: clone & remove keyframe controllers & keyframe data)
-//			xnif_root = root_block;
-//			
-//			// Now the XKf file...
-//			// Create xkf root header.
-//			xkf_root = CreateBlock("NiSequenceStreamHelper");
-//			
-//			// Add a copy of the NiTextKeyExtraData block to the XKf header.
-//			NiObjectRef xkf_txtkey_block = CreateBlock("NiTextKeyExtraData");
-//			//TODO: Have Amorilia fix this
-//			//xkf_root["Extra Data"] = xkf_txtkey_block;
-//			
-//			/*ITextKeyExtraData const *itxtkey_block = QueryTextKeyExtraData(txtkey_block);
-//			ITextKeyExtraData *ixkf_txtkey_block = QueryTextKeyExtraData(xkf_txtkey_block);
-//			ixkf_txtkey_block->SetKeys(itxtkey_block->GetKeys());*/
-//			
-//			// Append NiNodes with a NiKeyFrameController as NiStringExtraData blocks.
-//			list<NiObjectRef> nodes = GetAllObjectsByType( root_block, NiNode::TypeConst() );
-//			for ( list<NiObjectRef>::iterator it = nodes.begin(); it != nodes.end(); ) {
-//				//TODO: Have Amorilia Fix this
-//				/*if ( (*it)->GetAttr("Controller")->asLink().is_null() || (*it)->GetAttr("Controller")->asLink()->GetBlockType() != "NiKeyframeController" )
-//					it = nodes.erase( it );
-//				else
-//					it++;*/
-//			};
-//			
-//			NiObjectRef last_block = xkf_txtkey_block;
-//			for ( list<NiObjectRef>::const_iterator it = nodes.begin(); it != nodes.end(); ++it ) {
-//				NiObjectRef nodextra = CreateBlock("NiStringExtraData");
-//				//TODO: Implement NiStringEtraData along with functions/member variables to cover these data items
-//				//nodextra["String Data"] = (*it)["Name"]->asString();
-//				//last_block["Next Extra Data"] = nodextra;
-//				last_block = nodextra;
-//			};
-//			
-//			// Add controllers & controller data.
-//			last_block = xkf_root;
-//			for ( list<NiObjectRef>::const_iterator it = nodes.begin(); it != nodes.end(); ++it ) {
-//				//TODO:  Implement NiTimeController class functions/variables
-//				//NiObjectRef controller = (*it)->GetAttr("Controller")->asLink();
-//				//NiObjectRef xkf_controller = CreateBlock("NiKeyframeController");
-//				//xkf_controller["Flags"] = controller["Flags"]->asInt();
-//				//xkf_controller["Frequency"] = controller["Frequency"]->asFloat();
-//				//xkf_controller["Phase"] = controller["Phase"]->asFloat();
-//				//xkf_controller["Start Time"] = controller["Start Time"]->asFloat();
-//				//xkf_controller["Stop Time"] = controller["Stop Time"]->asFloat();
-//				//
-//				//NiObjectRef xkf_data = CreateBlock("NiKeyframeData");
-//				//xkf_controller["Data"] = xkf_data;
-//				//IKeyframeData const *ikfdata = QueryKeyframeData(controller["Data"]->asLink());
-//				//IKeyframeData *ixkfdata = QueryKeyframeData(xkf_data);
-//				//ixkfdata->SetRotateType(ikfdata->GetRotateType());
-//				//ixkfdata->SetTranslateType(ikfdata->GetTranslateType());
-//				//ixkfdata->SetScaleType(ikfdata->GetScaleType());
-//				//ixkfdata->SetRotateKeys(ikfdata->GetRotateKeys());
-//				//ixkfdata->SetTranslateKeys(ikfdata->GetTranslateKeys());
-//				//ixkfdata->SetScaleKeys(ikfdata->GetScaleKeys());
-//	
-//				//if ( last_block == xkf_root ) {
-//				//	if ( ! last_block["Controller"]->asLink().is_null() )
-//				//		throw runtime_error("Cannot create .kf file for multicontrolled nodes."); // not sure 'bout this one...
-//				//	last_block["Controller"] = xkf_controller;
-//				//} else {
-//				//	if ( ! last_block["Next Controller"]->asLink().is_null() )
-//				//		throw runtime_error("Cannot create .kf file for multicontrolled nodes."); // not sure 'bout this one...
-//				//	last_block["Next Controller"] = xkf_controller;
-//				//};
-//				//last_block = xkf_controller;
-//				//// note: targets are automatically calculated, we don't need to reset them
-//			};
-//		} else // TODO other games
-//			throw runtime_error("Not yet implemented.");
-//	} else {
-//		// no animation groups: nothing to do
-//		xnif_root = NULL;
-//		xkf_root = NULL;
-//	};
-//}
+void SplitNifTree( NiObjectRef const & root_block, NiObjectRef & xnif_root, NiObjectRef & xkf_root, Kfm & kfm, int kf_type ) {
+	// Do we have animation groups (a NiTextKeyExtraData block)?
+	// If so, create XNif and XKf trees.
+	NiObjectRef txtkey = GetObjectByType( root_block, NiTextKeyExtraData::TypeConst() );
+	NiTextKeyExtraDataRef txtkey_block;
+	if ( txtkey != NULL ) {
+		txtkey_block = DynamicCast<NiTextKeyExtraData>(txtkey);
+	}
+	if ( txtkey_block != NULL ) {
+		if ( kf_type == KF_MW ) {
+			// Construct the XNif file...
+			// We are lazy. (TODO: clone & remove keyframe controllers & keyframe data)
+			xnif_root = root_block;
+			
+			// Now the XKf file...
+			// Create xkf root header.
+			NiSequenceStreamHelperRef xkf_stream_helper = new NiSequenceStreamHelper;
+			xkf_root = xkf_stream_helper;
+			
+			// Add a copy of the NiTextKeyExtraData block to the XKf header.
+			NiTextKeyExtraDataRef xkf_txtkey_block = new NiTextKeyExtraData;
+
+			//TODO: Have Amorilia fix this
+			xkf_stream_helper->AddExtraData( StaticCast<NiExtraData>(xkf_txtkey_block) );
+			
+			//ITextKeyExtraData const *itxtkey_block = QueryTextKeyExtraData(txtkey_block);
+			//ITextKeyExtraData *ixkf_txtkey_block = QueryTextKeyExtraData(xkf_txtkey_block);
+			
+			xkf_txtkey_block->SetKeys( txtkey_block->GetKeys() );
+			
+			// Append NiNodes with a NiKeyFrameController as NiStringExtraData blocks.
+			list< pair< NiNodeRef, NiKeyframeControllerRef> > node_controllers;
+
+			list<NiObjectRef> nodes = GetAllObjectsByType( root_block, NiNode::TypeConst() );
+			for ( list<NiObjectRef>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
+				NiNodeRef node = DynamicCast<NiNode>(*it);
+				if ( node == NULL ) {
+					continue;
+				}
+
+				//Find the first NiKeyframeController in the controller list, if any
+				list<NiTimeControllerRef> controllers = node->GetControllers();
+				NiKeyframeControllerRef key_controller;
+				for ( list<NiTimeControllerRef>::iterator controller = controllers.begin(); controller != controllers.end(); ++controller ) {
+					key_controller = DynamicCast<NiKeyframeController>(*it);
+					if ( key_controller != NULL ) {
+						break;
+					}
+				}
+
+				//If this node has no keyframe controller, put it in the list
+				if ( key_controller != NULL ) {
+					node_controllers.push_back( pair<NiNodeRef,NiKeyframeControllerRef>( node, key_controller ) );
+				}
+			};
+			
+			
+			for ( list< pair< NiNodeRef, NiKeyframeControllerRef> >::iterator it = node_controllers.begin(); it != node_controllers.end(); ++it ) {
+				//Add string data				
+				NiStringExtraDataRef nodextra = new NiStringExtraData;
+				nodextra->SetData( it->first->GetName() );
+				xkf_stream_helper->AddExtraData( StaticCast<NiExtraData>(nodextra) );
+
+				// Add controllers & controller data.
+				NiKeyframeControllerRef controller = it->second;
+				NiKeyframeControllerRef xkf_controller =  new NiKeyframeController;
+
+				xkf_controller->SetFlags( controller->GetFlags() );
+				xkf_controller->SetFrequency( controller->GetFrequency() );
+				xkf_controller->SetPhase( controller->GetPhase() );
+				xkf_controller->SetStartTime( controller->GetStartTime() );
+				xkf_controller->SetStopTime( controller->GetStopTime() );
+				
+				NiKeyframeDataRef xkf_data = new NiKeyframeData;
+				NiKeyframeDataRef kfdata = controller->GetData();
+				xkf_controller->SetData( xkf_data );
+
+				xkf_data->SetRotateType( kfdata->GetRotateType() );
+				xkf_data->SetTranslateType( kfdata->GetTranslateType() );
+				xkf_data->SetScaleType( kfdata->GetScaleType() );
+				xkf_data->SetQuatRotateKeys( kfdata->GetQuatRotateKeys() );
+				xkf_data->SetXRotateKeys( kfdata->GetXRotateKeys() );
+				xkf_data->SetYRotateKeys( kfdata->GetYRotateKeys() );
+				xkf_data->SetZRotateKeys( kfdata->GetZRotateKeys() );
+				xkf_data->SetTranslateKeys( kfdata->GetTranslateKeys() );
+				xkf_data->SetScaleKeys( kfdata->GetScaleKeys() );
+	
+				xkf_stream_helper->AddController( StaticCast<NiTimeController>(controller) );
+			};
+		} else // TODO other games
+			throw runtime_error("KF splitting for the requested game is not yet implemented.");
+	} else {
+		// no animation groups: nothing to do
+		xnif_root = NULL;
+		xkf_root = NULL;
+	};
+}
 
 //TODO:  This was written by Amorilia.  Figure out how to fix it.
 ///*!
@@ -557,35 +578,35 @@ list<NiObjectRef> GetAllObjectsByType( NiObjectRef const & root, const Type & ty
 //};
 
 //TODO:  This was written by Amorilia.  Figure out how to fix it.
-//void WriteFileGroup( string const & file_name, NiObjectRef const & root_block, unsigned int version, unsigned int export_files, unsigned int kf_type ) {
-//	// Get base filename.
-//	uint file_name_slash = uint(file_name.rfind("\\") + 1);
-//	string file_name_path = file_name.substr(0, file_name_slash);
-//	string file_name_base = file_name.substr(file_name_slash, file_name.length());
-//	uint file_name_dot = uint(file_name_base.rfind("."));
-//	file_name_base = file_name_base.substr(0, file_name_dot);
-//	
-//	// Deal with the simple case first
-//	if ( export_files == EXPORT_NIF )
-//		WriteNifTree( file_name_path + file_name_base + ".nif", root_block, version ); // simply export the NIF file!
-//	// Now consider all other cases
-//	else if ( kf_type == KF_MW ) {
-//		if ( export_files == EXPORT_NIF_KF ) {
-//			// for Morrowind we must also write the full NIF file
-//			WriteNifTree( file_name_path + file_name_base + ".nif", root_block, version ); // simply export the NIF file!
-//			NiObjectRef xnif_root;
-//			NiObjectRef xkf_root;
-//			Kfm kfm; // dummy
-//			SplitNifTree( root_block, xnif_root, xkf_root, kfm, KF_MW );
-//			if ( xnif_root != NULL ) {
-//				WriteNifTree( file_name_path + "x" + file_name_base + ".nif", xnif_root, version );
-//				WriteNifTree( file_name_path + "x" + file_name_base + ".kf", xkf_root, version );
-//			};
-//		} else
-//			throw runtime_error("Invalid export option.");
-//	} else
-//		throw runtime_error("Not yet implemented.");
-//};
+void WriteFileGroup( string const & file_name, NiObjectRef const & root_block, unsigned int version, ExportOptions export_files, NifGame kf_type ) {
+	// Get base filename.
+	uint file_name_slash = uint(file_name.rfind("\\") + 1);
+	string file_name_path = file_name.substr(0, file_name_slash);
+	string file_name_base = file_name.substr(file_name_slash, file_name.length());
+	uint file_name_dot = uint(file_name_base.rfind("."));
+	file_name_base = file_name_base.substr(0, file_name_dot);
+	
+	// Deal with the simple case first
+	if ( export_files == EXPORT_NIF )
+		WriteNifTree( file_name_path + file_name_base + ".nif", root_block, version ); // simply export the NIF file!
+	// Now consider all other cases
+	else if ( kf_type == KF_MW ) {
+		if ( export_files == EXPORT_NIF_KF ) {
+			// for Morrowind we must also write the full NIF file
+			WriteNifTree( file_name_path + file_name_base + ".nif", root_block, version ); // simply export the NIF file!
+			NiObjectRef xnif_root;
+			NiObjectRef xkf_root;
+			Kfm kfm; // dummy
+			SplitNifTree( root_block, xnif_root, xkf_root, kfm, KF_MW );
+			if ( xnif_root != NULL ) {
+				WriteNifTree( file_name_path + "x" + file_name_base + ".nif", xnif_root, version );
+				WriteNifTree( file_name_path + "x" + file_name_base + ".kf", xkf_root, version );
+			};
+		} else
+			throw runtime_error("Invalid export option.");
+	} else
+		throw runtime_error("Not yet implemented.");
+};
 
 
 //Returns the total number of blocks in memory
diff --git a/niflib.h b/niflib.h
index 1e67ffd90bf2758e11173d5f2aac08a0bcc1195b..613fb7a468242028a4d67bf151341bc33997bf53 100644
--- a/niflib.h
+++ b/niflib.h
@@ -49,20 +49,36 @@ POSSIBILITY OF SUCH DAMAGE. */
 #include <map>
 #include "dll_export.h"
 #include "nif_math.h"
-#include "NIF_IO.h"
-#include "obj/NiObject.h"
-#include "obj/NiNode.h"
-#include "obj/NiAVObject.h"
-//#include "gen/obj_defines.h"
-//#include "kfm.h"
+#include "Ref.h"
 
 using namespace std;
 namespace Niflib {
 
+//Classes used
+class NiObject;
+class NiNode;
+class NiAVObject;
+
 #ifndef NULL
 #define NULL 0  /*!< Definition used to detect null pointers. */ 
 #endif
 
+/*! Keyframe trees are game dependent, so here we define a few games. */
+enum NifGame {
+	KF_MW = 0, /*!< keyframe files: NiSequenceStreamHelper header, .kf extension */
+	KF_DAOC = 1, /*!< keyframe files: NiNode header, .kfa extension */
+	KF_CIV4 = 2 /*!< keyframe files: NiControllerSequence header, .kf extension */
+};
+
+/*! Export options. */
+enum ExportOptions { 
+	EXPORT_NIF = 0, /*!< NIF */
+	EXPORT_NIF_KF = 1, /*!< NIF + single KF + KFM */
+	EXPORT_NIF_KF_MULTI = 2, /*!< NIF + multiple KF + KFM */
+	EXPORT_KF = 3, /*!< single KF */
+	EXPORT_KF_MULTI = 4 /*!< multiple KF */
+};
+
 //--Main Functions--//
 
 /*!
@@ -114,14 +130,14 @@ NIFLIB_API unsigned int CheckNifHeader( string const & file_name );
  * 
  * \sa ReadNifTree, WriteNifTree
  */
-NIFLIB_API vector<NiObjectRef> ReadNifList( string const & file_name );
+NIFLIB_API vector< Ref<NiObject> > ReadNifList( string const & file_name );
 
 /*!
  * Reads the given input stream and returns a vector of block references
  * \param stream The input stream to read NIF data from.
  * \return A vector of block references that point to all the blocks read from the stream.
  */
-NIFLIB_API vector<NiObjectRef> ReadNifList( istream & in );
+NIFLIB_API vector< Ref<NiObject> > ReadNifList( istream & in );
 
 /*!
  * Reads the given file by file name and returns a reference to the root block.
@@ -140,14 +156,14 @@ NIFLIB_API vector<NiObjectRef> ReadNifList( istream & in );
  * 
  * \sa ReadNifList, WriteNifTree
  */
-NIFLIB_API NiObjectRef ReadNifTree( string const & file_name );
+NIFLIB_API Ref<NiObject> ReadNifTree( string const & file_name );
 
 /*!
  * Reads the given input stream and returns a reference to the root block.
  * \param stream The input stream to read NIF data from.
  * \return A block reference that points to the root of the tree of data blocks contained in the NIF file.
  */
-NIFLIB_API NiObjectRef ReadNifTree( istream & in );
+NIFLIB_API Ref<NiObject> ReadNifTree( istream & in );
 
 /*!
  * Creates a new NIF file of the given file name by crawling through the data tree starting with the root block given.
@@ -170,7 +186,7 @@ NIFLIB_API NiObjectRef ReadNifTree( istream & in );
  * 
  * \sa ReadNifList, WriteNifTree
  */
-NIFLIB_API void WriteNifTree( string const & file_name, NiObjectRef const & root, unsigned int version = VER_4_0_0_2, unsigned int user_version = 0 );
+NIFLIB_API void WriteNifTree( string const & file_name, Ref<NiObject> const & root, unsigned int version = VER_4_0_0_2, unsigned int user_version = 0 );
 
 /*!
  * Writes a nif tree to an ostream starting at the given root block.
@@ -178,7 +194,7 @@ NIFLIB_API void WriteNifTree( string const & file_name, NiObjectRef const & root
  * \param root The root block to start from when writing out the NIF data.  All decedents of this block will be written to the stream in tree-descending order.
  * \param version The version of the NIF format to use when writing a file.  Default is version 4.0.0.2.
  */
-NIFLIB_API void WriteNifTree( ostream & stream, NiObjectRef const & root, unsigned int version = VER_4_0_0_2, unsigned int user_version = 0 );
+NIFLIB_API void WriteNifTree( ostream & stream, Ref<NiObject> const & root, unsigned int version = VER_4_0_0_2, unsigned int user_version = 0 );
 
 //TODO:  This was written by Amorilia.  Figure out how to fix it.
 /*!
@@ -189,7 +205,7 @@ NIFLIB_API void WriteNifTree( ostream & stream, NiObjectRef const & root, unsign
  * \param export_files What files to write: NIF, NIF + KF + KFM, NIF + KF's + KFM, KF only, KF's only
  * \param kf_type The KF type (Morrowind style, DAoC style, CivIV style, ...)
  */
-//NIFLIB_API void WriteFileGroup( string const & file_name, NiObjectRef const & root, unsigned int version, unsigned int export_files, unsigned int kf_type );
+NIFLIB_API void WriteFileGroup( string const & file_name, Ref<NiObject> const & root, unsigned int version, ExportOptions export_files, NifGame kf_type );
 
 //TODO:  Figure out how to fix this to work with the new system
 /*!
@@ -224,7 +240,7 @@ NIFLIB_API void WriteNifTree( ostream & stream, NiObjectRef const & root, unsign
  * 
  * sa BlocksInMemory
  */
-NIFLIB_API NiObjectRef CreateBlock( string block_type );
+NIFLIB_API Ref<NiObject> CreateBlock( string block_type );
 
 /*!
  * Returns whether the requested version is supported.
diff --git a/niflib.vcproj b/niflib.vcproj
index 2b8ec7831378999d9a8a58f0a54d3ce6adcd8446..e257e6c64222d06cfe85681fe1efdc6c8afd39f5 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -355,6 +355,10 @@
 			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
+			<File
+				RelativePath=".\kfm.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\NIF_IO.cpp"
 				>
@@ -1398,6 +1402,10 @@
 				RelativePath=".\dll_export.h"
 				>
 			</File>
+			<File
+				RelativePath=".\kfm.h"
+				>
+			</File>
 			<File
 				RelativePath=".\NIF_IO.h"
 				>
diff --git a/obj/NiObject.h b/obj/NiObject.h
index 2298994d31e8c2fb0c47c36bcfd67c9941dd95d4..7a61b268d4fba630d318ee89f015452c1ad187e8 100644
--- a/obj/NiObject.h
+++ b/obj/NiObject.h
@@ -28,8 +28,6 @@ using namespace std;
 
 class NiObject;
 typedef Ref<NiObject> NiObjectRef;
-typedef Ref<NiObject> blk_ref; //Temporary to make old code compile
-typedef NiObject IBlock;
 
 class NiObject {
 public:
diff --git a/obj/NiSkinData.cpp b/obj/NiSkinData.cpp
index 22933978305960558b1fd8cbdad836459faa2a2a..6b1f279420e39f1bee3c9b4c09f8759480d86b20 100644
--- a/obj/NiSkinData.cpp
+++ b/obj/NiSkinData.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for licence. */
 
 #include "NiSkinData.h"
+#include "NiNode.h"
 #include "../gen/SkinData.h"
 #include "../gen/SkinWeight.h"
 #include "NiSkinPartition.h"
@@ -81,7 +82,7 @@ NiSkinData::NiSkinData( const Ref<NiTriBasedGeom> & owner ) {
 	}
 
 	boneList.resize( skinInst->GetBoneCount() );
-	vector<NiNodeRef> bone_nodes = skinInst->GetBones();
+	vector< Ref<NiNode> > bone_nodes = skinInst->GetBones();
 	
 	//--Calculate Overall Offset--//
 
diff --git a/pch.h b/pch.h
index aab1431864e4aeda060284504efe53235b82fd34..863410d5e447e1fcebafce27ebb12f323232465d 100644
--- a/pch.h
+++ b/pch.h
@@ -3,7 +3,6 @@
 #include "dll_export.h"
 #include "NIF_IO.h"
 #include "nif_math.h"
-#include "niflib.h"
 #include "Ref.h"
 #include "Type.h"