diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt
index 355c3fd2cac45cd83b2163b74e350f3dc2877487..cdc748b693785f6b571da56cb8d80a71034c5936 100644
--- a/MaxNifPlugins_Readme.txt
+++ b/MaxNifPlugins_Readme.txt
@@ -1,4 +1,4 @@
-                        MaxPlugins 0.2.4
+                        MaxPlugins 0.2.5
                         ================
 
  
@@ -27,6 +27,22 @@
 
     Change log
     ----------
+      0.2.5
+      -----
+    o Exporter
+      - Rewrote animation export dialogs and procedures to write files
+        similar to Civilation exporter.
+      - Removed seperate *.kf and merged with *.nif like Civ4
+      - Fixed issues with NiStencilProperty (via niflib) for Morrowind
+      - Add option to optionally export accum nodes
+      - Add options for exporting skin partition in different ways
+      - Expose the Auto detect parameter to allow game to be saved
+      
+    o Importer
+      - Add option to ignore root
+      - Expose the Time Tag and Key Note params on nif dialog
+      - Expose the Auto detect parameter to allow game to be saved
+        
       0.2.4
       -----
     o Exporter
diff --git a/NifCommon/AnimKey.cpp b/NifCommon/AnimKey.cpp
index 8caa4ac15022d18669288e865b1cd846395b7785..30fdbb0cf629e0cb32b08cebd679390b3e4ecf95 100644
--- a/NifCommon/AnimKey.cpp
+++ b/NifCommon/AnimKey.cpp
@@ -321,6 +321,44 @@ template<> void MergeKey<ITCBRotKey>(ITCBRotKey& lhs, ITCBRotKey& rhs) {
    lhs.val = Quat(lhs.val) * Quat(rhs.val);
 }
 
+
+template<> FloatKey InterpKey<FloatKey>(Control *subCtrl, TimeValue time, float timeOff) {
+   FloatKey rKey;
+   memset(&rKey, 0, sizeof(rKey));
+   rKey.time = timeOff + FrameToTime(time);
+   Interval valid; valid.SetEmpty();
+   if (subCtrl->SuperClassID() == SClass_ID(CTRL_SCALE_CLASS_ID) ) {
+      ScaleValue s;
+      subCtrl->GetValue(time, &s, valid, CTRL_ABSOLUTE);
+      rKey.data = Average(s.s);
+   } else {
+      subCtrl->GetValue(time, &rKey.data, valid, CTRL_ABSOLUTE);
+   }
+   return rKey;
+}
+
+template<> QuatKey InterpKey<QuatKey>(Control *subCtrl, TimeValue time, float timeOff) {
+   QuatKey rKey;
+   memset(&rKey, 0, sizeof(rKey));
+   rKey.time = timeOff + FrameToTime(time);
+   Interval valid; valid.SetEmpty();
+   Quat q;
+   subCtrl->GetValue(time, &q, valid, CTRL_ABSOLUTE);
+   rKey.data = TOQUAT(q, true);
+   return rKey;
+}
+
+template<> Vector3Key InterpKey<Vector3Key>(Control *subCtrl, TimeValue time, float timeOff) {
+   Vector3Key rKey;
+   memset(&rKey, 0, sizeof(rKey));
+   rKey.time = timeOff + FrameToTime(time);
+   Interval valid; valid.SetEmpty();
+   Point3 p;
+   subCtrl->GetValue(time, &p, valid, CTRL_ABSOLUTE);
+   rKey.data = TOVECTOR3(p);
+   return rKey;
+}
+
 float GetValue(Vector3& value, V3T type)
 {
    switch (type) {
@@ -364,7 +402,6 @@ Vector3Key& CopyKey( Vector3Key& dst, FloatKey& src, V3T type)
    return dst;
 }
 
-
 void SplitKeys(vector<Vector3Key>&keys, vector<FloatKey>&xkeys, vector<FloatKey>&ykeys, vector<FloatKey>&zkeys)
 {
    int n = keys.size();
@@ -435,3 +472,5 @@ bool GetTranslationKeys(Control *c, vector<Vector3Key> keys, const vector<float>
    }
    return false;
 }
+
+
diff --git a/NifCommon/AnimKey.h b/NifCommon/AnimKey.h
index 7766ab9a82cd60adbfa67b1e36cf622f499d1084..bd549a61f095ad9feaf7662b5475b777e6872c19 100644
--- a/NifCommon/AnimKey.h
+++ b/NifCommon/AnimKey.h
@@ -70,6 +70,11 @@ template<> QuatKey MapKey<QuatKey, ITCBRotKey>(ITCBRotKey& key, float time);
 template<> FloatKey MapKey<FloatKey, ITCBScaleKey>(ITCBScaleKey& key, float time);
 template<> Vector3Key MapKey<Vector3Key, ITCBPoint3Key>(ITCBPoint3Key& key, float time);
 
+// Interpolated Keys
+template<typename T> T InterpKey(Control *subCtrl, TimeValue time, float timeOff);
+template<> FloatKey InterpKey<FloatKey>(Control *subCtrl, TimeValue time, float timeOff);
+template<> QuatKey InterpKey<QuatKey>(Control *subCtrl, TimeValue time, float timeOff);
+template<> Vector3Key InterpKey<Vector3Key>(Control *subCtrl, TimeValue time, float timeOff);
 
 template<typename T> void MergeKey(T& lhs, T& rhs) {
    lhs.val += rhs.val;
@@ -142,13 +147,20 @@ inline int GetKeys(Control *subCtrl, vector<T>& keys, Interval range)
       float timeOffset = -FrameToTime(range.Start());
       int n = ikeys->GetNumKeys();
       keys.reserve(n);
+      bool hasStart = false, hasEnd = false;
       for (int i=0; i<n; ++i){
          AnyKey buf; U *key = reinterpret_cast<U*>((IKey*)buf);
          ikeys->GetKey(i, key);
          if (range.InInterval(key->time)) {
+            hasStart |= (range.Start() == key->time);
+            hasEnd   |= (range.End() == key->time);
             keys.push_back( MapKey<T>(*key, timeOffset) );
          }
       }
+      if (keys.size() > 0) {
+         if (!hasStart) keys.insert(keys.begin(), InterpKey<T>(subCtrl, range.Start(), timeOffset) );
+         if (!hasEnd) keys.push_back(InterpKey<T>(subCtrl, range.End(), timeOffset) );
+      }
       return keys.size();
    }
    return 0;
diff --git a/NifCommon/NifCommon_VC80.vcproj b/NifCommon/NifCommon_VC80.vcproj
index 62f60d5fa8bf3df7256f397632ac1b8faa4e8fdd..4da6b708b3a0495532a809fbd8bd1478508bf654 100644
--- a/NifCommon/NifCommon_VC80.vcproj
+++ b/NifCommon/NifCommon_VC80.vcproj
@@ -41,7 +41,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/FI&quot;$(ProjectDir)pch.h&quot;"
-				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib"
+				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES"
 				ExceptionHandling="2"
 				RuntimeLibrary="0"
@@ -107,7 +107,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/FI&quot;$(ProjectDir)pch.h&quot;"
 				Optimization="0"
-				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib"
+				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib\include"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES"
 				MinimalRebuild="true"
 				ExceptionHandling="2"
@@ -175,7 +175,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/FI&quot;$(ProjectDir)pch.h&quot;"
-				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib"
+				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED"
 				ExceptionHandling="2"
 				RuntimeLibrary="0"
@@ -241,7 +241,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/FI&quot;$(ProjectDir)pch.h&quot;"
 				Optimization="0"
-				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib"
+				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib\include"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED"
 				MinimalRebuild="true"
 				ExceptionHandling="2"
@@ -309,7 +309,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/FI&quot;$(ProjectDir)pch.h&quot;"
-				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib"
+				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED"
 				ExceptionHandling="2"
 				RuntimeLibrary="0"
@@ -375,7 +375,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/FI&quot;$(ProjectDir)pch.h&quot;"
 				Optimization="0"
-				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib"
+				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib\include"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED"
 				MinimalRebuild="true"
 				ExceptionHandling="2"
diff --git a/NifExport/Animation.cpp b/NifExport/Animation.cpp
index 70eaba44f9a15c6b00a1ab3c3d45e0a7bb27e986..1066a9c1093b3b307a351f96eab78e99b3ad5364 100644
--- a/NifExport/Animation.cpp
+++ b/NifExport/Animation.cpp
@@ -13,11 +13,12 @@ HISTORY:
 #include "pch.h"
 #include <IFrameTagManager.h>
 #include <notetrck.h>
-
+#include <set>
 #include "NifExport.h"
 #include "AnimKey.h"
 
 #include <obj/NiControllerSequence.h>
+#include <obj/NiControllerManager.h>
 #include <obj/NiInterpolator.h>
 #include <obj/NiTransformInterpolator.h>
 #include <obj/NiTransformData.h>
@@ -28,6 +29,8 @@ HISTORY:
 #include <obj/NiKeyframeData.h>
 #include <obj/NiStringPalette.h>
 #include <obj/NiBSplineCompTransformInterpolator.h>
+#include <obj/NiDefaultAVObjectPalette.h>
+#include <obj/NiMultiTargetTransformController.h>
 using namespace Niflib;
 
 const Class_ID IPOS_CONTROL_CLASS_ID = Class_ID(0x118f7e02,0xffee238a);
@@ -45,26 +48,152 @@ struct AnimationExport
    INode * findTrackedNode(INode *root);
 
    bool doExport(NiControllerSequenceRef seq);
+   bool doExport(NiControllerManagerRef ctrl, INode *node);
    bool exportController(INode *node);
    Control *GetTMController(INode* node);
+   NiTimeControllerRef exportController(INode *node, Interval range, bool setTM );
+   bool GetTextKeys(INode *node, vector<StringKey>& textKeys);
 
    Exporter &ne;
    Interval range;
    NiControllerSequenceRef seq;
+
+   set<NiAVObjectRef> objRefs;
+   map<NiControllerSequenceRef, Interval> ranges;
 };
 
+bool GetTextKeys(INode *node, vector<StringKey>& textKeys, Interval range)
+{
+   // Populate Text keys and Sequence information from note tracks
+   if (Exporter::mUseTimeTags) {
+      if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) {
+         int n = tagMgr->GetTagCount();
+         for (int i = 0; i<n; i++) {
+            UINT id = tagMgr->GetTagID(i);
+            TimeValue t = tagMgr->GetTimeByID(id, FALSE);
+            TSTR name = tagMgr->GetNameByID(id);
+
+            StringKey strkey;
+            strkey.time = FrameToTime( Interval(range.Start(), t).Duration()-1 );
+            strkey.data = name;
+            textKeys.push_back(strkey);
+         }
+      }
+   } else {
+      for (int i=0, n=node->NumNoteTracks(); i<n; ++i) {
+         if ( NoteTrack *nt = node->GetNoteTrack(i) ) {
+            if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) {
+               DefNoteTrack *defNT = (DefNoteTrack *)nt;
+               if ( defNT->NumKeys() > 0 ) {
+                  bool stop = false;
+                  for (int j=0, m=defNT->keys.Count(); j<m && !stop; ++j) {
+                     NoteKey* key = defNT->keys[j];
+
+                     if (wildmatch("start*", key->note)) {
+                        stringlist args = TokenizeCommandLine(key->note, true);
+                        if (args.empty()) continue;
+
+                        range.SetStart( key->time );
+                        for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
+                           if (strmatch("-name", *itr)) {
+                              if (++itr == args.end()) break;
+                           }
+                        }
+                     } else if ( wildmatch("end*", key->note) ) {
+                        range.SetEnd( key->time );
+                        stop = true;
+                     }
+                     StringKey strkey;
+                     strkey.time = FrameToTime( Interval(range.Start(), key->time).Duration()-1 );
+                     strkey.data = key->note;
+                     textKeys.push_back(strkey);
+                  }
+               }
+            }
+         }
+      }
+   }
+   return !textKeys.empty();
+}
+
+void Exporter::InitializeTimeController(NiTimeControllerRef ctrl, NiNodeRef parent)
+{
+   ctrl->SetFrequency(1.0f);
+   ctrl->SetStartTime(FloatINF);
+   ctrl->SetStopTime(FloatNegINF);
+   ctrl->SetPhase(0.0f);
+   ctrl->SetFlags(0x0C);
+   ctrl->SetTarget( parent );
+   parent->AddController(DynamicCast<NiTimeController>(ctrl));
+}
+
+NiNodeRef Exporter::createAccumNode(NiNodeRef parent, INode *node)
+{
+   NiNodeRef accumNode;
+   bool isTracked = isNodeTracked(node);
+   if (!Exporter::mAllowAccum || !isTracked)
+   {
+      accumNode = parent;
+   }
+   else
+   {
+      accumNode = getNode( FormatString("%s NonAccum", node->GetName()) );
+      accumNode->SetLocalTransform(Matrix44::IDENTITY);
+      parent->AddChild(DynamicCast<NiAVObject>(accumNode));
+   }
+
+   // add multi target controller to parent if exporting with animation
+   if ( mExportType == NIF_WO_KF ){
+
+      if ( Exporter::mAllowAccum && isTracked ) {
+         // transfer controllers to accum
+         list<NiTimeControllerRef> ctlrs = parent->GetControllers();
+         for (list<NiTimeControllerRef>::iterator it = ctlrs.begin(); it != ctlrs.end(); ++it) {
+            parent->RemoveController(*it);
+            accumNode->AddController(*it);
+         }
+      }
+
+   } else if ( Exporter::mExportType != Exporter::NIF_WO_ANIM ) 
+   {
+      // NiMultiTargetTransformController causes crashes in old formats
+      if (Exporter::mNifVersionInt >= VER_10_0_1_0)
+      {
+         NiMultiTargetTransformControllerRef ctrl = new NiMultiTargetTransformController();
+         vector<NiNodeRef> children;
+         getChildNodes(node, children);
+         ctrl->SetExtraTargets(children);
+         Exporter::InitializeTimeController(ctrl, parent);
+      }
+      NiControllerManagerRef mgr = new NiControllerManager();
+      Exporter::InitializeTimeController(mgr, parent);
+
+      // Export Animation now
+      doAnimExport(mgr, node);
+   }
+   return accumNode;
+}
 Exporter::Result Exporter::doAnimExport(NiControllerSequenceRef root)
 {
    AnimationExport animExporter(*this);
-
    return animExporter.doExport(root) ? Exporter::Ok : Exporter::Abort ;
 }
-//NiControllerSequenceRef makeSequence(TimeValue start, TimeValue end);
 
-INode * AnimationExport::findTrackedNode(INode *node)
+Exporter::Result Exporter::doAnimExport(NiControllerManagerRef mgr, INode *node)
 {
-   // locate START in note track before assuming all is well
-   if (node->HasNoteTracks()) {
+   AnimationExport animExporter(*this);
+   return animExporter.doExport(mgr, node) ? Exporter::Ok : Exporter::Abort ;
+}
+
+bool Exporter::isNodeTracked(INode *node)
+{
+   if (Exporter::mUseTimeTags) {
+      // Assume only one top level node has animation
+      if (mI->GetRootNode() == node->GetParentNode() && isNodeKeyed(node)) {
+         return true;
+      }
+   }
+   else if (node->HasNoteTracks()) {
       for (int i=0, n=node->NumNoteTracks(); i<n; ++i) {
          if ( NoteTrack *nt = node->GetNoteTrack(i) ) {
             if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) {
@@ -73,7 +202,7 @@ INode * AnimationExport::findTrackedNode(INode *node)
                   for (int j=0, m=defNT->keys.Count(); j<m; ++j) {
                      NoteKey* key = defNT->keys[j];
                      if (wildmatch("start*", key->note)) {
-                        return node;
+                        return true;
                      }
                   }
                }
@@ -81,6 +210,75 @@ INode * AnimationExport::findTrackedNode(INode *node)
          }
       }
    }
+   return false;
+}
+
+
+static bool HasKeys(Control *c)
+{
+   bool rv = false;
+   if (c != NULL)
+   {
+      if (c->IsColorController())
+         return false;
+
+      if (IKeyControl *ikeys = GetKeyControlInterface(c)){
+         if (ikeys->GetNumKeys() > 0)
+            return true;
+      }
+      if (Control *sc = c->GetWController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+      if (Control *sc = c->GetXController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+      if (Control *sc = c->GetYController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+      if (Control *sc = c->GetZController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+      if (Control *sc = c->GetRotationController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+      if (Control *sc = c->GetPositionController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+      if (Control *sc = c->GetScaleController()) { 
+         if (sc != c && HasKeys(sc)) 
+            return true;
+      }
+   }
+   return false;
+}
+
+bool Exporter::isNodeKeyed(INode *node) {
+   if (node->HasNoteTracks()) {
+      return true;
+   }
+   if (node->NumKeys() > 0) {
+      return true;
+   }
+   if (Control *tmCont = node->GetTMController()) {
+      if (HasKeys(tmCont))
+         return true;
+   }
+   return false;
+}
+
+
+INode * AnimationExport::findTrackedNode(INode *node)
+{
+   if (ne.isNodeTracked(node))
+      return node;
+
+   // locate START in note track before assuming all is well
    for (int i=0; i < node->NumberOfChildren(); ++i ){
       if ( INode *root = findTrackedNode( node->GetChildNode(i) ) ) {
          return root;
@@ -111,38 +309,54 @@ bool AnimationExport::doExport(NiControllerSequenceRef seq)
    seq->SetTextKey(textKeyData);
 
    // Populate Text keys and Sequence information from note tracks
-   for (int i=0, n=node->NumNoteTracks(); i<n; ++i) {
-      if ( NoteTrack *nt = node->GetNoteTrack(i) ) {
-         if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) {
-            DefNoteTrack *defNT = (DefNoteTrack *)nt;
-            if ( defNT->NumKeys() > 0 ) {
-               bool stop = false;
-               for (int j=0, m=defNT->keys.Count(); j<m && !stop; ++j) {
-                  NoteKey* key = defNT->keys[j];
-
-                  if (wildmatch("start*", key->note)) {
-                     stringlist args = TokenizeCommandLine(key->note, true);
-                     if (args.empty()) continue;
-
-                     seq->SetStartTime(0.0f);
-                     range.SetStart( key->time );
-                     for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
-                        if (strmatch("-name", *itr)) {
-                           if (++itr == args.end()) break;
-                           seq->SetName(*itr);
-                        } else if (strmatch("-loop", *itr)) {
-                           seq->SetCycleType(CYCLE_LOOP);
+   if (Exporter::mUseTimeTags) {
+      if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) {
+         int n = tagMgr->GetTagCount();
+         for (int i = 0; i<n; i++) {
+            UINT id = tagMgr->GetTagID(i);
+            TimeValue t = tagMgr->GetTimeByID(id, FALSE);
+            TSTR name = tagMgr->GetNameByID(id);
+
+            StringKey strkey;
+            strkey.time = FrameToTime( Interval(range.Start(), t).Duration()-1 );
+            strkey.data = name;
+            textKeys.push_back(strkey);
+         }
+      }
+   } else {
+      for (int i=0, n=node->NumNoteTracks(); i<n; ++i) {
+         if ( NoteTrack *nt = node->GetNoteTrack(i) ) {
+            if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) {
+               DefNoteTrack *defNT = (DefNoteTrack *)nt;
+               if ( defNT->NumKeys() > 0 ) {
+                  bool stop = false;
+                  for (int j=0, m=defNT->keys.Count(); j<m && !stop; ++j) {
+                     NoteKey* key = defNT->keys[j];
+
+                     if (wildmatch("start*", key->note)) {
+                        stringlist args = TokenizeCommandLine(key->note, true);
+                        if (args.empty()) continue;
+
+                        seq->SetStartTime(0.0f);
+                        range.SetStart( key->time );
+                        for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
+                           if (strmatch("-name", *itr)) {
+                              if (++itr == args.end()) break;
+                              seq->SetName(*itr);
+                           } else if (strmatch("-loop", *itr)) {
+                              seq->SetCycleType(CYCLE_LOOP);
+                           }
                         }
+                     } else if ( wildmatch("end*", key->note) ) {
+                        range.SetEnd( key->time );
+                        seq->SetStopTime( FrameToTime( range.Duration()-1 ) );
+                        stop = true;
                      }
-                  } else if ( wildmatch("end*", key->note) ) {
-                     range.SetEnd( key->time );
-                     seq->SetStopTime( FrameToTime( range.Duration()-1 ) );
-                     stop = true;
+                     StringKey strkey;
+                     strkey.time = FrameToTime( Interval(range.Start(), key->time).Duration()-1 );
+                     strkey.data = key->note;
+                     textKeys.push_back(strkey);
                   }
-                  StringKey strkey;
-                  strkey.time = FrameToTime( Interval(range.Start(), key->time).Duration()-1 );
-                  strkey.data = key->note;
-                  textKeys.push_back(strkey);
                }
             }
          }
@@ -155,24 +369,191 @@ bool AnimationExport::doExport(NiControllerSequenceRef seq)
    bool ok = exportController(node);
 
    // Handle NonAccum
-   if (ok)
+   if (ok && Exporter::mAllowAccum)
    {
       NiNodeRef ninode = new NiNode();
       ninode->SetName(FormatString("%s NonAccum", node->GetName()));
 
-      NiTransformControllerRef control = new NiTransformController();
-      NiTransformInterpolatorRef interp = new NiTransformInterpolator();
-      ninode->AddController(StaticCast<NiTimeController>(control));
-      control->SetInterpolator(StaticCast<NiInterpolator>(interp));
+      if (Exporter::mNifVersionInt >= VER_10_2_0_0)
+      {
+         NiTransformControllerRef control = new NiTransformController();
+         NiTransformInterpolatorRef interp = new NiTransformInterpolator();
+         ninode->AddController(StaticCast<NiTimeController>(control));
+         control->SetInterpolator(StaticCast<NiInterpolator>(interp));
 
-      interp->SetTranslation( Vector3(0.0f, 0.0f, 0.0f) );
-      interp->SetScale( 1.0f );
-      interp->SetRotation( Quaternion(1.0f, 0.0f, 0.0f, 0.0f) );
-      seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), Exporter::mDefaultPriority);
+         interp->SetTranslation( Vector3(0.0f, 0.0f, 0.0f) );
+         interp->SetScale( 1.0f );
+         interp->SetRotation( Quaternion(1.0f, 0.0f, 0.0f, 0.0f) );
+         seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), Exporter::mDefaultPriority);
+      }
    }
    return ok;
 }
 
+bool AnimationExport::doExport(NiControllerManagerRef mgr, INode *node)
+{
+   int start = 0;
+   NiDefaultAVObjectPaletteRef objPal = new NiDefaultAVObjectPalette();
+   mgr->SetObjectPalette(objPal);
+
+
+   vector<NiControllerSequenceRef> seqs;
+   vector<StringKey> textKeys;
+   NiControllerSequenceRef curSeq;
+
+   // Populate Text keys and Sequence information from note tracks
+   if (Exporter::mUseTimeTags) {
+      if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) {
+
+         curSeq = new NiControllerSequence();
+         curSeq->SetStartTime(FloatINF);
+         curSeq->SetStopTime(FloatINF);
+         curSeq->SetFrequency(1.0f);
+         curSeq->SetCycleType( CYCLE_CLAMP );
+         curSeq->SetTargetName( node->GetName() );
+         seqs.push_back(curSeq);
+         this->range.SetInstant(0);
+         curSeq->SetStartTime(0.0f);
+
+         int n = tagMgr->GetTagCount();
+         for (int i = 0; i<n; i++) {
+            UINT id = tagMgr->GetTagID(i);
+            TimeValue t = tagMgr->GetTimeByID(id, FALSE);
+            TSTR name = tagMgr->GetNameByID(id);
+
+            if (t < range.Start())
+               range.SetStart(t);
+
+            if (t > range.End())
+               range.SetEnd( t );
+
+            StringKey strkey;
+            strkey.time = FrameToTime( Interval(range.Start(), t).Duration()-1 );
+            strkey.data = name;
+            textKeys.push_back(strkey);
+         }
+         NiTextKeyExtraDataRef textKeyData = new NiTextKeyExtraData();
+         curSeq->SetTextKey(textKeyData);
+         textKeyData->SetKeys(textKeys);
+
+         curSeq->SetStopTime( FrameToTime( range.Duration()-1 ) );
+         this->ranges[curSeq] = range;
+         curSeq = NULL;
+      }
+
+   } else {
+
+      int nTracks = node->NumNoteTracks();
+
+      // Populate Text keys and Sequence information from note tracks
+      for (int i=0; i<nTracks; ++i) {
+         if ( NoteTrack *nt = node->GetNoteTrack(i) ) {
+            if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) {
+               DefNoteTrack *defNT = (DefNoteTrack *)nt;
+               if ( defNT->NumKeys() > 0 ) {
+                  for (int j=0, m=defNT->keys.Count(); j<m; ++j) {
+                     NoteKey* key = defNT->keys[j];
+
+                     if (wildmatch("start*", key->note)) {
+                        stringlist args = TokenizeCommandLine(key->note, true);
+                        textKeys.clear();
+
+                        curSeq = new NiControllerSequence();
+                        curSeq->SetStartTime(FloatINF);
+                        curSeq->SetStopTime(FloatINF);
+                        curSeq->SetFrequency(1.0f);
+                        curSeq->SetCycleType( CYCLE_CLAMP );
+                        curSeq->SetTargetName( node->GetName() );
+                        seqs.push_back(curSeq);
+                        this->range.SetInstant(0);
+
+                        curSeq->SetStartTime(0.0f);
+                        range.SetStart( key->time );
+                        for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
+                           if (strmatch("-name", *itr)) {
+                              if (++itr == args.end()) break;
+                              curSeq->SetName(*itr);
+                           } else if (strmatch("-loop", *itr)) {
+                              curSeq->SetCycleType(CYCLE_LOOP);
+                           }
+                        }
+                     }
+
+                     StringKey strkey;
+                     strkey.time = FrameToTime( Interval(range.Start(), key->time).Duration()-1 );
+                     strkey.data = key->note;
+                     textKeys.push_back(strkey);
+
+                     if ( wildmatch("end*", key->note) ) {
+                        range.SetEnd( key->time );
+
+                        // add accumulated text keys to sequence
+                        if (curSeq != NULL) {
+                           curSeq->SetStopTime( FrameToTime( range.Duration()-1 ) );
+
+                           this->ranges[curSeq] = range;
+
+                           NiTextKeyExtraDataRef textKeyData = new NiTextKeyExtraData();
+                           curSeq->SetTextKey(textKeyData);
+                           textKeyData->SetKeys(textKeys);
+                           textKeys.clear();
+                           curSeq = NULL;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   for (vector<NiControllerSequenceRef>::iterator itr = seqs.begin(); itr != seqs.end(); ++itr)
+   {     
+      // Hold temporary value
+      this->seq = (*itr);
+      
+      //this->range.SetStart( TimeToFrame(seq->GetStartTime()) );
+      //this->range.SetEnd( TimeToFrame(seq->GetStopTime()) );
+
+      this->range = this->ranges[this->seq];
+
+      // Now let the fun begin.
+      bool ok = exportController(node);
+
+      // Handle NonAccum
+      if (ok && Exporter::mAllowAccum)
+      {
+         NiNodeRef ninode = ne.getNode( FormatString("%s NonAccum", node->GetName()) );
+         objRefs.insert( StaticCast<NiAVObject>(ninode) );
+
+         if (Exporter::mNifVersionInt >= VER_10_2_0_0)
+         {
+            NiTransformControllerRef control = new NiTransformController();
+            NiTransformInterpolatorRef interp = new NiTransformInterpolator();
+            ninode->AddController(StaticCast<NiTimeController>(control));
+            control->SetInterpolator(StaticCast<NiInterpolator>(interp));
+
+            interp->SetTranslation( Vector3(0.0f, 0.0f, 0.0f) );
+            interp->SetScale( 1.0f );
+            interp->SetRotation( Quaternion(1.0f, 0.0f, 0.0f, 0.0f) );
+            seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), Exporter::mDefaultPriority);
+
+            // now remove temporary controller
+            ninode->RemoveController(StaticCast<NiTimeController>(control));
+         }
+      }
+   }
+
+   // Set objects with animation
+   vector<NiAVObjectRef> objs;
+   objs.insert(objs.end(), objRefs.begin(), objRefs.end());
+   objPal->SetObjs(objs);
+
+   mgr->SetControllerSequences(seqs);
+
+   return true;
+}
+
 
 Control *AnimationExport::GetTMController(INode *n)
 {
@@ -191,11 +572,28 @@ Control *AnimationExport::GetTMController(INode *n)
    return c;
 }
 
+NiTimeControllerRef Exporter::CreateController(INode *node, Interval range)
+{
+   AnimationExport ae(*this);
+   if ( NiTimeControllerRef tc = ae.exportController(node, range, false) ) {
+      if (Exporter::mExportType == Exporter::NIF_WO_KF && isNodeTracked(node)) {
+         NiNodeRef ninode = getNode(node->GetName());
+         vector<StringKey> textKeys;
+         if (GetTextKeys(node, textKeys, range)) {
+            NiTextKeyExtraDataRef textKeyData = new NiTextKeyExtraData();
+            ninode->AddExtraData(StaticCast<NiExtraData>(textKeyData), Exporter::mNifVersionInt);
+            textKeyData->SetKeys(textKeys);
+         }
+      }
+      return tc;
+   }
+   return NiTimeControllerRef();
+}
 
-bool AnimationExport::exportController(INode *node)
+NiTimeControllerRef AnimationExport::exportController(INode *node, Interval range, bool setTM )
 {
-   bool ok = true;
    bool skip = false;
+   NiTimeControllerRef timeControl;
 
    // Primary recursive decent routine
 
@@ -217,23 +615,54 @@ bool AnimationExport::exportController(INode *node)
       {
          Interval validity; validity.SetEmpty();
          Matrix3 tm = node->GetObjTMAfterWSM(range.Start());
-         Matrix3 pm = Inverse(node->GetParentTM(range.Start()));
-         tm *= pm;
+         if (INode *parent = node->GetParentNode()) {
+            Matrix3 pm = Inverse(parent->GetObjTMAfterWSM(range.Start()));
+            tm *= pm;
+         }
 
-         NiNodeRef ninode = new NiNode();
-         ninode->SetName(node->GetName());
+         bool keepData = false;
 
-         //Vector3 trans(FloatNegINF, FloatNegINF, FloatNegINF);
-         //Quaternion rot(FloatNegINF, FloatNegINF, FloatNegINF, FloatNegINF);
-         Vector3 trans = TOVECTOR3(tm.GetTrans());
-         Quaternion rot = TOQUAT( Quat(tm), true );
+         // Set default transform to NaN except for root node
+         Vector3 trans(FloatNegINF, FloatNegINF, FloatNegINF);
+         Quaternion rot(FloatNegINF, FloatNegINF, FloatNegINF, FloatNegINF);
          float scale = FloatNegINF;
-         bool keepData = false;
+         //Vector3 trans = TOVECTOR3(tm.GetTrans());
+         //Quaternion rot = TOQUAT( Quat(tm), true );
 
-         NiTransformControllerRef control = new NiTransformController();
-         NiTransformInterpolatorRef interp = new NiTransformInterpolator();
-         ninode->AddController(StaticCast<NiTimeController>(control));
-         control->SetInterpolator(StaticCast<NiInterpolator>(interp));
+         NiNodeRef ninode = ne.getNode( node->GetName() );
+         if (setTM) {
+            trans = TOVECTOR3(tm.GetTrans());
+            rot = TOQUAT( Quat(tm), true );
+         }
+
+         NiKeyframeDataRef data;
+
+         if (Exporter::mNifVersionInt < VER_10_2_0_0)
+         {
+            NiKeyframeControllerRef control = new NiKeyframeController();
+            Exporter::InitializeTimeController(control, ninode);
+            data = new NiKeyframeData();
+            control->SetData(data);
+            timeControl = StaticCast<NiTimeController>(control);
+         }
+         else
+         {
+            NiTransformControllerRef control = new NiTransformController();
+            Exporter::InitializeTimeController(control, ninode);
+
+            NiTransformInterpolatorRef interp = new NiTransformInterpolator();
+            data = new NiTransformData();
+            control->SetInterpolator(StaticCast<NiInterpolator>(interp));
+
+            interp->SetTranslation(trans);
+            interp->SetScale(scale);
+            interp->SetRotation(rot);
+            interp->SetData(data);
+
+            timeControl = StaticCast<NiTimeController>(control);
+         }
+         timeControl->SetStartTime( 0.0f );
+         timeControl->SetStopTime( FrameToTime( range.Duration()-1 ) );
 
          //if (validity.InInterval(range))
          //{
@@ -245,8 +674,6 @@ bool AnimationExport::exportController(INode *node)
          //}
          //else
          {
-            NiTransformDataRef data = new NiTransformData();
-
             if (Control *c = tmCont->GetPositionController()) 
             {
                int nkeys = 0;
@@ -334,6 +761,7 @@ bool AnimationExport::exportController(INode *node)
                   nkeys += GetKeys<QuatKey, IBezQuatKey>(c, keys, range);
                   data->SetQuatRotateKeys(keys);
                } else if (c->ClassID() == Class_ID(EULER_CONTROL_CLASS_ID,0)) {
+                  data->SetRotateType(XYZ_ROTATION_KEY);
                   if (Control *x = c->GetXController()){
                      vector<FloatKey> keys;
                      if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
@@ -351,7 +779,7 @@ bool AnimationExport::exportController(INode *node)
                      }
                      data->SetXRotateKeys(keys);
                   }
-                  if (Control *y = c->GetXController()) {
+                  if (Control *y = c->GetYController()) {
                      vector<FloatKey> keys;
                      if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
                         nkeys += GetKeys<FloatKey, ILinFloatKey>(y, keys, range);
@@ -422,21 +850,49 @@ bool AnimationExport::exportController(INode *node)
                   //scale = Average(GetScale(tm));
                }           
             }
+
             // only add transform data object if data actually is present
-            if (keepData) {
-               interp->SetData(data);
+            if (!keepData) {
+               ninode->RemoveController(timeControl);
+               timeControl = NULL;
+            } else {
+               objRefs.insert( StaticCast<NiAVObject>(ninode) );
             }
-            interp->SetTranslation(trans);
-            interp->SetScale(scale);
-            interp->SetRotation(rot);
-
-            // Get Priority from node
-            float priority;
-            npGetProp(node, NP_ANM_PRI, priority, Exporter::mDefaultPriority);
-            seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), priority);
          }
       }
    }
+   return timeControl;
+}
+
+bool AnimationExport::exportController(INode *node)
+{
+   bool ok = true;
+
+   bool keepTM = false;
+   if (seq->GetTargetName() == node->GetName()) {
+      keepTM = true;
+   }
+
+   NiTimeControllerRef control = exportController( node, range, keepTM );
+   if (control != NULL)
+   {
+      NiSingleInterpolatorControllerRef interpControl = DynamicCast<NiSingleInterpolatorController>(control);
+      if (interpControl) {
+         // Get Priority from node
+         float priority;
+         npGetProp(node, NP_ANM_PRI, priority, Exporter::mDefaultPriority);
+         seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), priority);
+      }
+      else 
+      {
+         seq->AddController(control);
+      }
+
+      NiObjectNETRef target = control->GetTarget();
+      // now remove temporary controller
+      target->RemoveController(StaticCast<NiTimeController>(control));
+   }
+
    for (int i=0, n=node->NumberOfChildren(); ok && i<n; ++i)
    {
       INode *child = node->GetChildNode(i);
diff --git a/NifExport/Coll.cpp b/NifExport/Coll.cpp
index 230687f5dc0bf9a625efc2346ca5429d9f489723..39a4c81feddab0d3de873233bf178d270dfe61a4 100755
--- a/NifExport/Coll.cpp
+++ b/NifExport/Coll.cpp
@@ -463,9 +463,10 @@ bhkSphereRepShapeRef Exporter::makeTriStripsShape(INode *node, const Matrix3& tm
 	for (int i=0; i<mesh->getNumFaces(); i++)
 		addFace(tris, verts, vnorms, i, vi, mesh, sm);
 
-	TriStrips strips;
-	strippify(strips, verts, vnorms, tris);
-	NiTriStripsDataRef data = makeTriStripsData(strips);
+	//TriStrips strips;
+	//strippify(strips, verts, vnorms, tris);
+	//NiTriStripsDataRef data = makeTriStripsData(strips);
+   NiTriStripsDataRef data = new NiTriStripsData(tris, false);
 	data->SetVertices(verts);
 	data->SetNormals(vnorms);
 
diff --git a/NifExport/Config.cpp b/NifExport/Config.cpp
index 1ff47215a3f811c63ea53af2a3b1720566b5400f..0bc19ce38b3290d82d6abd389599f91fb1ea7fc2 100755
--- a/NifExport/Config.cpp
+++ b/NifExport/Config.cpp
@@ -68,6 +68,17 @@ void Exporter::writeConfig(Interface *i)
       SetIniValue(NifExportSection, "SkeletonOnly", mSkeletonOnly, iniName);
       SetIniValue(NifExportSection, "Cameras", mExportCameras, iniName);
       SetIniValue(NifExportSection, "GenerateBoneCollision", mGenerateBoneCollision, iniName);
+
+      SetIniValue(NifExportSection, "ExportTransforms", mExportTransforms, iniName);
+      SetIniValue<int>(NifExportSection, "ExportType", mExportType, iniName);     
+      SetIniValue<float>(KfExportSection, "Priority", mDefaultPriority, iniName);
+
+      SetIniValue(NifExportSection, "MultiplePartitions", mMultiplePartitions, iniName);
+      SetIniValue<int>(NifExportSection, "BonesPerVertex", mBonesPerVertex, iniName);     
+      SetIniValue<int>(KfExportSection, "BonesPerPartition", mBonesPerPartition, iniName);
+      SetIniValue(NifExportSection, "UseTimeTags", mUseTimeTags, iniName);
+
+      SetIniValue(NifExportSection, "AllowAccum", mAllowAccum, iniName);
       
    }
 }
@@ -123,7 +134,17 @@ void Exporter::readConfig(Interface *i)
       mSkeletonOnly = GetIniValue(NifExportSection, "SkeletonOnly", false, iniName);
       mExportCameras = GetIniValue(NifExportSection, "Cameras", false, iniName);
       mGenerateBoneCollision = GetIniValue(NifExportSection, "GenerateBoneCollision", false, iniName);
-      
+
+      mExportTransforms = GetIniValue(KfExportSection, "Transforms", true, iniName);
+      mDefaultPriority = GetIniValue<float>(KfExportSection, "Priority", 0.0f, iniName);
+      mExportType = ExportType(GetIniValue<int>(NifExportSection, "ExportType", NIF_WO_ANIM, iniName));
+
+      mMultiplePartitions = GetIniValue(NifExportSection, "MultiplePartitions", false, iniName);
+      mBonesPerVertex = GetIniValue<int>(NifExportSection, "BonesPerVertex", 4, iniName);     
+      mBonesPerPartition = GetIniValue<int>(KfExportSection, "BonesPerPartition", 20, iniName);
+
+      mUseTimeTags = GetIniValue(NifExportSection, "UseTimeTags", false, iniName);
+      mAllowAccum = GetIniValue(NifExportSection, "AllowAccum", true, iniName);
   }
 }
 
diff --git a/NifExport/DllEntry.cpp b/NifExport/DllEntry.cpp
index 8907fa30db1f0a35a8ab4ad4837e92ad3c4bb885..2443ecc1128bc0613c1b6981a115d3e6708ba191 100755
--- a/NifExport/DllEntry.cpp
+++ b/NifExport/DllEntry.cpp
@@ -60,7 +60,7 @@ __declspec( dllexport ) const TCHAR* LibDescription()
 //TODO: Must change this number when adding a new class
 __declspec( dllexport ) int LibNumberClasses()
 {
-   return 2;
+   return 1;
 }
 
 // This function returns the number of plug-in classes this DLL
diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp
index 8bdf74b283dc387b0a24605022d2d300ceb9700d..829eb695bdc5232daa4ef822301ce480d026af01 100755
--- a/NifExport/Exporter.cpp
+++ b/NifExport/Exporter.cpp
@@ -25,12 +25,20 @@ bool Exporter::mRemoveUnreferencedBones=false;
 bool Exporter::mSortNodesToEnd=false;
 string Exporter::mGameName = "User";
 string Exporter::mNifVersion = "20.0.0.5";
+int Exporter::mNifVersionInt = VER_20_0_0_5;
 int Exporter::mNifUserVersion = 0;
 bool Exporter::mSkeletonOnly=false;
 bool Exporter::mExportCameras=false;
 bool Exporter::mGenerateBoneCollision=false;
 bool Exporter::mExportTransforms=true;
 float Exporter::mDefaultPriority=0.0f;
+Exporter::ExportType Exporter::mExportType = NIF_WO_ANIM;
+bool Exporter::mMultiplePartitions=false;
+int Exporter::mBonesPerVertex = 4;
+int Exporter::mBonesPerPartition = 20;
+bool Exporter::mUseTimeTags = false;
+bool Exporter::mAutoDetect = true;
+bool Exporter::mAllowAccum = true;
 
 Exporter::Exporter(Interface *i, AppSettings *appSettings)
    : mI(i), mAppSettings(appSettings)
@@ -45,6 +53,10 @@ Exporter::Result Exporter::doExport(NiNodeRef &root, INode *node)
    int nifVersion = GetVersion(Exporter::mNifVersion);
    mIsBethesda = (nifVersion == VER_20_0_0_5 || nifVersion == VER_20_0_0_4) && (Exporter::mNifUserVersion == 11);
 
+   if (mUseTimeTags && nifVersion >= VER_20_0_0_4) {
+      throw runtime_error("Time tag sequences are not supported for version 20.0.0.4 or higher.");
+   }
+
    CalcBoundingBox(node, mBoundingBox);
 
    if (mSkeletonOnly && mIsBethesda)
@@ -145,10 +157,17 @@ Exporter::Result Exporter::exportNodes(NiNodeRef &parent, INode *node)
       } 
       else if (!mSkeletonOnly)
       {
-         newParent = (mExportExtraNodes) ? makeNode(nodeParent, node, local) : nodeParent;
-
-         Result result;
-         result = exportMesh(newParent, node, t);
+         if (mExportType != NIF_WO_ANIM && isNodeTracked(node)) {
+            // Create Node + Accum if has Start Track
+            newParent = createAccumNode( makeNode(nodeParent, node, local) , node);
+         } else if ( mExportExtraNodes || (mExportType != NIF_WO_ANIM && isNodeKeyed(node) ) ) {
+            // Create node if using Extra Nodes or if exporting with anim and node has key values
+            newParent = makeNode(nodeParent, node, local);
+         } else {
+            // Else dont create a node
+            newParent = nodeParent;
+         }
+         Result result = exportMesh(newParent, node, t);
          if (result != Ok)
             return result;
       }
diff --git a/NifExport/Exporter.h b/NifExport/Exporter.h
index 8d5b2f0dfaf90b39abe09b808d948aaa7a36e233..365b5d35aada61c4d621713ed9a423477b4888a7 100755
--- a/NifExport/Exporter.h
+++ b/NifExport/Exporter.h
@@ -1,12 +1,19 @@
 #ifndef __EXPORTER_H__
 #define __EXPORTER_H__
 
+namespace Niflib
+{
+   class NiTimeController;
+   class NiControllerManager;
+   class NiControllerSequence;
+}
 using namespace Niflib;
 
 class BitmapTex;
 class AppSettings;
 class StdMat2;
 
+
 class Exporter
 {
 
@@ -20,6 +27,17 @@ public:
 		Skip
 	};
 
+   enum ExportType
+   {
+      NIF_WO_ANIM  = 0,
+      NIF_WO_KF    = 1,
+      SINGLE_KF_WITH_NIF = 2,
+      SINGLE_KF_WO_NIF = 3,
+      MULTI_KF_WITH_NIF = 4,
+      MULTI_KF_WO_NIF = 5,
+      NIF_WITH_MGR = 6,
+   };
+
    // Callback for post-processing instructions
    struct NiCallback
    {
@@ -52,13 +70,20 @@ public:
    static bool          mSortNodesToEnd;
    static string        mGameName;
    static string        mNifVersion;
+   static int           mNifVersionInt;
    static int           mNifUserVersion;
    static bool				mSkeletonOnly;
    static bool				mExportCameras;
    static bool          mGenerateBoneCollision;
-
    static bool          mExportTransforms;
    static float         mDefaultPriority;
+   static ExportType    mExportType;
+   static bool          mMultiplePartitions;
+   static int           mBonesPerVertex;
+   static int           mBonesPerPartition;
+   static bool          mUseTimeTags;
+   static bool          mAutoDetect;
+   static bool          mAllowAccum;
 
 	Exporter(Interface *i, AppSettings *appSettings);
 
@@ -103,6 +128,7 @@ public:
 	typedef std::map<int, FaceGroup>	FaceGroups;	
    typedef std::map<string, NiNodeRef>	NodeMap;	
    typedef std::list<NiCallback*> CallbackList;
+   typedef std::list<Ref<NiNode> > NodeList;
    
 	Interface				*mI;
 	NiNodeRef				mNiRoot;
@@ -111,6 +137,7 @@ public:
    CallbackList         mPostExportCallbacks;
    bool                 mIsBethesda;
    Box3                 mBoundingBox;
+   NodeList             mAnimationRoots;
 
    Result					exportNodes(NiNodeRef &root, INode *node);
 	Result					exportCollision(NiNodeRef &root, INode *node);
@@ -184,6 +211,11 @@ public:
 
    /* animation export */
    Result doAnimExport(Ref<NiControllerSequence> root);
+   Result doAnimExport(Ref<NiControllerManager> ctrl, INode *node);
+   bool isNodeTracked(INode *node);
+   bool isNodeKeyed(INode *node);
+   Ref<NiTimeController> CreateController(INode *node, Interval range);
+   static void InitializeTimeController(Ref<NiTimeController> ctrl, NiNodeRef parent);
 
    /* misc export */
    bool exportUPB(NiNodeRef &root, INode *node);
@@ -191,6 +223,9 @@ public:
    void sortNodes(NiNodeRef node);
    NiNodeRef exportBone(NiNodeRef parent, INode *node);
    Result exportLight(NiNodeRef root, INode *node, GenLight* light);
+   void getChildNodes(INode *node, vector<NiNodeRef>&list);
+
+   NiNodeRef createAccumNode(NiNodeRef parent, INode *node);
 };
 
 #endif 
diff --git a/NifExport/KfExport.cpp b/NifExport/KfExport.cpp
index 4102b0c8e651f3511caf265f32f1dff1de80dfe4..795136fd360904b9ed992a8051833b1bc319ea7b 100644
--- a/NifExport/KfExport.cpp
+++ b/NifExport/KfExport.cpp
@@ -82,7 +82,7 @@ static BOOL CALLBACK KfExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam
          CheckDlgButton(hWnd, IDC_CHK_LIGHTS, Exporter::mExportLights);
          CheckDlgButton(hWnd, IDC_CHK_CAMERA, Exporter::mExportCameras);
          CheckDlgButton(hWnd, IDC_CHK_TRANSFORMS, Exporter::mExportTransforms);
-         SetDlgItemText(hWnd, IDC_ED_PRIORITY, FormatText("%.4f", Exporter::mDefaultPriority));
+         SetDlgItemText(hWnd, IDC_ED_PRIORITY, FormatText("%.1f", Exporter::mDefaultPriority));
 
          string selection = Exporter::mGameName;
          string version = Exporter::mNifVersion;
diff --git a/NifExport/Mesh.cpp b/NifExport/Mesh.cpp
index 5ed4f0b981edd113885236b58c39e30d23b8a1ed..1601f417f6240e5c97575efb81c19a83cd38826e 100755
--- a/NifExport/Mesh.cpp
+++ b/NifExport/Mesh.cpp
@@ -27,7 +27,6 @@ Exporter::Result Exporter::exportMesh(NiNodeRef &ninode, INode *node, TimeValue
 
 	Mesh *mesh = &tri->GetMesh();
 
-
    // Note that calling setVCDisplayData will clear things like normals so we set this up first
    vector<Color4> vertColors;
    if (mVertexColors)
@@ -35,8 +34,7 @@ Exporter::Result Exporter::exportMesh(NiNodeRef &ninode, INode *node, TimeValue
       bool hasvc = false;
       if (mesh->mapSupport(MAP_ALPHA))
       {
-         mesh->setVCDisplayData(MAP_ALPHA);
-         int n = mesh->getNumVertCol();
+         mesh->setVCDisplayData(MAP_ALPHA);         int n = mesh->getNumVertCol();
          if (n > vertColors.size())
             vertColors.assign(n, Color4(1.0f, 1.0f, 1.0f, 1.0f));
          VertColor *vertCol = mesh->vertColArray;
@@ -133,15 +131,13 @@ NiTriBasedGeomRef Exporter::makeMesh(NiNodeRef &parent, Mtl *mtl, FaceGroup &grp
 
 	if (exportStrips) {
       shape = new NiTriStrips();
-      data = new NiTriStripsData();
+      data = new NiTriStripsData(grp.faces);
 	} else {
       shape = new NiTriShape();
-      data = new NiTriShapeData();
+      data = new NiTriShapeData(grp.faces);
 	}
-
-   data->SetTriangles(grp.faces);
-	data->SetVertices(grp.verts);
-	data->SetNormals(grp.vnorms);
+   data->SetVertices(grp.verts);
+   data->SetNormals(grp.vnorms);
 
 	if (grp.uvs.size() > 0)
 	{
@@ -285,6 +281,9 @@ struct SkinInstance : public Exporter::NiCallback
    // Bone to weight map
    BoneWeightList boneWeights;
 
+   Matrix3 bone_init_tm;
+   Matrix3 node_init_tm;
+
    SkinInstance(Exporter *Owner) : owner(Owner) {}
    virtual ~SkinInstance() {}
    virtual Exporter::Result execute();
@@ -319,6 +318,9 @@ bool Exporter::makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, Ti
    SkinInstance* si = new SkinInstance(this);
    mPostExportCallbacks.push_back(si);
 
+   skin->GetSkinInitTM(node, si->bone_init_tm, false);
+   skin->GetSkinInitTM(node, si->node_init_tm, true);
+
    si->shape = shape;
 
    // Get bone references (may not actually exist in proper structure at this time)
@@ -369,26 +371,29 @@ bool Exporter::makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, Ti
 
 Exporter::Result SkinInstance::execute()
 {
-   shape->BindSkin(boneList);
+   shape->BindSkin(boneList, false);
    uint bone = 0;
    for (BoneWeightList::iterator bitr = boneWeights.begin(); bitr != boneWeights.end(); ++bitr, ++bone) {
       shape->SetBoneWeights(bone, (*bitr));
    }
-   shape->GenHardwareSkinInfo();
+   if (Exporter::mMultiplePartitions)
+      shape->GenHardwareSkinInfo(Exporter::mBonesPerPartition, Exporter::mBonesPerVertex);
+   else
+      shape->GenHardwareSkinInfo(0, 0);
+
+   //NiSkinInstanceRef skinInst = shape->GetSkinInstance();
+   //NiSkinDataRef skinData = skinInst->GetSkinData();
+   //Matrix44 tm = skinData->GetOverallTransform();
+   //Matrix3 otm = TOMATRIX3(tm);
+   //Matrix3 stm = TOMATRIX3(shape->GetLocalTransform());
+   //Matrix3 btm = Inverse(bone_init_tm) * stm;
+
+   //Matrix3 asdf = btm * otm;
+   //skinData->SetOverallTransform(TOMATRIX4(btm));
+      
    return Exporter::Ok;
 }
 
-static void InitializeTimeController(NiTimeControllerRef ctrl, NiNodeRef parent)
-{
-   ctrl->SetFrequency(1.0f);
-   ctrl->SetStartTime(FloatINF);
-   ctrl->SetStopTime(FloatNegINF);
-   ctrl->SetPhase(0.0f);
-   ctrl->SetFlags(0x0C);
-   ctrl->SetTarget( parent );
-   parent->AddController(DynamicCast<NiTimeController>(ctrl));
-}
-
 static void FillBoneController(Exporter* exporter, NiBSBoneLODControllerRef boneCtrl, INode *node)
 {
    for (int i=0; i<node->NumberOfChildren(); i++) 
@@ -552,25 +557,35 @@ NiNodeRef Exporter::exportBone(NiNodeRef parent, INode *node)
          }
       }
 
+      if (mExportType != NIF_WO_ANIM && isNodeTracked(node)) {
+         NiNodeRef accumNode = createAccumNode(newParent, node);
 
-      if (wildmatch("Bip??", node->GetName()))
-      {
-         NiNodeRef accumNode = new NiNode();
-         accumNode->SetName(FormatString("%s NonAccum", node->GetName()));
-         accumNode->SetLocalTransform(Matrix44::IDENTITY);
-         newParent->AddChild(DynamicCast<NiAVObject>(accumNode));
-
-         // Transfer 
+         // Transfer collision object to accum and create blend on accum
          if (mIsBethesda) {
             InitializeTimeController(new bhkBlendController(), accumNode);
             accumNode->SetCollisionObject(newParent->GetCollisionObject());
             newParent->SetCollisionObject( NiCollisionObjectRef() );
-         }
-         InitializeTimeController(new NiTransformController(), accumNode);
-         
+         }        
          newParent = accumNode;
+      } else if (wildmatch("Bip??", node->GetName())) {
+         newParent = createAccumNode(newParent, node);
+      }
+   }
+   else // normal handling
+   {
+      // Check for Accum Root using 
+      if (mExportType == NIF_WO_KF)
+      {
+         // Add controllers
+         if (Exporter::mAllowAccum) {
+            newParent = createAccumNode(newParent, node);
+         }
+      }
+      else if (mExportType != NIF_WO_ANIM && isNodeTracked(node)) 
+      {
+         newParent = createAccumNode(newParent, node);
       }
    }
 
    return newParent;
-}
\ No newline at end of file
+}
diff --git a/NifExport/NifExport.cpp b/NifExport/NifExport.cpp
index 4a7be3b46dcf171409aa11ef92ceb10ffda3f6cd..ee83d42c9622572a5a9e725653ad67db0e088434 100755
--- a/NifExport/NifExport.cpp
+++ b/NifExport/NifExport.cpp
@@ -2,6 +2,9 @@
 #include "AppSettings.h"
 #include "niutils.h"
 #include  <io.h>
+#include "obj/NiControllerManager.h"
+#include "obj/NiTimeController.h"
+#include "obj/NiControllerSequence.h"
 
 using namespace Niflib;
 
@@ -15,6 +18,8 @@ public:
 		
 	static HWND		hParams;
 	int				mDlgResult;
+   TSTR iniFileName;
+   TSTR shortDescription;
 		
 	int				ExtCount();					// Number of extensions supported
 	const TCHAR		*Ext(int n);					// Extension #n (i.e. "3DS")
@@ -55,7 +60,7 @@ class NifExportClassDesc : public ClassDesc2
 static NifExportClassDesc NifExportDesc;
 ClassDesc2* GetNifExportDesc() { return &NifExportDesc; }
 
-
+extern list<NiObjectRef> GetAllObjectsByType( NiObjectRef const & root, const Type & type );
 
 
 
@@ -88,14 +93,13 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
             CheckDlgButton(hWnd, IDC_CHK_REMAP, Exporter::mRemapIndices);
 
             CheckDlgButton(hWnd, IDC_CHK_EXTRA, Exporter::mExportExtraNodes);
-            CheckDlgButton(hWnd, IDC_CHK_SKIN, Exporter::mExportSkin);
             CheckDlgButton(hWnd, IDC_CHK_UPB, Exporter::mUserPropBuffer);
             CheckDlgButton(hWnd, IDC_CHK_HIER, Exporter::mFlattenHierarchy);
             CheckDlgButton(hWnd, IDC_CHK_REM_BONES, Exporter::mRemoveUnreferencedBones);
             CheckDlgButton(hWnd, IDC_CHK_SORTNODES, Exporter::mSortNodesToEnd);
             CheckDlgButton(hWnd, IDC_CHK_SKEL_ONLY, Exporter::mSkeletonOnly);
             CheckDlgButton(hWnd, IDC_CHK_CAMERA, Exporter::mExportCameras);
-            CheckDlgButton(hWnd, IDC_CHK_BONE_COLL, Exporter::mGenerateBoneCollision);
+            CheckDlgButton(hWnd, IDC_CHK_BONE_COLL, Exporter::mGenerateBoneCollision);            
 
             string selection = Exporter::mGameName;
             string version = Exporter::mNifVersion;
@@ -105,6 +109,30 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
             SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_SELECTSTRING, WPARAM(-1), LPARAM(selection.c_str()));
             SendDlgItemMessage(hWnd, IDC_CB_VERSION, WM_SETTEXT, 0, LPARAM(version.c_str()));
             SendDlgItemMessage(hWnd, IDC_CB_USER_VERSION, WM_SETTEXT, 0, LPARAM(userVer.c_str()));
+            CheckDlgButton(hWnd, IDC_CHK_AUTO_DETECT, Exporter::mAutoDetect);
+
+            // Populate Type options
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::NIF_WO_ANIM, LPARAM("NIF w/o Anim"));
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::NIF_WO_KF, LPARAM("NIF with Anim"));
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::SINGLE_KF_WITH_NIF, LPARAM("Single KF with NIF"));
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::SINGLE_KF_WO_NIF, LPARAM("Single KF w/o NIF"));
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::MULTI_KF_WITH_NIF, LPARAM("Multi KF with NIF"));
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::MULTI_KF_WO_NIF, LPARAM("Multi KF w/o NIF"));
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_ADDSTRING, Exporter::NIF_WITH_MGR, LPARAM("NIF w/ Manager"));
+            
+            SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_SETCURSEL, WPARAM(Exporter::mExportType), 0);
+
+            CheckDlgButton(hWnd, IDC_CHK_TRANSFORMS2, Exporter::mExportTransforms);
+            SetDlgItemText(hWnd, IDC_ED_PRIORITY2, FormatText("%.1f", Exporter::mDefaultPriority));
+            CheckDlgButton(hWnd, IDC_CHK_USE_TIME_TAGS, Exporter::mUseTimeTags);           
+
+            // Skin
+            CheckDlgButton(hWnd, IDC_CHK_SKIN, Exporter::mExportSkin);
+            CheckDlgButton(hWnd, IDC_CHK_SKINPART, Exporter::mMultiplePartitions);
+            SetDlgItemText(hWnd, IDC_ED_BONES_PART, FormatText("%d", Exporter::mBonesPerPartition));
+            SetDlgItemText(hWnd, IDC_ED_BONES_VERTEX, FormatText("%d", Exporter::mBonesPerVertex));
+
+            CheckDlgButton(hWnd, IDC_CHK_ALLOW_ACCUM, Exporter::mAllowAccum);
 
 				TSTR tmp;
 				tmp.printf("%.4f", Exporter::mWeldThresh);
@@ -147,7 +175,6 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
 						Exporter::mRemapIndices = IsDlgButtonChecked(hWnd, IDC_CHK_REMAP);
 
                   Exporter::mExportExtraNodes = IsDlgButtonChecked(hWnd, IDC_CHK_EXTRA);
-                  Exporter::mExportSkin = IsDlgButtonChecked(hWnd, IDC_CHK_SKIN);
                   Exporter::mUserPropBuffer = IsDlgButtonChecked(hWnd, IDC_CHK_UPB);
                   Exporter::mFlattenHierarchy = IsDlgButtonChecked(hWnd, IDC_CHK_HIER);
                   Exporter::mRemoveUnreferencedBones = IsDlgButtonChecked(hWnd, IDC_CHK_REM_BONES);
@@ -155,13 +182,30 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
                   Exporter::mSkeletonOnly = IsDlgButtonChecked(hWnd, IDC_CHK_SKEL_ONLY);
                   Exporter::mExportCameras = IsDlgButtonChecked(hWnd, IDC_CHK_CAMERA);
                   Exporter::mGenerateBoneCollision = IsDlgButtonChecked(hWnd, IDC_CHK_BONE_COLL);
-							
+
+                  Exporter::mExportTransforms = IsDlgButtonChecked(hWnd, IDC_CHK_TRANSFORMS2);
+                  Exporter::mUseTimeTags = IsDlgButtonChecked(hWnd, IDC_CHK_USE_TIME_TAGS);           
+
+                  Exporter::mExportType = Exporter::ExportType(SendDlgItemMessage(hWnd, IDC_CBO_ANIM_TYPE, CB_GETCURSEL, 0, 0));
+                  GetDlgItemText(hWnd, IDC_ED_PRIORITY2, tmp, MAX_PATH);
+                  Exporter::mDefaultPriority = atof(tmp);
+
 						GetDlgItemText(hWnd, IDC_ED_TEXPREFIX, tmp, MAX_PATH);
 						Exporter::mTexPrefix = tmp;
 
 						GetDlgItemText(hWnd, IDC_ED_WELDTHRESH, tmp, MAX_PATH);
 						Exporter::mWeldThresh = atof(tmp);
 
+                  Exporter::mAllowAccum = IsDlgButtonChecked(hWnd, IDC_CHK_ALLOW_ACCUM);
+
+                  // Skin
+                  Exporter::mExportSkin = IsDlgButtonChecked(hWnd, IDC_CHK_SKIN);
+                  Exporter::mMultiplePartitions = IsDlgButtonChecked(hWnd, IDC_CHK_SKINPART);
+                  GetDlgItemText(hWnd, IDC_ED_BONES_PART, tmp, MAX_PATH);
+                  Exporter::mBonesPerPartition = atoi(tmp);
+                  GetDlgItemText(hWnd, IDC_ED_BONES_VERTEX, tmp, MAX_PATH);
+                  Exporter::mBonesPerVertex = atoi(tmp);
+
                   GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH);
                   if (AppSettings *appSettings = FindAppSetting(tmp))
                   {
@@ -171,6 +215,7 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
                      GetDlgItemText(hWnd, IDC_CB_USER_VERSION, tmp, MAX_PATH);
                      Exporter::mNifUserVersion = strtol(tmp, &end, 0);
                   }
+                  Exporter::mAutoDetect = IsDlgButtonChecked(hWnd, IDC_CHK_AUTO_DETECT);
 
 						EndDialog(hWnd, imp->mDlgResult=IDOK);
 						close = true;
@@ -217,7 +262,21 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
 //--- NifExport -------------------------------------------------------
 NifExport::NifExport()
 {
-
+   Interface *gi = GetCOREInterface();
+   TCHAR iniName[MAX_PATH];
+   if (gi) {
+      LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR);
+      PathCombine(iniName, pluginDir, "MaxNifTools.ini");
+   } else {
+      GetModuleFileName(NULL, iniName, _countof(iniName));
+      if (LPTSTR fname = PathFindFileName(iniName))
+         fname = NULL;
+      PathAddBackslash(iniName);
+      PathAppend(iniName, "plugcfg");
+      PathAppend(iniName, "MaxNifTools.ini");
+   }
+   iniFileName = iniName;
+   shortDescription = GetIniValue<TSTR>("System", "ShortDescription", "Netimmerse/Gamebryo", iniFileName);
 }
 
 NifExport::~NifExport() 
@@ -227,12 +286,17 @@ NifExport::~NifExport()
 
 int NifExport::ExtCount()
 {
-	return 1;
+	return 2;
 }
 
 const TCHAR *NifExport::Ext(int n)
 {		
-	return _T("nif");
+   switch (n)
+   {
+   case 0: return _T("KF");
+   case 1: return _T("NIF");
+   }
+	return NULL;
 }
 
 const TCHAR *NifExport::LongDesc()
@@ -242,7 +306,7 @@ const TCHAR *NifExport::LongDesc()
 	
 const TCHAR *NifExport::ShortDesc() 
 {			
-	return _T("Gamebryo File");
+	return shortDescription;
 }
 
 const TCHAR *NifExport::AuthorName()
@@ -285,6 +349,10 @@ int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL
 {
 	try
 	{
+      TCHAR path[MAX_PATH];
+      GetFullPathName(name, MAX_PATH, path, NULL);
+      PathRenameExtension(path, ".nif");
+
       // read application settings
       AppSettings::Initialize(i);
 
@@ -304,10 +372,11 @@ int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL
       AppSettings *appSettings = NULL;
       if (iniNameIsValid)
       {
-         string fname = name;
+         string fname = path;
          // Locate which application to use. If Auto, find first app where this file appears in the root path list
          string curapp = GetIniValue<string>(NifExportSection, "CurrentApp", "AUTO", iniName);
          if (0 == _tcsicmp(curapp.c_str(), "AUTO")) {
+            Exporter::mAutoDetect = true;
             // Scan Root paths
             for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){
                if ((*itr).IsFileInRootPaths(fname)) {
@@ -316,6 +385,7 @@ int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL
                }
             }
          } else {
+            Exporter::mAutoDetect = false;
             appSettings = FindAppSetting(curapp);
          }
       }
@@ -340,12 +410,18 @@ int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL
          appSettings = FindAppSetting(Exporter::mGameName);
          if (appSettings == NULL && !TheAppSettings.empty())
             appSettings = &TheAppSettings.front();
+
+         if (Exporter::mAutoDetect){
+            SetIniValue<string>(NifExportSection, "CurrentApp", "AUTO", iniName);
+         } else {
+            SetIniValue<string>(NifExportSection, "CurrentApp", appSettings->Name, iniName);
+         }
+
          appSettings->NiVersion = Exporter::mNifVersion;
          appSettings->NiUserVersion = Exporter::mNifUserVersion;
          appSettings->WriteSettings(i);
       }
 
-
       int nifVersion = VER_20_0_0_5;
       int nifUserVer = Exporter::mNifUserVersion;
 
@@ -355,6 +431,17 @@ int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL
          if (!IsVersionSupported(nifVersion))
             throw exception(FormatString("Version '%s' is not a supported version.").c_str());
       }
+      Exporter::mNifVersionInt = nifVersion;
+
+      Exporter::ExportType exportType = Exporter::mExportType;
+
+      // Hack so MW exports cleaner. Basically write tree without NiControllerManager
+      if (  nifVersion <= VER_10_0_1_0 
+         && (Exporter::mExportType != Exporter::NIF_WO_ANIM && Exporter::mExportType != Exporter::NIF_WITH_MGR)
+         )
+      {
+         Exporter::mExportType = Exporter::NIF_WO_KF;
+      }
 
 		Exporter::mSelectedOnly = (options&SCENE_EXPORT_SELECTED) != 0;
 		Exporter exp(i, appSettings);
@@ -365,7 +452,67 @@ int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL
 		if (result!=Exporter::Ok)
 			throw exception("Unknown error.");
 
-		WriteNifTree(name, NiObjectRef(root), nifVersion, nifUserVer);
+      if (exportType == Exporter::NIF_WO_ANIM || exportType == Exporter::NIF_WITH_MGR)
+      {
+         WriteNifTree(path, NiObjectRef(root), nifVersion, nifUserVer);
+      }
+      else 
+      {
+         Niflib::ExportOptions export_type = EXPORT_NIF;
+         switch (exportType) {
+            case Exporter::SINGLE_KF_WITH_NIF: export_type = EXPORT_NIF_KF;       break;
+            case Exporter::SINGLE_KF_WO_NIF:   export_type = EXPORT_KF;           break;
+            case Exporter::MULTI_KF_WITH_NIF:  export_type = EXPORT_NIF_KF_MULTI; break;
+            case Exporter::MULTI_KF_WO_NIF:    export_type = EXPORT_KF_MULTI;     break;
+         }
+
+         Niflib::NifGame game = KF_MW;
+         if (nifVersion <= VER_4_0_0_2) {
+            game = KF_MW;
+         } else if (nifVersion <= VER_20_0_0_4) {
+            game = KF_DAOC;
+         } else {
+            game = KF_CIV4;
+         }
+
+         // 
+         //if (nifVersion <= VER_10_0_1_0) {
+
+         //   // Now search and locate newer timeframe controllers and convert to keyframecontrollers
+         //   list<NiObjectRef> mgrs = GetAllObjectsByType( root, NiControllerManager::TypeConst() );
+         //   for ( list<NiObjectRef>::iterator it = mgrs.begin(); it != mgrs.end(); ++it) {
+         //      if (NiControllerManagerRef mgr = DynamicCast<NiControllerManager>(*it)) {
+         //         NiObjectNETRef target = mgr->GetTarget();
+         //         target->RemoveController( StaticCast<NiTimeController>(mgr) );
+         //         vector<NiControllerSequenceRef> seqs = mgr->GetControllerSequences();
+         //         for (vector<NiControllerSequenceRef>::iterator itr = seqs.begin(); itr != seqs.end(); ++itr) {
+         //            NiControllerSequenceRef seq = (*itr);
+         //            MergeNifTrees(DynamicCast<NiNode>(target), seq, nifVersion, nifUserVer);
+         //         }
+         //      }
+         //   }
+         //}
+
+         WriteFileGroup(path, StaticCast<NiObject>(root), nifVersion, nifUserVer, export_type, game);
+/*
+         for (NodeList::iterator itr = mAnimationRoots.begin(); itr != mAnimationRoots.end(); ++itr){
+            list<NiTimeControllerRef> ctlrs = (*itr)->GetControllers();
+            if ( NiControllerManagerRef mgr = SelectFirstObjectOfType<NiControllerManager>( ctlrs ) ) {
+               (*itr)->RemoveController( mgr );
+
+               vector<NiControllerSequenceRef> seqs = mgr->GetControllerSequences();
+               WriteNifTree()
+            }
+         }
+
+         if (mExportType == SINGLE_KF_WITH_NIF || mExportType == MULTI_KF_WITH_NIF)
+         {
+            GetFullPathName(name, MAX_PATH, path, NULL);
+            PathRenameExtension(path, ".nif");
+            WriteNifTree(path, NiObjectRef(root), nifVersion, nifUserVer);
+         }
+*/
+      }
 	}
 
 	catch (exception &e)
diff --git a/NifExport/NifExport.rc b/NifExport/NifExport.rc
index e9f8667ef76badcbcc0debc9b014428f172e567a..c9eb4b768211a5802817a5b9e6fe3f3d953219ff 100755
--- a/NifExport/NifExport.rc
+++ b/NifExport/NifExport.rc
@@ -98,44 +98,59 @@ BEGIN
     LTEXT           "http://www.niftools.org",IDC_LBL_LINK,103,109,95,14,SS_NOTIFY | SS_CENTERIMAGE
 END
 
-IDD_NIF_PANEL DIALOGEX 0, 0, 205, 203
+IDD_NIF_PANEL DIALOGEX 0, 0, 229, 291
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_TOOLWINDOW
 CAPTION "Export Nif"
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    GROUPBOX        "Export:",IDC_STATIC,7,7,81,107
-    CONTROL         "&Hidden Nodes",IDC_CHK_HIDDEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,17,67,10
-    CONTROL         "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,29,67,10
-    CONTROL         "&Vertex Colors",IDC_CHK_VCOLORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,41,67,10
-    CONTROL         "Skin Modifier",IDC_CHK_SKIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,53,67,10
-    CONTROL         "&Animation",IDC_CHK_ANIMATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,65,67,10
-    CONTROL         "Furniture &Markers",IDC_CHK_FURN,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,14,101,67,10
-    CONTROL         "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,77,67,10
-    CONTROL         "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,89,67,10
-    GROUPBOX        "Behaviors:",IDC_STATIC,94,7,104,107
-    CONTROL         "Generate &Strips",IDC_CHK_STRIPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,17,88,10
-    CONTROL         "Extra Nodes on Mesh",IDC_CHK_EXTRA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,28,88,11
-    CONTROL         "Add User Prop Buffer",IDC_CHK_UPB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,40,88,11
-    CONTROL         "Flatten Hierarchy",IDC_CHK_HIER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,52,88,10
-    CONTROL         "Remove Extra Bones",IDC_CHK_REM_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,64,88,10
-    CONTROL         "Sort Nodes",IDC_CHK_SORTNODES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,76,88,10
-    CONTROL         "&Remap Indices",IDC_CHK_REMAP,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,102,100,88,10
-    CONTROL         "Skeleton Only",IDC_CHK_SKEL_ONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,88,71,10
-    LTEXT           "Default Texture &Prefix:",IDC_STATIC,7,127,71,8
-    EDITTEXT        IDC_ED_TEXPREFIX,7,138,190,12,ES_AUTOHSCROLL
-    LTEXT           "Game",IDC_STATIC,7,154,66,8
-    COMBOBOX        IDC_CB_GAME,7,165,105,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "Version",IDC_STATIC,117,154,39,8
-    EDITTEXT        IDC_CB_VERSION,117,165,45,12,ES_AUTOHSCROLL
-    LTEXT           "User",IDC_STATIC,167,154,25,8
-    EDITTEXT        IDC_CB_USER_VERSION,167,165,30,12,ES_AUTOHSCROLL
-    DEFPUSHBUTTON   "&Export",IDOK,5,182,34,14
-    PUSHBUTTON      "&Cancel",IDCANCEL,45,182,33,14
-    LTEXT           "http://www.niftools.org",IDC_LBL_LINK,103,182,95,14,SS_NOTIFY | SS_CENTERIMAGE
-    EDITTEXT        IDC_ED_WELDTHRESH,185,118,11,12,ES_AUTOHSCROLL | NOT WS_VISIBLE | WS_DISABLED
-    LTEXT           "Auto-&Weld",IDC_LBL_WELDTHRESH,175,118,8,8,NOT WS_VISIBLE | WS_DISABLED
-    CONTROL         "Gen. Bone Collision",IDC_CHK_BONE_COLL,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,100,118,73,10
+    GROUPBOX        "General Options",IDC_STATIC,4,7,220,60
+    LTEXT           "Game",IDC_STATIC,10,16,66,8
+    COMBOBOX        IDC_CB_GAME,10,25,105,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Version",IDC_STATIC,118,16,39,8
+    EDITTEXT        IDC_CB_VERSION,118,25,41,12,ES_AUTOHSCROLL
+    LTEXT           "User",IDC_STATIC,163,16,25,8
+    EDITTEXT        IDC_CB_USER_VERSION,162,25,22,12,ES_AUTOHSCROLL
+    CONTROL         "Auto Detect",IDC_CHK_AUTO_DETECT,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,188,23,35,16
+    LTEXT           "Default Texture &Prefix:",IDC_STATIC,10,40,71,8
+    EDITTEXT        IDC_ED_TEXPREFIX,9,50,208,12,ES_AUTOHSCROLL
+    GROUPBOX        "Export:",IDC_STATIC,4,70,220,50
+    CONTROL         "&Hidden Nodes",IDC_CHK_HIDDEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,81,67,10
+    CONTROL         "Skeleton Only",IDC_CHK_SKEL_ONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,82,10
+    CONTROL         "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,105,67,10
+    CONTROL         "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,82,67,10
+    CONTROL         "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,93,67,10
+    CONTROL         "Furniture &Markers",IDC_CHK_FURN,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,120,105,67,10
+    GROUPBOX        "Mesh:",IDC_STATIC,4,123,108,73
+    CONTROL         "Generate &Strips",IDC_CHK_STRIPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,134,82,10
+    CONTROL         "Extra Nodes on Mesh",IDC_CHK_EXTRA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,145,82,11
+    CONTROL         "Flatten Hierarchy",IDC_CHK_HIER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,158,82,10
+    CONTROL         "Remove Extra Bones",IDC_CHK_REM_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,169,82,10
+    CONTROL         "&Vertex Colors",IDC_CHK_VCOLORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,181,67,10
+    GROUPBOX        "Skin Modifier",IDC_STATIC,116,123,108,73
+    CONTROL         "Export Skin Modifier",IDC_CHK_SKIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,134,93,10
+    LTEXT           "Bones Per Vertex:",IDC_LBL_BONES_VERTEX,120,174,63,8
+    EDITTEXT        IDC_ED_BONES_VERTEX,195,173,24,12,ES_AUTOHSCROLL
+    LTEXT           "Bones Per Partition:",IDC_LBL_BONES_PART,130,160,62,8
+    EDITTEXT        IDC_ED_BONES_PART,195,158,24,12,ES_AUTOHSCROLL
+    CONTROL         "Gen. Bone Collision",IDC_CHK_BONE_COLL,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,151,7,73,10
+    CONTROL         "&Remap Indices",IDC_CHK_REMAP,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,152,7,72,10
+    GROUPBOX        "Animation",IDC_GRP_ANIMATION,4,196,108,68
+    COMBOBOX        IDC_CBO_ANIM_TYPE,7,207,85,69,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Transforms",IDC_CHK_TRANSFORMS2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,223,67,10
+    LTEXT           "Priority:",IDC_LBL_PRIORITY2,9,249,23,8
+    EDITTEXT        IDC_ED_PRIORITY2,37,248,55,12,ES_AUTOHSCROLL
+    GROUPBOX        "Miscellaneous:",IDC_STATIC,115,196,109,68
+    CONTROL         "Add User Prop Buffer",IDC_CHK_UPB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,209,82,11
+    CONTROL         "Sort Nodes",IDC_CHK_SORTNODES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,222,82,10
+    LTEXT           "Auto-&Weld",IDC_LBL_WELDTHRESH,125,249,47,8,NOT WS_VISIBLE | WS_DISABLED
+    EDITTEXT        IDC_ED_WELDTHRESH,179,247,43,12,ES_AUTOHSCROLL | NOT WS_VISIBLE | WS_DISABLED
+    DEFPUSHBUTTON   "&Export",IDOK,5,270,34,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,45,270,33,14
+    LTEXT           "http://www.niftools.org",IDC_LBL_LINK,148,270,76,14,SS_NOTIFY | SS_CENTERIMAGE
+    CONTROL         "Enable Multiple Partitions",IDC_CHK_SKINPART,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,147,93,10
+    CONTROL         "Use Time Tags",IDC_CHK_USE_TIME_TAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,235,96,10
+    CONTROL         "Add Accum Nodes",IDC_CHK_ALLOW_ACCUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,235,82,10
 END
 
 
@@ -157,10 +172,10 @@ BEGIN
 
     IDD_NIF_PANEL, DIALOG
     BEGIN
-        LEFTMARGIN, 7
-        RIGHTMARGIN, 198
+        LEFTMARGIN, 4
+        RIGHTMARGIN, 224
         TOPMARGIN, 7
-        BOTTOMMARGIN, 196
+        BOTTOMMARGIN, 284
     END
 END
 #endif    // APSTUDIO_INVOKED
@@ -172,8 +187,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,4,0
- PRODUCTVERSION 0,2,4,0
+ FILEVERSION 0,2,5,0
+ PRODUCTVERSION 0,2,5,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -189,12 +204,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Exporter"
-            VALUE "FileVersion", "0, 2, 4, 0"
+            VALUE "FileVersion", "0, 2, 5, 0"
             VALUE "InternalName", "NifExport.dle"
             VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved."
             VALUE "OriginalFilename", "NifExport.dle"
             VALUE "ProductName", "3ds Max Nif Exporter"
-            VALUE "ProductVersion", "0, 2, 4, 0"
+            VALUE "ProductVersion", "0, 2, 5, 0"
         END
     END
     BLOCK "VarFileInfo"
@@ -204,6 +219,19 @@ BEGIN
 END
 
 
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog Info
+//
+
+IDD_NIF_PANEL DLGINIT
+BEGIN
+    IDC_CBO_ANIM_TYPE, 0x403, 15, 0
+0x494e, 0x2046, 0x6977, 0x6874, 0x4e20, 0x206f, 0x464b, "\000" 
+    0
+END
+
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // String Table
diff --git a/NifExport/NifExport_VC80.vcproj b/NifExport/NifExport_VC80.vcproj
index e1997b4f727ae3659f13f70fb9c4d97a32ef3d48..3693d6dfd2f7cbb366c0eb0b6f75822dc05f1785 100644
--- a/NifExport/NifExport_VC80.vcproj
+++ b/NifExport/NifExport_VC80.vcproj
@@ -53,7 +53,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS"
 				StringPooling="true"
 				ExceptionHandling="2"
@@ -81,7 +81,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib niflib.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib"
 				OutputFile="c:\3dsmax8\plugins\NifExport.dle"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -155,7 +155,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/LD /FI&quot;$(ProjectDir)pch.h&quot; /Zm200"
 				Optimization="0"
-				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS"
 				StringPooling="true"
 				MinimalRebuild="true"
@@ -183,7 +183,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib niflibd.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib"
 				OutputFile="c:\3dsmax8\plugins\NifExport.dle"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
@@ -252,7 +252,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/LD /FI&quot;$(ProjectDir)pch.h&quot; /Zm200"
 				Optimization="0"
-				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS"
 				StringPooling="true"
 				MinimalRebuild="true"
@@ -280,7 +280,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib niflibd.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib"
 				OutputFile="c:\3dsmax6\plugins\NifExport.dle"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
@@ -355,7 +355,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS"
 				StringPooling="true"
 				ExceptionHandling="2"
@@ -383,7 +383,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib niflib.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib"
 				OutputFile="c:\3dsmax6\plugins\NifExport.dle"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -463,7 +463,7 @@
 				EnableIntrinsicFunctions="true"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="true"
-				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS"
 				StringPooling="true"
 				ExceptionHandling="2"
@@ -491,7 +491,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib niflib.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib"
 				OutputFile="c:\3dsmax7\plugins\NifExport.dle"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -565,7 +565,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/LD /FI&quot;$(ProjectDir)pch.h&quot; /Zm200"
 				Optimization="0"
-				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS"
 				StringPooling="true"
 				MinimalRebuild="true"
@@ -593,7 +593,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib niflibd.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib"
 				OutputFile="c:\3dsmax7\plugins\NifExport.dle"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
@@ -743,230 +743,6 @@
 				RelativePath="Util.cpp"
 				>
 			</File>
-			<Filter
-				Name="NvTriStrip"
-				>
-				<File
-					RelativePath="NvTriStrip\NvTriStrip.cpp"
-					>
-					<FileConfiguration
-						Name="Release - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-				</File>
-				<File
-					RelativePath="NvTriStrip\NvTriStripObjects.cpp"
-					>
-					<FileConfiguration
-						Name="Release - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-				</File>
-				<File
-					RelativePath="NvTriStrip\VertexCache.cpp"
-					>
-					<FileConfiguration
-						Name="Release - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-				</File>
-			</Filter>
-			<Filter
-				Name="TriStripper"
-				>
-				<File
-					RelativePath=".\TriStripper\connectivity_graph.cpp"
-					>
-				</File>
-				<File
-					RelativePath=".\TriStripper\policy.cpp"
-					>
-				</File>
-				<File
-					RelativePath="TriStripper\tri_stripper.cpp"
-					>
-					<FileConfiguration
-						Name="Release - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 8|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 6|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Release - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-					<FileConfiguration
-						Name="Debug - Max 7|Win32"
-						>
-						<Tool
-							Name="VCCLCompilerTool"
-							UsePrecompiledHeader="0"
-						/>
-					</FileConfiguration>
-				</File>
-			</Filter>
 		</Filter>
 		<Filter
 			Name="Header Files"
@@ -988,50 +764,6 @@
 				RelativePath=".\resource.h"
 				>
 			</File>
-			<Filter
-				Name="NvTriStrip"
-				>
-				<File
-					RelativePath="NvTriStrip\NvTriStrip.h"
-					>
-				</File>
-				<File
-					RelativePath="NvTriStrip\NvTriStripObjects.h"
-					>
-				</File>
-				<File
-					RelativePath="NvTriStrip\VertexCache.h"
-					>
-				</File>
-			</Filter>
-			<Filter
-				Name="TriStripper"
-				>
-				<File
-					RelativePath=".\TriStripper\detail\cache_simulator.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TriStripper\detail\connectivity_graph.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TriStripper\detail\graph_array.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TriStripper\detail\heap_array.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TriStripper\detail\policy.h"
-					>
-				</File>
-				<File
-					RelativePath=".\TriStripper\detail\types.h"
-					>
-				</File>
-			</Filter>
 		</Filter>
 		<Filter
 			Name="Resource Files"
diff --git a/NifExport/Strips.cpp b/NifExport/Strips.cpp
index 7ca4f350a6f5b75da98ca927bcb1eaede3a5f649..a69a666bd87683b735c34910a294edeed6b68467 100755
--- a/NifExport/Strips.cpp
+++ b/NifExport/Strips.cpp
@@ -1,5 +1,6 @@
 #include "pch.h"
 
+/*
 using namespace triangle_stripper;
 
 void Exporter::strippify(TriStrips &strips, vector<Vector3> &verts, vector<Vector3> &norms, const Triangles &tris)
@@ -69,7 +70,7 @@ void Exporter::strippify(TriStrips &strips, vector<Vector3> &verts, vector<Vecto
 		strips.push_back(strip);
 	}
 }
-
+*/
 void Exporter::strippify(FaceGroup &grp)
 {
    TriStrips &strips = grp.strips;
diff --git a/NifExport/Util.cpp b/NifExport/Util.cpp
index 4c161845b722d49fae0b71c8d0ba9aefc559a309..6dd15345265f84ad5105f6ee20980af7a677330f 100755
--- a/NifExport/Util.cpp
+++ b/NifExport/Util.cpp
@@ -4,6 +4,7 @@
 #include <obj/NiPointLight.h>
 #include <obj/NiDirectionalLight.h>
 #include <obj/NiSpotLight.h>
+#include <obj/NiTimeController.h>
 
 bool Exporter::TMNegParity(const Matrix3 &m)
 {
@@ -66,9 +67,12 @@ Matrix3 Exporter::getTransform(INode *node, TimeValue t, bool local)
    Matrix3 tm = node->GetObjTMAfterWSM(t);
    if (local)
    {
-      Matrix3 pm = node->GetParentTM(t);
-      pm.Invert();
-      tm *= pm;
+      INode *parent = node->GetParentNode();
+      if (parent != NULL) {
+         Matrix3 pm = parent->GetObjTMAfterWSM(t);
+         pm.Invert();
+         tm *= pm;
+      }
    }
    return tm;
 }
@@ -125,6 +129,10 @@ NiNodeRef Exporter::makeNode(NiNodeRef &parent, INode *maxNode, bool local)
 
    exportUPB(node, maxNode);
 
+   // Normal Embedded Animation 
+   if (mExportType == NIF_WO_KF)
+      CreateController(maxNode, mI->GetAnimRange());
+
 	parent->AddChild(DynamicCast<NiAVObject>(node));
 	return node;
 }
@@ -412,3 +420,14 @@ void Exporter::CalcBoundingSphere(INode *node, Point3 center, float& radius, int
    }
 }
 
+
+
+void Exporter::getChildNodes(INode *node, vector<NiNodeRef>& list)
+{
+   for (int i=0; i<node->NumberOfChildren(); i++) 
+   {
+      INode * child = node->GetChildNode(i);
+      list.push_back( getNode(child->GetName()) );
+      getChildNodes(child, list);
+   }
+}
diff --git a/NifExport/pch.h b/NifExport/pch.h
index a965e1cc70218e5c7655f8f7efff909fd2b0f183..d697250272c056e7484c56bef7af72f173428eb5 100755
--- a/NifExport/pch.h
+++ b/NifExport/pch.h
@@ -39,10 +39,13 @@
 #include "obj/bhkRigidBodyT.h"
 
 // undef macros for tristripper
-#undef max
-#undef min
-#include "NvTriStrip/NvTriStrip.h"
-#include "TriStripper/tri_stripper.h"
+//#undef max
+//#undef min
+#include "../NvTriStrip/NvTriStrip.h"
+//#include "TriStripper/detail/types.h"
+//#include "TriStripper/detail/policy.h"
+//#include "TriStripper/detail/cache_simulator.h"
+//#include "TriStripper/tri_stripper.h"
 
 #include "NifPlugins.h"
 #include "Exporter.h"
diff --git a/NifExport/resource.h b/NifExport/resource.h
index 3d67a7f977ff854f1ab41c0ba34a65177ff3043a..75ae16849ebed96cfab43eb1e9776a0e7b26d5e4 100755
--- a/NifExport/resource.h
+++ b/NifExport/resource.h
@@ -33,6 +33,7 @@
 #define IDC_CB_USER_VERSION             1016
 #define IDC_CHK_SKIN                    1017
 #define IDC_CHK_ANIMATION               1018
+#define IDC_LBL_PRIORITY2               1018
 #define IDC_CHK_EXTRA                   1019
 #define IDC_CHK_UPB                     1020
 #define IDC_CHK_HIER                    1021
@@ -43,7 +44,21 @@
 #define IDC_CHK_SKEL_ONLY2              1026
 #define IDC_CHK_BONE_COLL               1026
 #define IDC_CHK_TRANSFORMS              1026
-#define IDC_EDIT1                       1027
+#define IDC_CHK_TRANSFORMS2             1027
+#define IDC_GRP_ANIMATION               1028
+#define IDC_ED_PRIORITY2                1029
+#define IDC_CBO_ACCUM                   1030
+#define IDC_CHK_USE_TIME_TAGS           1030
+#define IDC_CBO_ANIM_TYPE               1031
+#define IDC_CHECK1                      1032
+#define IDC_CHK_AUTO_DETECT             1032
+#define IDC_CHK_SORTNODES2              1033
+#define IDC_CHK_ALLOW_ACCUM             1033
+#define IDC_LBL_BONES_VERTEX            1034
+#define IDC_ED_BONES_VERTEX             1035
+#define IDC_LBL_BONES_PART              1036
+#define IDC_ED_BONES_PART               1037
+#define IDC_CHK_SKINPART                1038
 #define IDC_COLOR                       1456
 #define IDC_EDIT                        1490
 #define IDC_SPIN                        1496
@@ -52,9 +67,9 @@
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_RESOURCE_VALUE        103
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1028
+#define _APS_NEXT_CONTROL_VALUE         1033
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/NifFurniture/NifFurniture.rc b/NifFurniture/NifFurniture.rc
index 3c75f27838963c2b7681050ae1b370c57ee8180b..84545f4dbd180b9e1649b1c3705e7567c342f763 100755
--- a/NifFurniture/NifFurniture.rc
+++ b/NifFurniture/NifFurniture.rc
@@ -107,8 +107,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,4,0
- PRODUCTVERSION 0,2,4,0
+ FILEVERSION 0,2,5,0
+ PRODUCTVERSION 0,2,5,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -124,12 +124,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Furniture Plugin"
-            VALUE "FileVersion", "0, 2, 4, 0"
+            VALUE "FileVersion", "0, 2, 5, 0"
             VALUE "InternalName", "NifFurniture.dlu"
             VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved."
             VALUE "OriginalFilename", "NifFurniture.dlu"
             VALUE "ProductName", "3ds Max Nif Furniture Plugin"
-            VALUE "ProductVersion", "0, 2, 4, 0"
+            VALUE "ProductVersion", "0, 2, 5, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp
index 58494607f163373e7991f65ffd03946a173b3287..e86545c229da6f7f7b369a48679ebcf8ce8cee7f 100644
--- a/NifImport/ImportAnimation.cpp
+++ b/NifImport/ImportAnimation.cpp
@@ -286,78 +286,65 @@ static FPValue myAddNewNoteKey(Value* noteTrack, int frame)
    return retVal;
 }
 
-bool KFMImporter::ImportAnimation()
+bool NifImporter::AddNoteTracks(float time, string name, string target, NiTextKeyExtraDataRef textKeyData, bool loop)
 {
-   bool ok = false;
-   int curFrame = 0;
-   // Read Kf files
-
-   AnimationImport ai(*this);
-
-   float time = 0.0f;
-   for(vector<NiControllerSequenceRef>::iterator itr = kf.begin(); itr != kf.end(); ++itr){
-
-      float minTime = 1e+35f;
-      float maxTime = 0.0f;
-
-      NiControllerSequenceRef cntr = (*itr);
-      float start = cntr->GetStartTime();
-      float stop = cntr->GetStopTime();
-      float total = (stop - start);
+   vector<StringKey> textKeys = textKeyData->GetKeys();
+   if (!textKeys.empty()) {
 
-      vector<ControllerLink> links = cntr->GetControllerData();
-
-      NiTextKeyExtraDataRef textKeyData = cntr->GetTextKeyExtraData();
-      vector<StringKey> textKeys = textKeyData->GetKeys();
-      if (!textKeys.empty()) {
+      Interval range = gi->GetAnimRange();
+      for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
+         TimeValue t = TimeToFrame(time + (*itr).time);
+         if (t < range.Start())
+            range.SetStart(t);
+         if (t > range.End())
+            range.SetEnd(t);
+      }
+      gi->SetAnimRange(range);
 
-         if (addNoteTracks) {
-            string target = cntr->GetTargetName();
-            if ( INode *n = gi->GetINodeByName(target.c_str()) ) {
+      if (addNoteTracks && (wildmatch("start*", textKeys.front().data)) ) {
+         if ( INode *n = gi->GetINodeByName(target.c_str()) ) {
 #if 1
-               DefNoteTrack* nt = (DefNoteTrack*)NewDefaultNoteTrack();
-               n->AddNoteTrack(nt);
-
-               for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
-                  TimeValue t = TimeToFrame(time + (*itr).time);
-
-                  if (wildmatch("start*", (*itr).data)){
-                     stringlist args = TokenizeCommandLine((*itr).data.c_str(), true);
-                     if (args.empty()) continue;
-                     bool hasName = false;
-                     bool hasLoop = false;
-                     CycleType ct = cntr->GetCycleType();
-                     for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
-                        if (strmatch("-name", *itr)) {
-                           if (++itr == args.end()) break;                       
-                           hasName = true;
-                        } else if (strmatch("-loop", *itr)) {
-                           hasLoop = true;
-                        }
+            DefNoteTrack* nt = (DefNoteTrack*)NewDefaultNoteTrack();
+            n->AddNoteTrack(nt);
+
+            for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
+               TimeValue t = TimeToFrame(time + (*itr).time);
+
+               if (wildmatch("start*", (*itr).data)){
+                  stringlist args = TokenizeCommandLine((*itr).data.c_str(), true);
+                  if (args.empty()) continue;
+                  bool hasName = false;
+                  bool hasLoop = false;
+                  for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
+                     if (strmatch("-name", *itr)) {
+                        if (++itr == args.end()) break;                       
+                        hasName = true;
+                     } else if (strmatch("-loop", *itr)) {
+                        hasLoop = true;
                      }
-                     if (!hasName) {
-                        string name = cntr->GetName();
-                        if (name.empty())
-                           name = FormatString("EMPTY_SEQUENCE_AT_%df", int(t * FramesPerSecond / TicksPerFrame) );
-                        args.push_back("-name");
-                        args.push_back(name);
-                     }
-                     if (!hasLoop && ct == CYCLE_LOOP) {
-                        args.push_back("-loop");
-                     }
-
-                     string line = JoinCommandLine(args);
-                     NoteKey *key = new NoteKey(t, line.c_str(), 0);
-                     nt->keys.Append(1, &key);
-                  } else {
-                     NoteKey *key = new NoteKey(t, (*itr).data.c_str(), 0);
-                     nt->keys.Append(1, &key);
                   }
+                  if (!hasName) {
+                     if (name.empty())
+                        name = FormatString("EMPTY_SEQUENCE_AT_%df", int(t * FramesPerSecond / TicksPerFrame) );
+                     args.push_back("-name");
+                     args.push_back(name);
+                  }
+                  if (!hasLoop && loop) {
+                     args.push_back("-loop");
+                  }
+
+                  string line = JoinCommandLine(args);
+                  NoteKey *key = new NoteKey(t, line.c_str(), 0);
+                  nt->keys.Append(1, &key);
+               } else {
+                  NoteKey *key = new NoteKey(t, (*itr).data.c_str(), 0);
+                  nt->keys.Append(1, &key);
                }
+            }
 
 #else
-               TSTR script;
-               script += 
+            TSTR script;
+            script += 
                "fn getActorManager obj = (\n"
                "   local nt = undefined\n"
                "   n = numNoteTracks obj\n"
@@ -374,58 +361,86 @@ bool KFMImporter::ImportAnimation()
                "   Key.value = tag\n"
                ")\n";
 
-               script += FormatText("nt = getActorManager $'%s'\n", target.c_str());
-               
-               for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
-                  TimeValue t = TimeToFrame(time + (*itr).time);
-
-                  if (wildmatch("start*", (*itr).data)){
-                     stringlist args = TokenizeCommandLine((*itr).data.c_str(), true);
-                     if (args.empty()) continue;
-                     bool hasName = false;
-                     bool hasLoop = false;
-                     CycleType ct = cntr->GetCycleType();
-                     for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
-                        if (strmatch("-name", *itr)) {
-                           if (++itr == args.end()) break;                       
-                           hasName = true;
-                        } else if (strmatch("-loop", *itr)) {
-                           hasLoop = true;
-                        }
-                     }
-                     if (!hasName) {
-                        string name = cntr->GetName();
-                        if (name.empty())
-                           name = FormatString("EMPTY_SEQUENCE_AT_%df", int(t * FramesPerSecond / TicksPerFrame) );
-                        args.push_back("-name");
-                        args.push_back(name);
+            script += FormatText("nt = getActorManager $'%s'\n", target.c_str());
+
+            for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
+               TimeValue t = TimeToFrame(time + (*itr).time);
+
+               if (wildmatch("start*", (*itr).data)){
+                  stringlist args = TokenizeCommandLine((*itr).data.c_str(), true);
+                  if (args.empty()) continue;
+                  bool hasName = false;
+                  bool hasLoop = false;
+                  CycleType ct = cntr->GetCycleType();
+                  for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) {
+                     if (strmatch("-name", *itr)) {
+                        if (++itr == args.end()) break;                       
+                        hasName = true;
+                     } else if (strmatch("-loop", *itr)) {
+                        hasLoop = true;
                      }
-                     if (!hasLoop && ct == CYCLE_LOOP) {
-                        args.push_back("-loop");
-                     }
-                     
-                     string line = JoinCommandLine(args);
-                     script += FormatText("addNoteKey nt (%d/ticksPerFrame) \"%s\"\n", t, line.c_str());
-                  } else {
-                     script += FormatText("addNoteKey nt (%d/ticksPerFrame) \"%s\"\n", t, (*itr).data.c_str());
+                  }
+                  if (!hasName) {
+                     string name = cntr->GetName();
+                     if (name.empty())
+                        name = FormatString("EMPTY_SEQUENCE_AT_%df", int(t * FramesPerSecond / TicksPerFrame) );
+                     args.push_back("-name");
+                     args.push_back(name);
+                  }
+                  if (!hasLoop && ct == CYCLE_LOOP) {
+                     args.push_back("-loop");
                   }
 
-                  //NoteKey *key = new NoteKey(TimeToFrame(time + (*itr).time), (*itr).data.c_str(), 0);
-                  //nt->keys.Append(1, &key);
+                  string line = JoinCommandLine(args);
+                  script += FormatText("addNoteKey nt (%d/ticksPerFrame) \"%s\"\n", t, line.c_str());
+               } else {
+                  script += FormatText("addNoteKey nt (%d/ticksPerFrame) \"%s\"\n", t, (*itr).data.c_str());
                }
-               ExecuteMAXScriptScript(script, TRUE, NULL);
-#endif
+
+               //NoteKey *key = new NoteKey(TimeToFrame(time + (*itr).time), (*itr).data.c_str(), 0);
+               //nt->keys.Append(1, &key);
             }
+            ExecuteMAXScriptScript(script, TRUE, NULL);
+#endif
          }
+      }
 
-         if (addTimeTags) {
-            if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) {
-               for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
-                  tagMgr->CreateNewTag(const_cast<TCHAR*>((*itr).data.c_str()), TimeToFrame(time + (*itr).time), 0, FALSE);
-               }
+      if (addTimeTags) {
+         if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) {
+            for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) {
+               tagMgr->CreateNewTag(const_cast<TCHAR*>((*itr).data.c_str()), TimeToFrame(time + (*itr).time), 0, FALSE);
             }
          }
       }
+      return true;
+   }
+   return false;
+}
+
+bool KFMImporter::ImportAnimation()
+{
+   bool ok = false;
+   int curFrame = 0;
+   // Read Kf files
+
+   AnimationImport ai(*this);
+
+   float time = 0.0f;
+   for(vector<NiControllerSequenceRef>::iterator itr = kf.begin(); itr != kf.end(); ++itr){
+
+      float minTime = 1e+35f;
+      float maxTime = 0.0f;
+
+      NiControllerSequenceRef cntr = (*itr);
+      float start = cntr->GetStartTime();
+      float stop = cntr->GetStopTime();
+      float total = (stop - start);
+
+      vector<ControllerLink> links = cntr->GetControllerData();
+
+      NiTextKeyExtraDataRef textKeyData = cntr->GetTextKeyExtraData();
+      AddNoteTracks( time, cntr->GetName(), cntr->GetTargetName(), textKeyData, (CYCLE_LOOP == cntr->GetCycleType()) );
+
       for (vector<ControllerLink>::iterator lnk=links.begin(); lnk != links.end(); ++lnk)
       {
          string name = (*lnk).targetName;
@@ -589,7 +604,11 @@ bool AnimationImport::AddValues(NiObjectNETRef nref)
    if (NULL == c)
       return false;
 
-   float time = FramesIncrement;
+   if (NiTextKeyExtraDataRef keydata = SelectFirstObjectOfType<NiTextKeyExtraData>(nref->GetExtraData())) {
+      ni.AddNoteTracks(0.0f, string(), nref->GetName(), keydata, false);
+   }
+
+   float time = 0.0f;
    list< NiTimeControllerRef > clist = nref->GetControllers();
    if (NiTransformControllerRef tc = SelectFirstObjectOfType<NiTransformController>(clist)) {
       if (NiTransformInterpolatorRef interp = tc->GetInterpolator()) {
diff --git a/NifImport/MaxNifImport.rc b/NifImport/MaxNifImport.rc
index 6ca19508c6329bf51f5241e622a9db3dd1ccbcda..b46336ffd8137720ed66642f1ab73a5b7a30b0e3 100644
--- a/NifImport/MaxNifImport.rc
+++ b/NifImport/MaxNifImport.rc
@@ -26,38 +26,45 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 // Dialog
 //
 
-IDD_NIF_PANEL DIALOGEX 0, 0, 218, 193
+IDD_NIF_PANEL DIALOGEX 0, 0, 211, 257
 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_TOOLWINDOW
 CAPTION "Import Nif"
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    GROUPBOX        "Import:",IDC_STATIC,7,6,81,105
-    CONTROL         "&Skeleton",IDC_CHK_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,16,67,10
-    CONTROL         "S&kin Modifier",IDC_CHK_SKIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,27,67,10
-    CONTROL         "Vertex &Colors",IDC_CHK_VCOLORS,"Button",BS_AUTO3STATE | WS_TABSTOP,14,38,67,10
-    CONTROL         "&Animation",IDC_CHK_ANIMATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,50,67,10
-    CONTROL         "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,62,67,10
-    CONTROL         "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,74,67,10
-    CONTROL         "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,86,67,10
-    CONTROL         "Furniture &Markers",IDC_CHK_FURN,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,97,67,10
-    CONTROL         "Flip U&V",IDC_CHK_FLIP_UV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,16,88,10
-    CONTROL         "&Render Textures in View",IDC_CHK_SHOW_TEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,27,88,10
-    CONTROL         "Auto Sm&ooth Mesh",IDC_CHK_AUTOSMOOTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,38,88,11
-    CONTROL         "Remove &Illegal Faces",IDC_CHK_ILLEGAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,50,88,11
-    CONTROL         "Remove &Unused Bones",IDC_CHK_REM_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,62,88,10
-    CONTROL         "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,73,88,10
-    CONTROL         "Ignore User Prop Buffers",IDC_CHK_UPB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,86,89,10
-    GROUPBOX        "Behaviors:",IDC_STATIC,94,6,101,105
-    CONTROL         "Use &Biped",IDC_CHK_BIPED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,102,98,87,10
-    LTEXT           "Game:",IDC_STATIC,7,129,31,8
-    COMBOBOX        IDC_CB_GAME,47,127,131,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "Skeleton:",IDC_STC_SKELETON,7,143,31,8
-    EDITTEXT        IDC_ED_SKELETON,7,155,171,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_BTN_BROWSE,192,155,19,13
-    DEFPUSHBUTTON   "&Import",IDOK,5,172,34,14
-    PUSHBUTTON      "&Cancel",IDCANCEL,45,172,33,14
-    LTEXT           "http://www.niftools.org",IDC_LBL_LINK,93,172,95,14,SS_NOTIFY | SS_CENTERIMAGE
+    GROUPBOX        "General Options:",IDC_STATIC,7,7,197,33
+    LTEXT           "Game:",IDC_STATIC,11,20,31,8
+    COMBOBOX        IDC_CB_GAME,37,18,123,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "Auto Detect",IDC_CHK_AUTO_DETECT,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,167,16,35,16
+    GROUPBOX        "Import:",IDC_STATIC,7,44,94,65
+    CONTROL         "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,57,67,10
+    CONTROL         "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,70,67,10
+    CONTROL         "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,82,67,10
+    CONTROL         "Furniture &Markers",IDC_CHK_FURN,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,94,67,10
+    GROUPBOX        "Geometry:",IDC_STATIC,105,44,99,65
+    CONTROL         "Vertex &Colors",IDC_CHK_VCOLORS,"Button",BS_AUTO3STATE | WS_TABSTOP,110,55,67,10
+    CONTROL         "S&kin Modifier",IDC_CHK_SKIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,67,67,10
+    CONTROL         "Auto Sm&ooth Mesh",IDC_CHK_AUTOSMOOTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,79,76,11
+    CONTROL         "Remove &Illegal Faces",IDC_CHK_ILLEGAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,92,80,11
+    GROUPBOX        "Animation:",IDC_STATIC,7,114,94,61
+    CONTROL         "Import &Animation",IDC_CHK_ANIMATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,125,67,10
+    CONTROL         "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,137,73,10
+    CONTROL         "Add Key Notes",IDC_CHK_KEYNOTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,149,72,10
+    CONTROL         "Add Time Tags",IDC_CHK_TIMETAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,162,72,10
+    GROUPBOX        "Miscellaneous:",IDC_STATIC,104,114,100,61
+    CONTROL         "Flip U&V",IDC_CHK_FLIP_UV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,126,47,10
+    CONTROL         "&Render Textures in View",IDC_CHK_SHOW_TEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,137,88,10
+    CONTROL         "Ignore User Prop Buffers",IDC_CHK_UPB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,149,89,10
+    GROUPBOX        "Skeleton:",IDC_STATIC,7,177,197,56
+    CONTROL         "Import &Skeleton",IDC_CHK_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,189,67,10
+    CONTROL         "Remove &Unused Bones",IDC_CHK_REM_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,202,88,10
+    CONTROL         "Use &Biped",IDC_CHK_BIPED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,110,189,87,10
+    EDITTEXT        IDC_ED_SKELETON,12,215,170,12,ES_AUTOHSCROLL
+    PUSHBUTTON      "...",IDC_BTN_BROWSE,184,215,16,13
+    DEFPUSHBUTTON   "&Import",IDOK,5,236,34,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,45,236,33,14
+    LTEXT           "http://www.niftools.org",IDC_LBL_LINK,122,236,78,14,SS_NOTIFY | SS_CENTERIMAGE
+    CONTROL         "Ignore Root Node",IDC_CHK_IGNORE_ROOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,109,161,89,10
 END
 
 IDD_KF_PANEL DIALOGEX 0, 0, 118, 99
@@ -87,9 +94,9 @@ BEGIN
     IDD_NIF_PANEL, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 211
+        RIGHTMARGIN, 204
         TOPMARGIN, 7
-        BOTTOMMARGIN, 186
+        BOTTOMMARGIN, 250
     END
 
     IDD_KF_PANEL, DIALOG
@@ -135,8 +142,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,4,0
- PRODUCTVERSION 0,2,4,0
+ FILEVERSION 0,2,5,0
+ PRODUCTVERSION 0,2,5,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -152,12 +159,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Importer"
-            VALUE "FileVersion", "0, 2, 4, 0"
+            VALUE "FileVersion", "0, 2, 5, 0"
             VALUE "InternalName", "MaxNifImport.dli"
             VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved."
             VALUE "OriginalFilename", "MaxNifImport.dli"
             VALUE "ProductName", "3ds Max Nif Importer"
-            VALUE "ProductVersion", "0, 2, 4, 0"
+            VALUE "ProductVersion", "0, 2, 5, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/NifImport/MaxNifImport_VC80.vcproj b/NifImport/MaxNifImport_VC80.vcproj
index 93ff0e2604c2dfbf7bb02493d56e7076d3e45144..1fa3a1679139016fc4c35adda079972f5dbc8b0d 100644
--- a/NifImport/MaxNifImport_VC80.vcproj
+++ b/NifImport/MaxNifImport_VC80.vcproj
@@ -49,7 +49,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/LD "
 				InlineFunctionExpansion="2"
-				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES"
 				StringPooling="true"
 				ExceptionHandling="2"
@@ -76,7 +76,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib "
 				OutputFile="C:\3dsmax6\plugins\MaxNifImport.dli"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -150,7 +150,7 @@
 				AdditionalOptions="/LD /Zm200"
 				Optimization="0"
 				InlineFunctionExpansion="2"
-				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE"
 				GeneratePreprocessedFile="0"
 				MinimalRebuild="true"
@@ -178,7 +178,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflibd.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib "
 				OutputFile="C:\3dsmax6\plugins\MaxNifImport.dli"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
@@ -251,7 +251,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/LD "
 				InlineFunctionExpansion="2"
-				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED"
 				StringPooling="true"
 				ExceptionHandling="2"
@@ -278,7 +278,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib "
 				OutputFile="C:\3dsmax7\plugins\MaxNifImport.dli"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -352,7 +352,7 @@
 				AdditionalOptions="/LD "
 				Optimization="0"
 				InlineFunctionExpansion="2"
-				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED"
 				GeneratePreprocessedFile="0"
 				ExceptionHandling="2"
@@ -378,7 +378,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflibd.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib "
 				OutputFile="C:\3dsmax7\plugins\MaxNifImport.dli"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
@@ -451,7 +451,7 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions="/LD "
 				InlineFunctionExpansion="2"
-				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED"
 				StringPooling="true"
 				ExceptionHandling="2"
@@ -478,7 +478,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib "
 				OutputFile="C:\3dsmax8\plugins\MaxNifImport.dli"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -552,7 +552,7 @@
 				AdditionalOptions="/LD /Zm200"
 				Optimization="0"
 				InlineFunctionExpansion="2"
-				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib;..\NifCommon"
+				AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\..\niflib\include;..\NifCommon"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED"
 				GeneratePreprocessedFile="0"
 				MinimalRebuild="true"
@@ -580,7 +580,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				AdditionalOptions="/MACHINE:I386"
-				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflibd.lib"
+				AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib "
 				OutputFile="C:\3dsmax8\plugins\MaxNifImport.dli"
 				LinkIncremental="2"
 				SuppressStartupBanner="true"
diff --git a/NifImport/NIFImport.cpp b/NifImport/NIFImport.cpp
index cb52375cb6d692979d4ffa47116b8b558e91a5ee..36477856fa53ea28598e1cc09af3fbc37fe8eced 100644
--- a/NifImport/NIFImport.cpp
+++ b/NifImport/NIFImport.cpp
@@ -117,6 +117,7 @@ void NifImporter::LoadIniSettings()
    appSettings = NULL;
    string curapp = GetIniValue<string>(NifImportSection, "CurrentApp", "AUTO");
    if (0 == _tcsicmp(curapp.c_str(), "AUTO")) {
+      autoDetect = true;
       // Scan Root paths
       for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){
          if ((*itr).IsFileInRootPaths(this->name)) {
@@ -125,6 +126,7 @@ void NifImporter::LoadIniSettings()
          }
       }
    } else {
+      autoDetect = false;
       appSettings = FindAppSetting(curapp);
    }
    if (appSettings == NULL && !TheAppSettings.empty()){
@@ -148,6 +150,7 @@ void NifImporter::LoadIniSettings()
    useCiv4Shader = GetIniValue(NifImportSection, "UseCiv4Shader", true);
    mergeNonAccum = GetIniValue(NifImportSection, "MergeNonAccum", true);
    importUPB = GetIniValue(NifImportSection, "ImportUPB", true);
+   ignoreRootNode = GetIniValue(NifImportSection, "IgnoreRootNode", true);
 
    // Biped
    importBones = GetIniValue(BipedImportSection, "ImportBones", true);
@@ -212,12 +215,17 @@ void NifImporter::SaveIniSettings()
    SetIniValue(NifImportSection, "RemoveIllegalFaces", removeIllegalFaces);
    SetIniValue(NifImportSection, "RemoveDegenerateFaces", removeDegenerateFaces);
    SetIniValue(NifImportSection, "ImportUPB", importUPB);
+   SetIniValue(NifImportSection, "IgnoreRootNode", ignoreRootNode);
 
    SetIniValue(BipedImportSection, "ImportBones", importBones);
    SetIniValue(BipedImportSection, "RemoveUnusedImportedBones", removeUnusedImportedBones);  
 
    SetIniValue(AnimImportSection, "EnableAnimations", enableAnimations);
    SetIniValue(AnimImportSection, "ClearAnimation", clearAnimation);
+   SetIniValue(AnimImportSection, "AddNoteTracks", addNoteTracks);
+   SetIniValue(AnimImportSection, "AddTimeTags", addTimeTags);
+
+   SetIniValue<string>(NifImportSection, "CurrentApp", autoDetect ? "AUTO" : appSettings->Name );
 }
 
 INode *NifImporter::GetNode(Niflib::NiNodeRef node)
@@ -269,7 +277,7 @@ bool NifImporter::DoImport()
          NiNodeRef rootNode = root;
 
          if (importBones) {
-            if (strmatch(rootNode->GetName(), "Scene Root"))
+            if (ignoreRootNode || strmatch(rootNode->GetName(), "Scene Root"))
                ImportBones(DynamicCast<NiNode>(rootNode->GetChildren()));
             else
                ImportBones(rootNode);
diff --git a/NifImport/NIFImporter.h b/NifImport/NIFImporter.h
index 6d472028309dade4451d3ae70617d89c9130bb44..dbc191cb1cdb4774a7d4db7e66e0fb491b246c49 100644
--- a/NifImport/NIFImporter.h
+++ b/NifImport/NIFImporter.h
@@ -17,6 +17,11 @@ HISTORY:
 #include "BaseImporter.h"
 #include "IniSection.h"
 
+namespace Niflib
+{
+   class NiTextKeyExtraData;
+}
+
 // NIF Importer
 class NifImporter : public BaseImporter//, public IniFileSection
 {
@@ -61,6 +66,8 @@ public:
    stringlist dummyNodeMatches;
    bool convertBillboardsToDummyNodes;
    bool uncontrolledDummies;
+   bool ignoreRootNode;
+   bool autoDetect;
 
    // Animation related Settings
    bool replaceTCBRotationWithBezier;
@@ -131,6 +138,7 @@ public:
    bool ImportAnimation();
    void ClearAnimation();
    void ClearAnimation(INode *node);
+   bool AddNoteTracks(float time, string name, string target, Niflib::Ref<Niflib::NiTextKeyExtraData> textKeyData, bool loop);
 
 
    protected: 
diff --git a/NifImport/NifDialog.cpp b/NifImport/NifDialog.cpp
index 4a36f8779db996420c8327b8c413b6a0ce578117..4940baaa28e60eb465e39a11ed18e80b8d151227 100644
--- a/NifImport/NifDialog.cpp
+++ b/NifImport/NifDialog.cpp
@@ -55,15 +55,18 @@ static BOOL CALLBACK MaxNifImportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wP
             CheckDlgButton(hWnd, IDC_CHK_ILLEGAL, imp->removeIllegalFaces);
             CheckDlgButton(hWnd, IDC_CHK_REM_BONES, imp->removeUnusedImportedBones);
             CheckDlgButton(hWnd, IDC_CHK_CLEARANIM, imp->clearAnimation);
+            CheckDlgButton(hWnd, IDC_CHK_KEYNOTES, imp->addNoteTracks);
+            CheckDlgButton(hWnd, IDC_CHK_TIMETAGS, imp->addTimeTags);
+            CheckDlgButton(hWnd, IDC_CHK_IGNORE_ROOT, imp->ignoreRootNode);
             
             CheckDlgButton(hWnd, IDC_CHK_BIPED, imp->useBiped);
-            CheckDlgButton(hWnd, IDC_CHK_UPB, !imp->importUPB);
-            
+            CheckDlgButton(hWnd, IDC_CHK_UPB, !imp->importUPB);           
             
             string selection = (imp->appSettings) ? imp->appSettings->Name : "User";
             for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr)
                SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_ADDSTRING, 0, LPARAM(itr->Name.c_str()));
             SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_SELECTSTRING, WPARAM(-1), LPARAM(selection.c_str()));
+            CheckDlgButton(hWnd, IDC_CHK_AUTO_DETECT, imp->autoDetect);
 
             SHAutoComplete(GetDlgItem(hWnd, IDC_ED_SKELETON), SHACF_FILESYSTEM);
             if (imp->HasSkeleton() && imp->appSettings && imp->importSkeleton) {
@@ -109,13 +112,17 @@ static BOOL CALLBACK MaxNifImportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wP
                   imp->removeIllegalFaces = IsDlgButtonChecked(hWnd, IDC_CHK_ILLEGAL) ? true : false;
                   imp->removeUnusedImportedBones = IsDlgButtonChecked(hWnd, IDC_CHK_REM_BONES) ? true : false;
                   imp->clearAnimation = IsDlgButtonChecked(hWnd, IDC_CHK_CLEARANIM) ? true : false;
+                  imp->addNoteTracks = IsDlgButtonChecked(hWnd, IDC_CHK_KEYNOTES) ? true : false;
+                  imp->addTimeTags = IsDlgButtonChecked(hWnd, IDC_CHK_TIMETAGS) ? true : false;
                   imp->useBiped = IsDlgButtonChecked(hWnd, IDC_CHK_BIPED) ? true : false;
                   imp->importUPB = IsDlgButtonChecked(hWnd, IDC_CHK_UPB) ? false : true;
-
+                  imp->ignoreRootNode = IsDlgButtonChecked(hWnd, IDC_CHK_IGNORE_ROOT) ? true : false;
+                  
                   GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH);
                   if (AppSettings *appSettings = FindAppSetting(tmp)) {
                      imp->appSettings = appSettings;
                   }
+                  imp->autoDetect = IsDlgButtonChecked(hWnd, IDC_CHK_AUTO_DETECT) ? true : false;
                   
                   GetDlgItemText(hWnd, IDC_ED_SKELETON, tmp, MAX_PATH);
                   imp->skeleton = tmp;
diff --git a/NifImport/resource.h b/NifImport/resource.h
index 22c9238e83a9422022be341a1ddf40d92b7d6bbf..066ecafac85cced43878275e8ca8f77aaa908cf8 100644
--- a/NifImport/resource.h
+++ b/NifImport/resource.h
@@ -27,7 +27,10 @@
 #define IDC_CHK_VCOLORS                 1012
 #define IDC_CHK_SHOW_TEX                1013
 #define IDC_CB_GAME                     1014
+#define IDC_CHK_IGNORE_ROOT             1015
 #define IDC_CB_USER_VERSION             1016
+#define IDC_CHK_LIGHTS2                 1016
+#define IDC_CHK_AUTO_DETECT             1016
 #define IDC_CHK_SKIN                    1017
 #define IDC_CHK_ANIMATION               1018
 #define IDC_CHK_AUTOSMOOTH              1019
diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc
index 68b5abcad3841198bf8997669839975917c566ce..7bf0c0e928ab59e26a861022014b0c53956da7ba 100755
--- a/NifProps/NifProps.rc
+++ b/NifProps/NifProps.rc
@@ -359,8 +359,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,4,0
- PRODUCTVERSION 0,2,4,0
+ FILEVERSION 0,2,5,0
+ PRODUCTVERSION 0,2,5,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -376,12 +376,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Reactor Properites Plugin"
-            VALUE "FileVersion", "0, 2, 4, 0"
+            VALUE "FileVersion", "0, 2, 5, 0"
             VALUE "InternalName", "NifProps.dlu"
             VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved."
             VALUE "OriginalFilename", "NifProps.dlu"
             VALUE "ProductName", "3ds Max Nif Reactor Properites Plugin"
-            VALUE "ProductVersion", "0, 2, 4, 0"
+            VALUE "ProductVersion", "0, 2, 5, 0"
         END
     END
     BLOCK "VarFileInfo"