diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp
index 73c14518ee861f2e4ac51cb76a67530dca37d8d2..695028bc00a6750a6dfebb790bbda74e9d7c9639 100644
--- a/NifImport/ImportAnimation.cpp
+++ b/NifImport/ImportAnimation.cpp
@@ -588,6 +588,29 @@ bool KFMImporter::ImportAnimation()
 				 }
 			 }
 		 }
+		 else if (strmatch(type, "NiKeyframeController"))
+		 {
+			 Control *c = ai.GetTMController(name);
+			 if (NULL == c)
+				 continue;
+
+			 INode *n = gi->GetINodeByName(name.c_str());
+
+			 if ((*lnk).priority_ != 0.0f) {
+				 npSetProp(n, NP_ANM_PRI, (*lnk).priority_);
+			 }
+
+			 NiKeyframeDataRef data;
+			 Point3 p; Quat q; float s;
+			 if (ai.GetTransformData(*lnk, name, data, p, q, s)) {
+				 PosRotScaleNode(n, p, q, s, prsDefault, 0);
+				 if (ai.AddValues(c, data, time)) {
+					 minTime = min(minTime, start);
+					 maxTime = max(maxTime, stop);
+					 ok = true;
+	 			 }
+			 }
+		 }
       }
       if (maxTime > minTime && maxTime > 0.0f)
          time += (maxTime-minTime) + FramesIncrement;
diff --git a/NifImport/KFImporter.cpp b/NifImport/KFImporter.cpp
index 43180a3545c7f778ca8857e2e40f8fd6ff4a3d6f..d3c34ac165a4ec65f2523980807867a8d6cfd899 100644
--- a/NifImport/KFImporter.cpp
+++ b/NifImport/KFImporter.cpp
@@ -2,6 +2,10 @@
 #include "KFImporter.h"
 #include <kfm.h>
 #include "gen/ControllerLink.h"
+#include "obj/NiSequenceStreamHelper.h"
+#include "obj/NiTextKeyExtraData.h"
+#include "obj/NiTimeController.h"
+#include <float.h>
 using namespace Niflib;
 
 KFImporter::KFImporter(const TCHAR *Name,ImpInterface *I,Interface *GI, BOOL SuppressPrompts)
@@ -18,8 +22,49 @@ void KFImporter::ReadBlocks()
 {
    try
    {
-      kf = DynamicCast<NiControllerSequence>(ReadNifList(name.c_str()));
-      BuildNodes();
+	   // Handle Freedom Force Animation Import
+	   std::vector<NiObjectRef> roots = ReadNifList(name.c_str());
+	   kf = DynamicCast<NiControllerSequence>(roots);
+	   if (kf.size() == 0)
+	   {
+		   std::vector<NiSequenceStreamHelperRef> helpers = DynamicCast<NiSequenceStreamHelper>(roots);
+		   for (std::vector<NiSequenceStreamHelperRef>::iterator itr = helpers.begin(); itr != helpers.end(); ++itr)
+		   {
+			   NiSequenceStreamHelperRef helper = (*itr);
+
+			   list< Ref<NiExtraData> > data = helper->GetExtraData();
+			   NiTextKeyExtraDataRef textKey = DynamicCast<NiTextKeyExtraData>(data).front();
+			   list< NiStringExtraDataRef > keys = DynamicCast<NiStringExtraData>(data);
+			   list< Ref<NiTimeController> > controllers = helper->GetControllers();
+
+			   if (keys.size() == controllers.size())
+			   {
+				   int nk = keys.size();
+
+				   NiControllerSequenceRef seq = new NiControllerSequence();
+				   seq->SetName( helper->GetName() );
+				   seq->SetTextKey( textKey );
+
+				   float start = FLT_MAX, stop = FLT_MIN;
+				   vector< Key<string> > textKeys = textKey->GetKeys();
+				   for (vector< Key<string> >::iterator tItr = textKeys.begin(); tItr != textKeys.end(); ++tItr) {
+					   start = min(start, tItr->time);
+					   stop = max(stop, tItr->time);
+				   }
+				   seq->SetStartTime( start );
+				   seq->SetStopTime( stop );
+
+				   list< NiStringExtraDataRef >::iterator keyItr = keys.begin();
+				   list< NiTimeControllerRef >::iterator ctrlItr = controllers.begin();
+				   for (int i=0; i<nk; ++i, ++keyItr, ++ctrlItr) {
+					   seq->AddController( (*keyItr)->GetData(), (*ctrlItr) );
+				   }
+				   kf.push_back( seq );
+			   }
+		   }
+	   }
+
+       BuildNodes();
    }
    catch (std::exception&)
    {