diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt
index 810cd274d867a31ef9ab860ae796c5418dc79003..355c3fd2cac45cd83b2163b74e350f3dc2877487 100644
--- a/MaxNifPlugins_Readme.txt
+++ b/MaxNifPlugins_Readme.txt
@@ -1,4 +1,4 @@
-                        MaxPlugins 0.2.3
+                        MaxPlugins 0.2.4
                         ================
 
  
@@ -27,6 +27,23 @@
 
     Change log
     ----------
+      0.2.4
+      -----
+    o Exporter
+      - Add animation export.
+      
+    o Importer
+      - Add option to ignore UPB buffers.  
+        * Useful in preventing LOD Bone warnings from the Civ4 Exporter
+      - Fixed problem with Animation Note Tracks not being cleared
+      - Fixed issue with BSpline animation when too much data was present
+        * Specifically the Civ4 Leaderheads now import animation very well
+      - Import Animation Priority into user prop buffer
+        
+    o NifProps Utility
+      - Added Animation Priority
+      - Removed unused Globals
+    
       0.2.3
       -----
     o Exporter
diff --git a/NifCommon/AnimKey.cpp b/NifCommon/AnimKey.cpp
index f5fcfdc44bc4edbedac4d12d0d27c70f4f810232..8caa4ac15022d18669288e865b1cd846395b7785 100644
--- a/NifCommon/AnimKey.cpp
+++ b/NifCommon/AnimKey.cpp
@@ -131,6 +131,30 @@ FloatKey MapKey<FloatKey, ILinFloatKey>(ILinFloatKey& key, float time)
    return InitFromLinKey(rKey, key, time);
 }
 
+template<>
+Vector3Key MapKey<Vector3Key, ILinPoint3Key>(ILinPoint3Key& key, float time)
+{
+   Vector3Key rKey;
+   rKey.data = TOVECTOR3(key.val);
+   return InitFromLinKey(rKey, key, time);
+}
+
+template<>
+QuatKey MapKey<QuatKey, ILinRotKey>(ILinRotKey& key, float time)
+{
+   QuatKey rKey;
+   rKey.data = TOQUAT(key.val, true);
+   return InitFromLinKey(rKey, key, time);
+}
+
+template<>
+FloatKey MapKey<FloatKey, ILinScaleKey>(ILinScaleKey& key, float time)
+{
+   FloatKey rKey;
+   rKey.data = (key.val[0] + key.val[1] + key.val[2]) / 3.0f;
+   return InitFromLinKey(rKey, key, time);
+}
+
 
 // Specialized Bezier/Hybrid mappings
 
@@ -154,7 +178,6 @@ IBezPoint3Key MapKey<IBezPoint3Key, Vector3Key>(Vector3Key& key, float time)
    return InitBezKey(rKey, key, time);
 }
 
-
 template<>
 IBezQuatKey MapKey<IBezQuatKey, QuatKey>(QuatKey& key, float time)
 {
@@ -172,7 +195,7 @@ IBezScaleKey MapKey<IBezScaleKey, FloatKey>(FloatKey& key, float time)
    return InitBezKey(rKey, key, time);
 }
 
-// Specialized Linear Mappings
+// Specialized Bezier/Hybrid Mappings
 
 template<>
 FloatKey MapKey<FloatKey, IBezFloatKey>(IBezFloatKey& key, float time)
@@ -184,6 +207,37 @@ FloatKey MapKey<FloatKey, IBezFloatKey>(IBezFloatKey& key, float time)
    return InitFromBezKey(rKey, key, time);
 }
 
+template<>
+Vector3Key MapKey<Vector3Key, IBezPoint3Key>(IBezPoint3Key& key, float time)
+{
+   Vector3Key rKey;
+   rKey.data = TOVECTOR3(key.val);
+   rKey.forward_tangent = TOVECTOR3(key.intan);
+   rKey.backward_tangent = TOVECTOR3(key.outtan);
+   return InitFromBezKey(rKey, key, time);
+}
+
+template<>
+QuatKey MapKey<QuatKey, IBezQuatKey>(IBezQuatKey& key, float time)
+{
+   QuatKey rKey;
+   rKey.data = TOQUAT(key.val, true);
+   //rKey.forward_tangent = TOQUAT(key.intan, true);
+   //rKey.backward_tangent = TOQUAT(key.outtan, true);
+   return InitFromBezKey(rKey, key, time);
+}
+
+template<>
+FloatKey MapKey<FloatKey, IBezScaleKey>(IBezScaleKey& key, float time)
+{
+   FloatKey rKey;
+   rKey.data = Average(key.val.s);
+   rKey.forward_tangent = Average(key.intan);
+   rKey.backward_tangent = Average(key.outtan);
+   return InitFromBezKey(rKey, key, time);
+}
+
+
 // Specialized TCB Mappings
 
 template<>
@@ -229,6 +283,32 @@ FloatKey MapKey<FloatKey, ITCBFloatKey>(ITCBFloatKey& key, float time)
    return InitFromTCBKey(rKey, key, time);
 }
 
+template<>
+Vector3Key MapKey<Vector3Key, ITCBPoint3Key>(ITCBPoint3Key& key, float time)
+{
+   Vector3Key rKey;
+   rKey.data = TOVECTOR3(key.val);
+   return InitFromTCBKey(rKey, key, time);
+}
+
+template<>
+QuatKey MapKey<QuatKey, ITCBRotKey>(ITCBRotKey& key, float time)
+{
+   QuatKey rKey;
+   rKey.data = TOQUAT(key.val, true);
+   return InitFromTCBKey(rKey, key, time);
+}
+
+template<>
+FloatKey MapKey<FloatKey, ITCBScaleKey>(ITCBScaleKey& key, float time)
+{
+   FloatKey rKey;
+   rKey.data = Average(key.val.s);
+   return InitFromTCBKey(rKey, key, time);
+}
+
+// Merge Keys
+
 template<> void MergeKey<ILinRotKey>(ILinRotKey& lhs, ILinRotKey& rhs) {
    lhs.val *= rhs.val;
 }
diff --git a/NifCommon/AnimKey.h b/NifCommon/AnimKey.h
index 1cb3462565c993e4d696429b80a3ac51184b4a1b..7766ab9a82cd60adbfa67b1e36cf622f499d1084 100644
--- a/NifCommon/AnimKey.h
+++ b/NifCommon/AnimKey.h
@@ -120,17 +120,38 @@ inline void SetKeys(Control *subCtrl, vector<U>& keys, float time)
 }
 
 template<typename T, typename U>
-inline void GetKeys(Control *subCtrl, vector<T>& keys, float time)
+inline int GetKeys(Control *subCtrl, vector<T>& keys, float time)
 {
    if (IKeyControl *ikeys = GetKeyControlInterface(subCtrl)){
-      int n = ikeys->GetKeySize();
+      int n = ikeys->GetNumKeys();
       keys.reserve(n);
       for (int i=0; i<n; ++i){
          AnyKey buf; U *key = reinterpret_cast<U*>((IKey*)buf);
          ikeys->GetKey(i, key);
          keys.push_back( MapKey<T>(*key, time) );
       }
+      return keys.size();
    }
+   return 0;
+}
+
+template<typename T, typename U>
+inline int GetKeys(Control *subCtrl, vector<T>& keys, Interval range)
+{
+   if (IKeyControl *ikeys = GetKeyControlInterface(subCtrl)){
+      float timeOffset = -FrameToTime(range.Start());
+      int n = ikeys->GetNumKeys();
+      keys.reserve(n);
+      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)) {
+            keys.push_back( MapKey<T>(*key, timeOffset) );
+         }
+      }
+      return keys.size();
+   }
+   return 0;
 }
 
 template<typename T, typename U>
diff --git a/NifCommon/NifPlugins.h b/NifCommon/NifPlugins.h
index ca1239c57aa1b3357fb1b78d805c7fa87b8b56fd..00905842f8a7a767a67ab51e01c56c4d396a0d9c 100644
--- a/NifCommon/NifPlugins.h
+++ b/NifCommon/NifPlugins.h
@@ -39,6 +39,8 @@ using Niflib::Vector3;
 
 #define NP_FRN_POS							_T("np_frn_pos")
 
+#define NP_ANM_PRI							_T("np_anm_pri")
+
 /* default values */
 #define NP_DEFAULT_HVK_MATERIAL				9
 #define NP_DEFAULT_HVK_LAYER				1
@@ -50,6 +52,8 @@ using Niflib::Vector3;
 #define NP_DEFAULT_HVK_MOTION_SYSTEM		7
 #define NP_DEFAULT_HVK_QUALITY_TYPE			1
 
+#define NP_DEFAULT_ANM_PRI	0.0f
+
 #define NP_DEFAULT_FRN_MARKER_TYPE			NP_FRN_SLEEP_LEFT
 
 /* other constants */
diff --git a/NifCommon/niutils.h b/NifCommon/niutils.h
index 2af7484621554c09f2ae117791b94162f96a47bf..294205978136de04e80ad65b70568f4c8006bc94 100644
--- a/NifCommon/niutils.h
+++ b/NifCommon/niutils.h
@@ -351,6 +351,14 @@ static inline Point3 GetScale(const Matrix3& mtx){
    return Point3( fabs(mtx.GetRow(0)[0]), fabs(mtx.GetRow(1)[1]), fabs(mtx.GetRow(2)[2]) );
 }
 
+static inline float Average(const Point3& val) {
+   return (val[0] + val[1] + val[2]) / 3.0f;
+}
+
+static inline float Average(const Niflib::Vector3& val) {
+   return (val.x + val.y + val.z) / 3.0f;
+}
+
 template <typename U, typename T>
 inline Niflib::Ref<U> SelectFirstObjectOfType( vector<Niflib::Ref<T> > const & objs ) {
    for (vector<Niflib::Ref<T> >::const_iterator itr = objs.begin(), end = objs.end(); itr != end; ++itr) {
diff --git a/NifExport/Animation.cpp b/NifExport/Animation.cpp
index 8b7994569fc955a475046d0e4596a1b04f8e254e..70eaba44f9a15c6b00a1ab3c3d45e0a7bb27e986 100644
--- a/NifExport/Animation.cpp
+++ b/NifExport/Animation.cpp
@@ -11,6 +11,9 @@ HISTORY:
 *>	Copyright (c) 2006, All Rights Reserved.
 **********************************************************************/
 #include "pch.h"
+#include <IFrameTagManager.h>
+#include <notetrck.h>
+
 #include "NifExport.h"
 #include "AnimKey.h"
 
@@ -39,33 +42,135 @@ struct AnimationExport
 {
    AnimationExport(Exporter& parent) : ne(parent) {}
 
-   bool doExport();
-   bool exportController(INode *node, NiControllerSequenceRef seq);
+   INode * findTrackedNode(INode *root);
+
+   bool doExport(NiControllerSequenceRef seq);
+   bool exportController(INode *node);
    Control *GetTMController(INode* node);
 
    Exporter &ne;
+   Interval range;
+   NiControllerSequenceRef seq;
 };
 
-bool Exporter::doAnimExport()
+Exporter::Result Exporter::doAnimExport(NiControllerSequenceRef root)
 {
    AnimationExport animExporter(*this);
-   return animExporter.doExport();
 
-   return true;
+   return animExporter.doExport(root) ? Exporter::Ok : Exporter::Abort ;
 }
 //NiControllerSequenceRef makeSequence(TimeValue start, TimeValue end);
 
-bool AnimationExport::doExport()
+INode * AnimationExport::findTrackedNode(INode *node)
 {
-   INode *root = ne.mI->GetRootNode();
-   NiControllerSequenceRef seq = new NiControllerSequence();
-   seq->SetStartTime(0.0f);
-   seq->SetStopTime(0.0f);
+   // locate START in note track before assuming all is well
+   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) ) {
+               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)) {
+                        return node;
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+   for (int i=0; i < node->NumberOfChildren(); ++i ){
+      if ( INode *root = findTrackedNode( node->GetChildNode(i) ) ) {
+         return root;
+      }
+   }
+   return NULL;
+}
+
+bool AnimationExport::doExport(NiControllerSequenceRef seq)
+{
+   INode *node = findTrackedNode(ne.mI->GetRootNode());
+   if (node == NULL)
+      throw runtime_error("No Actor Roots have been selected in the Animation Manager. Cannot continue.");
+
+   this->seq = seq;
+
+   vector<StringKey> textKeys;
+
+   this->range.SetInstant(0);
+
+   seq->SetStartTime(FloatINF);
+   seq->SetStopTime(FloatINF);
    seq->SetFrequency(1.0f);
    seq->SetCycleType( CYCLE_CLAMP );
-   seq->SetTargetName("Bip01");
-   
-   return true;
+   seq->SetTargetName( node->GetName() );
+
+   NiTextKeyExtraDataRef textKeyData = new NiTextKeyExtraData();
+   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);
+                        }
+                     }
+                  } 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);
+               }
+            }
+         }
+      }
+   }
+   textKeyData->SetKeys(textKeys);
+
+   // Now let the fun begin.
+
+   bool ok = exportController(node);
+
+   // Handle NonAccum
+   if (ok)
+   {
+      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));
+
+      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;
 }
 
 
@@ -87,175 +192,255 @@ Control *AnimationExport::GetTMController(INode *n)
 }
 
 
-bool AnimationExport::exportController(INode *node, NiControllerSequenceRef seq)
+bool AnimationExport::exportController(INode *node)
 {
    bool ok = true;
-   int nKeys = node->NumKeys();
-   if (nKeys >= 0)
+   bool skip = false;
+
+   // Primary recursive decent routine
+
+   ObjectState os = node->EvalWorldState(range.Start()); 
+
+   if (!Exporter::mExportCameras && os.obj && os.obj->SuperClassID()==CAMERA_CLASS_ID)
+   {
+      skip = true;
+   }
+   else if (!Exporter::mExportLights && os.obj && os.obj->SuperClassID()==LIGHT_CLASS_ID)
+   {
+      skip = true;
+   }
+
+   if (!skip && Exporter::mExportTransforms)
    {
-      float timeOffset = 0.0f;
-      NiKeyframeDataRef data = new NiKeyframeData();
+      float timeOffset = -FrameToTime(range.Start());
       if (Control *tmCont = GetTMController(node))
       {
-         if (Control *c = tmCont->GetPositionController()) 
+         Interval validity; validity.SetEmpty();
+         Matrix3 tm = node->GetObjTMAfterWSM(range.Start());
+         Matrix3 pm = Inverse(node->GetParentTM(range.Start()));
+         tm *= pm;
+
+         NiNodeRef ninode = new NiNode();
+         ninode->SetName(node->GetName());
+
+         //Vector3 trans(FloatNegINF, FloatNegINF, FloatNegINF);
+         //Quaternion rot(FloatNegINF, FloatNegINF, FloatNegINF, FloatNegINF);
+         Vector3 trans = TOVECTOR3(tm.GetTrans());
+         Quaternion rot = TOQUAT( Quat(tm), true );
+         float scale = FloatNegINF;
+         bool keepData = false;
+
+         NiTransformControllerRef control = new NiTransformController();
+         NiTransformInterpolatorRef interp = new NiTransformInterpolator();
+         ninode->AddController(StaticCast<NiTimeController>(control));
+         control->SetInterpolator(StaticCast<NiInterpolator>(interp));
+
+         //if (validity.InInterval(range))
+         //{
+         //   // Valid for entire interval.  i.e. no changes
+         //   interp->SetTranslation( TOVECTOR3(tm.GetTrans()) );
+         //   interp->SetScale( Average(GetScale(tm)) );
+         //   interp->SetRotation( TOQUAT( Quat(tm) ) );
+         //   seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control));
+         //}
+         //else
          {
-            // separate xyz
-            if (c->ClassID() == IPOS_CONTROL_CLASS_ID) 
-            { 
-               KeyType kType = QUADRATIC_KEY;
-               vector<FloatKey> xkeys, ykeys, zkeys;
-
-               if (Control *x = c->GetXController()){
-                  if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-                     kType = LINEAR_KEY;
-                     GetKeys<FloatKey, ILinFloatKey>(x, xkeys, timeOffset);
-                  } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-                     kType = QUADRATIC_KEY;
-                     GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset);
-                  } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-                     kType = TBC_KEY;
-                     GetKeys<FloatKey, ITCBFloatKey>(x, xkeys, timeOffset);
-                  } else {
-                     kType = QUADRATIC_KEY;
-                     GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset);
+            NiTransformDataRef data = new NiTransformData();
+
+            if (Control *c = tmCont->GetPositionController()) 
+            {
+               int nkeys = 0;
+               // separate xyz
+               if (c->ClassID() == IPOS_CONTROL_CLASS_ID) 
+               { 
+                  KeyType kType = QUADRATIC_KEY;
+                  vector<FloatKey> xkeys, ykeys, zkeys;
+                  if (Control *x = c->GetXController()){
+                     if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                        kType = LINEAR_KEY;
+                        nkeys += GetKeys<FloatKey, ILinFloatKey>(x, xkeys, range);
+                     } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                        kType = QUADRATIC_KEY;
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(x, xkeys, range);
+                     } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                        kType = TBC_KEY;
+                        nkeys += GetKeys<FloatKey, ITCBFloatKey>(x, xkeys, range);
+                     } else {
+                        kType = QUADRATIC_KEY;
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(x, xkeys, range);
+                     }
                   }
-               }
-               if (Control *y = c->GetYController()){
-                  if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-                     GetKeys<FloatKey, ILinFloatKey>(y, ykeys, timeOffset);
-                  } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-                     GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset);
-                  } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-                     GetKeys<FloatKey, ITCBFloatKey>(y, ykeys, timeOffset);
+                  if (Control *y = c->GetYController()){
+                     if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ILinFloatKey>(y, ykeys, range);
+                     } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(y, ykeys, range);
+                     } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ITCBFloatKey>(y, ykeys, range);
+                     } else {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(y, ykeys, range);
+                     }
+                  }
+                  if (Control *z = c->GetZController()){
+                     if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ILinFloatKey>(z, zkeys, range);
+                     } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(z, zkeys, range);
+                     } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, range);
+                     } else {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(z, zkeys, range);
+                     }
+                  }
+                  vector<Vector3Key> keys;
+                  JoinKeys(keys, xkeys, ykeys, zkeys);
+                  data->SetTranslateType(kType);
+                  data->SetTranslateKeys(keys);
+               } else {
+                  vector<Vector3Key> keys;
+                  if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                     data->SetTranslateType(LINEAR_KEY);
+                     nkeys += GetKeys<Vector3Key, ILinPoint3Key>(c, keys, range);
+                  } else if (c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                     data->SetTranslateType(QUADRATIC_KEY);
+                     nkeys += GetKeys<Vector3Key, IBezPoint3Key>(c, keys, range);
+                  } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                     data->SetTranslateType(TBC_KEY);
+                     nkeys += GetKeys<Vector3Key, ITCBPoint3Key>(c, keys, range);
                   } else {
-                     GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset);
+                     data->SetTranslateType(QUADRATIC_KEY);
+                     nkeys += GetKeys<Vector3Key, IBezPoint3Key>(c, keys, range);
                   }
+                  data->SetTranslateKeys(keys);
                }
-               if (Control *z = c->GetZController()){
-                  if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-                     GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset);
-                  } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-                     GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-                  } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-                     GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset);
-                  } else {
-                     GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
+               if (nkeys != 0) { // if no changes set the base transform
+                  keepData = true;
+                  //trans = TOVECTOR3(tm.GetTrans());
+               }
+            }
+
+            // Rotations
+            if (Control *c = tmCont->GetRotationController()) 
+            {
+               int nkeys = 0;
+               if (c->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID,0)) {
+                  vector<QuatKey> keys;
+                  data->SetRotateType(LINEAR_KEY);
+                  nkeys += GetKeys<QuatKey, ILinRotKey>(c, keys, range);
+                  data->SetQuatRotateKeys(keys);
+               } else if (c->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID,0)) {
+                  vector<QuatKey> keys;
+                  data->SetRotateType(QUADRATIC_KEY);
+                  nkeys += GetKeys<QuatKey, IBezQuatKey>(c, keys, range);
+                  data->SetQuatRotateKeys(keys);
+               } else if (c->ClassID() == Class_ID(EULER_CONTROL_CLASS_ID,0)) {
+                  if (Control *x = c->GetXController()){
+                     vector<FloatKey> keys;
+                     if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ILinFloatKey>(x, keys, range);
+                        data->SetXRotateType(LINEAR_KEY);
+                     } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(x, keys, range);
+                        data->SetXRotateType(QUADRATIC_KEY);
+                     } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ITCBFloatKey>(x, keys, range);
+                        data->SetXRotateType(TBC_KEY);
+                     } else {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(x, keys, range);
+                        data->SetXRotateType(QUADRATIC_KEY);
+                     }
+                     data->SetXRotateKeys(keys);
+                  }
+                  if (Control *y = c->GetXController()) {
+                     vector<FloatKey> keys;
+                     if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ILinFloatKey>(y, keys, range);
+                        data->SetYRotateType(LINEAR_KEY);
+                     } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(y, keys, range);
+                        data->SetYRotateType(QUADRATIC_KEY);
+                     } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ITCBFloatKey>(y, keys, range);
+                        data->SetYRotateType(TBC_KEY);
+                     } else {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(y, keys, range);
+                        data->SetYRotateType(QUADRATIC_KEY);
+                     }
+                     data->SetYRotateKeys(keys);
+                  }
+                  if (Control *z = c->GetZController()) {
+                     vector<FloatKey> keys;
+                     if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ILinFloatKey>(z, keys, range);
+                        data->SetZRotateType(LINEAR_KEY);
+                     } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(z, keys, range);
+                        data->SetZRotateType(QUADRATIC_KEY);
+                     } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
+                        nkeys += GetKeys<FloatKey, ITCBFloatKey>(z, keys, range);
+                        data->SetZRotateType(TBC_KEY);
+                     } else {
+                        nkeys += GetKeys<FloatKey, IBezFloatKey>(z, keys, range);
+                        data->SetZRotateType(QUADRATIC_KEY);
+                     }
+                     data->SetZRotateKeys(keys);
                   }
+               } else if (c->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID,0)) {
+                  vector<QuatKey> keys;
+                  data->SetRotateType(TBC_KEY);
+                  nkeys += GetKeys<QuatKey, ITCBRotKey>(c, keys, range);
+                  data->SetQuatRotateKeys(keys);
+               }
+               if (nkeys != 0) { // if no changes set the base transform
+                  keepData = true;
+                  //rot = TOQUAT( Quat(tm) );
                }
-               vector<Vector3Key> keys;
-               JoinKeys(keys, xkeys, ykeys, zkeys);
-               data->SetTranslateType(kType);
-               data->SetTranslateKeys(keys);
-
-            } else {
-               //if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-               //   data->SetRotateType(LINEAR_KEY);
-               //   GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset);
-               //} else if (c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-               //   data->SetZRotateType(QUADRATIC_KEY);
-               //   GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-               //} else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-               //   data->SetZRotateType(TBC_KEY);
-               //   GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset);
-               //} else {
-               //   data->SetZRotateType(QUADRATIC_KEY);
-               //   GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-               //}
             }
-         }
 
-         //// rotations
-         //if (Control *c = tmCont->GetPositionController()) 
-         //{
-         //   // separate xyz
-         //   if (c->ClassID() == IPOS_CONTROL_CLASS_ID) 
-         //   { 
-         //      if (Control *x = c->GetXController()){
-         //         if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetXRotateType(LINEAR_KEY);
-         //            GetKeys<FloatKey, ILinFloatKey>(x, xkeys, timeOffset);
-         //         } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetXRotateType(QUADRATIC_KEY);
-         //            GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset);
-         //         } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetXRotateType(TBC_KEY);
-         //            GetKeys<FloatKey, ITCBFloatKey>(x, xkeys, timeOffset);
-         //         } else {
-         //            data->SetXRotateType(QUADRATIC_KEY);
-         //            GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset);
-         //         }
-         //         data->SetXRotateKeys(xkeys);
-         //      }
-         //      if (Control *y = c->GetYController()){
-         //         KeyType kType = LINEAR_KEY;
-         //         vector<FloatKey> ykeys;
-         //         if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetYRotateType(LINEAR_KEY);
-         //            GetKeys<FloatKey, ILinFloatKey>(y, ykeys, timeOffset);
-         //         } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetYRotateType(QUADRATIC_KEY);
-         //            GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset);
-         //         } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetYRotateType(TBC_KEY);
-         //            GetKeys<FloatKey, ITCBFloatKey>(y, ykeys, timeOffset);
-         //         } else {
-         //            data->SetYRotateType(QUADRATIC_KEY);
-         //            GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset);
-         //         }
-         //         data->SetYRotateKeys(ykeys);
-         //      }
-         //      if (Control *z = c->GetZController()){
-         //         KeyType kType = LINEAR_KEY;
-         //         vector<FloatKey> zkeys;
-         //         if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetZRotateType(LINEAR_KEY);
-         //            GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset);
-         //         } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetZRotateType(QUADRATIC_KEY);
-         //            GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-         //         } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-         //            data->SetZRotateType(TBC_KEY);
-         //            GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset);
-         //         } else {
-         //            data->SetZRotateType(QUADRATIC_KEY);
-         //            GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-         //         }
-         //         data->SetZRotateKeys(zkeys);
-         //      }
-         //   } else {
-         //      if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) {
-         //         data->SetRotateType(LINEAR_KEY);
-         //         GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset);
-         //      } else if (c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) {
-         //         data->SetZRotateType(QUADRATIC_KEY);
-         //         GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-         //      } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) {
-         //         data->SetZRotateType(TBC_KEY);
-         //         GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset);
-         //      } else {
-         //         data->SetZRotateType(QUADRATIC_KEY);
-         //         GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset);
-         //      }
-         //   }
-         //}
+            // Scale
+            if (Control *c = tmCont->GetScaleController()) 
+            {
+               int nkeys = 0;
+               if (c->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID,0)) {
+                  vector<FloatKey> keys;
+                  data->SetScaleType(LINEAR_KEY);
+                  nkeys += GetKeys<FloatKey, ILinFloatKey>(c, keys, range);
+                  data->SetScaleKeys(keys);
+               } else if (c->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID,0)) {
+                  vector<FloatKey> keys;
+                  data->SetScaleType(QUADRATIC_KEY);
+                  nkeys += GetKeys<FloatKey, IBezFloatKey>(c, keys, range);
+                  data->SetScaleKeys(keys);
+               } else if (c->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID,0)) {
+                  vector<FloatKey> keys;
+                  data->SetScaleType(TBC_KEY);
+                  nkeys += GetKeys<FloatKey, ITCBFloatKey>(c, keys, range);
+                  data->SetScaleKeys(keys);
+               }
+               if (nkeys != 0) { // if no changes set the base transform
+                  keepData = true;
+                  //scale = Average(GetScale(tm));
+               }           
+            }
+            // only add transform data object if data actually is present
+            if (keepData) {
+               interp->SetData(data);
+            }
+            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);
+         }
       }
-      //Class_ID c->ClassID()
-      //if (Control *subCtrl = MakePositionXYZ(c, Class_ID(LININTERP_FLOAT_CLASS_ID,0))) {
-      
-      //NiKeyframeDataRef data = new NiKeyframeData();
-      //NiKeyframeDataRef data = CreateBlock("NiKeyframeData");
-      //data->SetRotateType(QUADRATIC_KEY);
-      //data->SetTranslateType(QUADRATIC_KEY);
-      //data->SetScaleType(QUADRATIC_KEY);
-      //data->SetTranslateKeys( interp->SampleTranslateKeys(npoints, 4) );
-      //data->SetQuatRotateKeys( interp->SampleQuatRotateKeys(npoints, 4) );
-      //data->SetScaleKeys( interp->SampleScaleKeys(npoints, 4) );
    }
    for (int i=0, n=node->NumberOfChildren(); ok && i<n; ++i)
    {
       INode *child = node->GetChildNode(i);
-      ok |= exportController(child, seq);
+      ok |= exportController(child);
    }
    return ok;
 }
\ No newline at end of file
diff --git a/NifExport/Config.cpp b/NifExport/Config.cpp
index ea3262bd7c8ecb394e070f66be6ca1f64804ae82..1ff47215a3f811c63ea53af2a3b1720566b5400f 100755
--- a/NifExport/Config.cpp
+++ b/NifExport/Config.cpp
@@ -5,6 +5,7 @@
 #define REGPATH "Software\\NifTools\\MaxPlugins"
 
 static LPCTSTR NifExportSection = TEXT("MaxNifExport");
+static LPCTSTR KfExportSection = TEXT("KfExport");
 
 void regSet(HKEY hKey, const char *value, float f);
 void regSet(HKEY hKey, const char *value, bool b);
@@ -127,6 +128,33 @@ void Exporter::readConfig(Interface *i)
 }
 
 
+void Exporter::readKfConfig(Interface *i)
+{
+   TCHAR iniName[MAX_PATH];
+   LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR);
+   PathCombine(iniName, pluginDir, "MaxNifTools.ini");
+
+   mExportHidden = GetIniValue(KfExportSection, "IncludeHidden", false, iniName);
+   mExportLights = GetIniValue(KfExportSection, "Lights", false, iniName);
+   mExportCameras = GetIniValue(KfExportSection, "Cameras", false, iniName);
+   mExportTransforms = GetIniValue(KfExportSection, "Transforms", true, iniName);
+   mDefaultPriority = GetIniValue<float>(KfExportSection, "Priority", 0.0f, iniName);
+}
+
+void Exporter::writeKfConfig(Interface *i)
+{
+   TCHAR iniName[MAX_PATH];
+   LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR);
+   PathCombine(iniName, pluginDir, "MaxNifTools.ini");
+
+   SetIniValue(KfExportSection, "IncludeHidden", mExportHidden, iniName);
+   SetIniValue(KfExportSection, "Lights", mExportLights, iniName);
+   SetIniValue(KfExportSection, "Cameras", mExportCameras, iniName);
+   SetIniValue(KfExportSection, "Transforms", mExportTransforms, iniName);
+   SetIniValue<float>(KfExportSection, "Priority", mDefaultPriority, iniName);
+}
+
+
 void regSet(HKEY hKey, const char *value, float f)
 {
 	DWORD dw = *((DWORD*)&f);
diff --git a/NifExport/DllEntry.cpp b/NifExport/DllEntry.cpp
index 0e7e3aa41240323708f514992bc56e1e06930ca8..8907fa30db1f0a35a8ab4ad4837e92ad3c4bb885 100755
--- a/NifExport/DllEntry.cpp
+++ b/NifExport/DllEntry.cpp
@@ -60,11 +60,7 @@ __declspec( dllexport ) const TCHAR* LibDescription()
 //TODO: Must change this number when adding a new class
 __declspec( dllexport ) int LibNumberClasses()
 {
-#if _DEBUG
-	return 2;
-#else
-   return 1;
-#endif
+   return 2;
 }
 
 // This function returns the number of plug-in classes this DLL
diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp
index a13f1df7e507b17431ca5aaf92e39f9895a9b4de..8bdf74b283dc387b0a24605022d2d300ceb9700d 100755
--- a/NifExport/Exporter.cpp
+++ b/NifExport/Exporter.cpp
@@ -29,6 +29,8 @@ 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::Exporter(Interface *i, AppSettings *appSettings)
    : mI(i), mAppSettings(appSettings)
diff --git a/NifExport/Exporter.h b/NifExport/Exporter.h
index 44dd7b7d7e28f4ac83dde840596bd85ca46c15e7..8d5b2f0dfaf90b39abe09b808d948aaa7a36e233 100755
--- a/NifExport/Exporter.h
+++ b/NifExport/Exporter.h
@@ -57,6 +57,9 @@ public:
    static bool				mExportCameras;
    static bool          mGenerateBoneCollision;
 
+   static bool          mExportTransforms;
+   static float         mDefaultPriority;
+
 	Exporter(Interface *i, AppSettings *appSettings);
 
 	Result					doExport(NiNodeRef &root, INode *node);
@@ -70,11 +73,15 @@ public:
 	static void				writeConfig(INode *node);
 	// writes config to registry
 	static void				writeConfig(Interface *i);
+   // writes config to registry
+   static void				writeKfConfig(Interface *i);
 
 	// reads config from root node
 	static void				readConfig(INode *node);
 	// reads config from registry
 	static void				readConfig(Interface *i);
+   // reads config from registry
+   static void				readKfConfig(Interface *i);
 
 public:
 	typedef vector<unsigned short> TriStrip;
@@ -176,7 +183,7 @@ public:
    bool exportSkin();
 
    /* animation export */
-   bool doAnimExport();
+   Result doAnimExport(Ref<NiControllerSequence> root);
 
    /* misc export */
    bool exportUPB(NiNodeRef &root, INode *node);
diff --git a/NifExport/KfExport.cpp b/NifExport/KfExport.cpp
index c865cc3f50e5868ef38819cf1144d256783be6b0..4102b0c8e651f3511caf265f32f1dff1de80dfe4 100644
--- a/NifExport/KfExport.cpp
+++ b/NifExport/KfExport.cpp
@@ -2,12 +2,12 @@
 #include "AppSettings.h"
 #include "niutils.h"
 #include  <io.h>
-
+#include "obj/NiControllerSequence.h"
 using namespace Niflib;
 
 #define KFEXPORT_CLASS_ID	Class_ID(0xa57ff0a4, 0xa0374ffc)
 
-static LPCTSTR KfExportSection = TEXT("MaxKfExport");
+static LPCTSTR KfExportSection = TEXT("KfExport");
 
 class KfExport : public SceneExport 
 {
@@ -43,12 +43,12 @@ class KfExportClassDesc : public ClassDesc2
 public:
    int 			IsPublic() { return TRUE; }
    void			*Create(BOOL loading = FALSE) { return new KfExport(); }
-   const TCHAR		*ClassName() { return GetString(IDS_CLASS_NAME); }
+   const TCHAR		*ClassName() { return GetString(IDS_KF_CLASS_NAME); }
    SClass_ID		SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
    Class_ID		ClassID() { return KFEXPORT_CLASS_ID; }
    const TCHAR		*Category() { return GetString(IDS_CATEGORY); }
 
-   const TCHAR		*InternalName() { return _T("KfExport"); }	// returns fixed parsable name (scripter-visible name)
+   const TCHAR		*InternalName() { return _T("_KfExport"); }	// returns fixed parsable name (scripter-visible name)
    HINSTANCE		HInstance() { return hInstance; }					// returns owning module handle
 
 
@@ -58,6 +58,128 @@ static KfExportClassDesc KfExportDesc;
 ClassDesc2* GetKfExportDesc() { return &KfExportDesc; }
 
 
+static BOOL CALLBACK KfExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) {
+   static KfExport *imp = NULL;
+
+   switch (message) 
+   {
+   case WM_INITDIALOG:
+      {
+         // Append file version to dialog
+         TSTR fileVersion = GetFileVersion(NULL);
+         if (!fileVersion.isNull()) {
+            char buffer[256];
+            GetWindowText(hWnd, buffer, _countof(buffer));
+            _tcscat(buffer, TEXT(" "));
+            _tcscat(buffer, fileVersion);
+            SetWindowText(hWnd, buffer);
+         }
+
+         imp = (KfExport *)lParam;
+         CenterWindow(hWnd,GetParent(hWnd));
+
+         CheckDlgButton(hWnd, IDC_CHK_HIDDEN, Exporter::mExportHidden);
+         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));
+
+         string selection = Exporter::mGameName;
+         string version = Exporter::mNifVersion;
+         string userVer = FormatString("%d", Exporter::mNifUserVersion);
+         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()));
+         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()));
+
+         imp->mDlgResult = IDCANCEL;
+      }
+      return TRUE;
+
+   case WM_CLOSE:
+      EndDialog(hWnd, imp->mDlgResult);
+      return TRUE;
+
+   case WM_COMMAND:
+      if (HIWORD(wParam) == BN_CLICKED)
+      {
+         char tmp[MAX_PATH], *end;
+         bool close = false;
+         switch (LOWORD(wParam))
+         {
+         case IDOK:
+            // Validity Check
+            GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH);
+            if (tmp[0] != 0)
+            {
+               int nifVersion = GetVersion(tmp);
+               if (!IsVersionSupported(nifVersion))
+               {
+                  MessageBox(hWnd, FormatString("Version '%s' is not a supported version.", tmp).c_str(), "NifExport", MB_OK|MB_ICONSTOP);
+                  return FALSE;
+               }
+            }
+
+            Exporter::mExportHidden = IsDlgButtonChecked(hWnd, IDC_CHK_HIDDEN);
+            Exporter::mExportLights = IsDlgButtonChecked(hWnd, IDC_CHK_LIGHTS);
+            Exporter::mExportCameras = IsDlgButtonChecked(hWnd, IDC_CHK_CAMERA);
+            Exporter::mExportTransforms = IsDlgButtonChecked(hWnd, IDC_CHK_TRANSFORMS);
+
+            GetDlgItemText(hWnd, IDC_ED_PRIORITY, tmp, MAX_PATH);
+            Exporter::mDefaultPriority = atof(tmp);
+
+            GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH);
+            if (AppSettings *appSettings = FindAppSetting(tmp))
+            {
+               Exporter::mGameName = appSettings->Name;
+               GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH);
+               Exporter::mNifVersion = tmp;
+               GetDlgItemText(hWnd, IDC_CB_USER_VERSION, tmp, MAX_PATH);
+               Exporter::mNifUserVersion = strtol(tmp, &end, 0);
+            }
+
+            EndDialog(hWnd, imp->mDlgResult=IDOK);
+            close = true;
+            break;
+
+         case IDCANCEL:
+            EndDialog(hWnd, imp->mDlgResult=IDCANCEL);
+            close = true;
+            break;
+         }
+
+         if (close)
+            SendMessage(hWnd, WM_CLOSE, 0, 0);
+      }
+      else if (HIWORD(wParam) == STN_CLICKED)
+      {
+         if (LOWORD(wParam) == IDC_LBL_LINK)
+         {
+            ShellExecute(hWnd, "open", "http://www.niftools.org",
+               NULL, NULL, SW_SHOWDEFAULT);
+         }
+      }
+      else if (HIWORD(wParam) == CBN_SELCHANGE)
+      {
+         if (LOWORD(wParam) == IDC_CB_GAME)
+         {
+            char tmp[MAX_PATH];
+            GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH);
+            if (AppSettings *appSettings = FindAppSetting(tmp))
+            {
+               string version = appSettings->NiVersion;
+               string userVer = FormatString("%d", appSettings->NiUserVersion);
+               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()));
+            }
+         }
+      }
+      break;
+   }
+   return FALSE;
+}
+
 //--- KfExport -------------------------------------------------------
 KfExport::KfExport()
 {
@@ -141,8 +263,103 @@ BOOL KfExport::SupportsOptions(int ext, DWORD options)
 
 int	KfExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options)
 {
-   // read application settings
-   AppSettings::Initialize(i);
+   try
+   {
+      // read application settings
+      AppSettings::Initialize(i);
+
+      TCHAR iniName[MAX_PATH];
+      LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR);
+      PathCombine(iniName, pluginDir, "MaxNifTools.ini");
+      bool iniNameIsValid = (-1 != _taccess(iniName, 0));
+
+      // read config from registry
+      Exporter::readKfConfig(i);
+
+      AppSettings *appSettings = NULL;
+      if (iniNameIsValid)
+      {
+         string fname = name;
+         // Locate which application to use. If Auto, find first app where this file appears in the root path list
+         string curapp = GetIniValue<string>(KfExportSection, "CurrentApp", "AUTO", iniName);
+         if (0 == _tcsicmp(curapp.c_str(), "AUTO")) {
+            // Scan Root paths
+            for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){
+               if ((*itr).IsFileInRootPaths(fname)) {
+                  appSettings = &(*itr);
+                  break;
+               }
+            }
+         } else {
+            appSettings = FindAppSetting(curapp);
+         }
+      }
+      if (appSettings == NULL && !TheAppSettings.empty())
+         appSettings = &TheAppSettings.front();
+
+      Exporter::mGameName = appSettings->Name;
+      Exporter::mNifVersion = appSettings->NiVersion;
+      Exporter::mNifUserVersion = appSettings->NiUserVersion;
+
+      if(!suppressPrompts)
+      {
+         if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_KF_PANEL), GetActiveWindow(), KfExportOptionsDlgProc, (LPARAM)this) != IDOK)
+            return true;
+
+         // write config to registry
+         Exporter::writeKfConfig(i);
+
+         // write config to root node
+         Exporter::writeConfig(i->GetRootNode());
+
+         // Update the current app version
+         appSettings = FindAppSetting(Exporter::mGameName);
+         if (appSettings == NULL && !TheAppSettings.empty())
+            appSettings = &TheAppSettings.front();
+         appSettings->NiVersion = Exporter::mNifVersion;
+         appSettings->NiUserVersion = Exporter::mNifUserVersion;
+         appSettings->WriteSettings(i);
+      }
+
+      int nifVersion = VER_20_0_0_5;
+      int nifUserVer = Exporter::mNifUserVersion;
+
+      if (!Exporter::mNifVersion.empty())
+      {
+         nifVersion = GetVersion(Exporter::mNifVersion);
+         if (!IsVersionSupported(nifVersion))
+            throw exception(FormatString("Version '%s' is not a supported version.").c_str());
+      }
+
+      Exporter::mSelectedOnly = (options&SCENE_EXPORT_SELECTED) != 0;
+      Exporter exp(i, appSettings);
+
+      Ref<NiControllerSequence> root = new NiControllerSequence();
+
+      TCHAR fname[MAX_PATH];
+      _tcscpy(fname, PathFindFileName(name));
+      PathRemoveExtension(fname);
+      root->SetName(fname);
+
+      Exporter::Result result = exp.doAnimExport(root);
+
+      if (result!=Exporter::Ok)
+         throw exception("Unknown error.");
+
+      WriteNifTree(name, StaticCast<NiObject>(root), nifVersion, nifUserVer);
+   }
+
+   catch (exception &e)
+   {
+      MessageBox(NULL, e.what(), "Export Error", MB_OK);
+      return true;
+   }
+
+   catch (...)
+   {
+      MessageBox(NULL, "Unknown error.", "Export Error", MB_OK);
+      return true;
+   }
 
    return TRUE;
 }
\ No newline at end of file
diff --git a/NifExport/MtlTex.cpp b/NifExport/MtlTex.cpp
index 75b4089cd2050e44187e0961f0ab882b4a14ba92..9465d638f0ccbc8947b0a359f3ffb5dbfd208226 100755
--- a/NifExport/MtlTex.cpp
+++ b/NifExport/MtlTex.cpp
@@ -136,16 +136,16 @@ void Exporter::makeMaterial(NiAVObjectRef &parent, Mtl *mtl)
          if (smtl->SupportsShaders()) {
             if (Shader *s = smtl->GetShader()) {
                if (smtl->GetWire()){
-                  NiWireframePropertyRef wireProp = CreateNiObject<NiWireframeProperty>();
+                  NiWireframePropertyRef wireProp = new NiWireframeProperty();
                   wireProp->SetFlags(1);
                   parent->AddProperty(wireProp);
                }
                if (smtl->GetTwoSided()){
-                  NiStencilPropertyRef stencil = CreateNiObject<NiStencilProperty>();
-                  stencil->SetStencilFunction(4);
+                  NiStencilPropertyRef stencil = new NiStencilProperty();
+                  stencil->SetStencilFunction(TEST_GREATER);
                   stencil->SetStencilEnabled(false);
-                  stencil->SetPassAction(3);
-                  stencil->SetDrawMode(3);
+                  stencil->SetPassAction(ACTION_INCREMENT);
+                  stencil->SetDrawMode(DRAW_BOTH);
                   parent->AddProperty(stencil);
                }
                if (smtl->IsFaceted()) {
@@ -343,10 +343,10 @@ bool Exporter::exportCiv4Shader(NiAVObjectRef parent, Mtl* mtl)
                }
                if (smtl->GetTwoSided()){
                   NiStencilPropertyRef stencil = CreateNiObject<NiStencilProperty>();
-                  stencil->SetStencilFunction(4);
+                  stencil->SetStencilFunction(TEST_GREATER);
                   stencil->SetStencilEnabled(false);
-                  stencil->SetPassAction(3);
-                  stencil->SetDrawMode(3);
+                  stencil->SetPassAction(ACTION_INCREMENT);
+                  stencil->SetDrawMode(DRAW_BOTH);
                   parent->AddProperty(stencil);
                }
                if (smtl->IsFaceted()) {
diff --git a/NifExport/NifExport.cpp b/NifExport/NifExport.cpp
index c434a040a0617c47aa96e71c101746b1519f789f..4a7be3b46dcf171409aa11ef92ceb10ffda3f6cd 100755
--- a/NifExport/NifExport.cpp
+++ b/NifExport/NifExport.cpp
@@ -7,7 +7,7 @@ using namespace Niflib;
 
 #define NifExport_CLASS_ID	Class_ID(0xa57ff0a4, 0xa0374ffb)
 
-static LPCTSTR NifExportSection = TEXT("MaxNifExport");
+LPCTSTR NifExportSection = TEXT("MaxNifExport");
 
 class NifExport : public SceneExport 
 {
@@ -41,7 +41,7 @@ class NifExportClassDesc : public ClassDesc2
 	public:
 	int 			IsPublic() { return TRUE; }
 	void			*Create(BOOL loading = FALSE) { return new NifExport(); }
-	const TCHAR		*ClassName() { return GetString(IDS_CLASS_NAME); }
+	const TCHAR		*ClassName() { return GetString(IDS_NIF_CLASS_NAME); }
 	SClass_ID		SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
 	Class_ID		ClassID() { return NifExport_CLASS_ID; }
 	const TCHAR		*Category() { return GetString(IDS_CATEGORY); }
@@ -283,68 +283,69 @@ BOOL NifExport::SupportsOptions(int ext, DWORD options)
 
 int	NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options)
 {
-   // read application settings
-   AppSettings::Initialize(i);
-
-   TCHAR iniName[MAX_PATH];
-   LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR);
-   PathCombine(iniName, pluginDir, "MaxNifTools.ini");
-   bool iniNameIsValid = (-1 != _taccess(iniName, 0));
-
-   // Set whether Config should use registry or not
-   Exporter::mUseRegistry = !iniNameIsValid || GetIniValue<bool>(NifExportSection, "UseRegistry", false, iniName);
-	// read config from registry
-	Exporter::readConfig(i);
-	// read config from root node
-	Exporter::readConfig(i->GetRootNode());
-
-   // locate the "default" app setting
-   AppSettings *appSettings = NULL;
-   if (iniNameIsValid)
-   {
-      string fname = name;
-      // 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")) {
-         // Scan Root paths
-         for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){
-            if ((*itr).IsFileInRootPaths(fname)) {
-               appSettings = &(*itr);
-               break;
+	try
+	{
+      // read application settings
+      AppSettings::Initialize(i);
+
+      TCHAR iniName[MAX_PATH];
+      LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR);
+      PathCombine(iniName, pluginDir, "MaxNifTools.ini");
+      bool iniNameIsValid = (-1 != _taccess(iniName, 0));
+
+      // Set whether Config should use registry or not
+      Exporter::mUseRegistry = !iniNameIsValid || GetIniValue<bool>(NifExportSection, "UseRegistry", false, iniName);
+      // read config from registry
+      Exporter::readConfig(i);
+      // read config from root node
+      Exporter::readConfig(i->GetRootNode());
+
+      // locate the "default" app setting
+      AppSettings *appSettings = NULL;
+      if (iniNameIsValid)
+      {
+         string fname = name;
+         // 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")) {
+            // Scan Root paths
+            for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){
+               if ((*itr).IsFileInRootPaths(fname)) {
+                  appSettings = &(*itr);
+                  break;
+               }
             }
+         } else {
+            appSettings = FindAppSetting(curapp);
          }
-      } else {
-         appSettings = FindAppSetting(curapp);
       }
-   }
-   if (appSettings == NULL && !TheAppSettings.empty())
-      appSettings = &TheAppSettings.front();
+      if (appSettings == NULL && !TheAppSettings.empty())
+         appSettings = &TheAppSettings.front();
 
-	if(!suppressPrompts)
-	{
       Exporter::mGameName = appSettings->Name;
       Exporter::mNifVersion = appSettings->NiVersion;
       Exporter::mNifUserVersion = appSettings->NiUserVersion;
 
-		if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), NifExportOptionsDlgProc, (LPARAM)this) != IDOK)
-			return true;
-
-		// write config to registry
-		Exporter::writeConfig(i);
-		// write config to root node
-		Exporter::writeConfig(i->GetRootNode());
-
-      // Update the current app version
-      appSettings = FindAppSetting(Exporter::mGameName);
-      if (appSettings == NULL && !TheAppSettings.empty())
-         appSettings = &TheAppSettings.front();
-      appSettings->NiVersion = Exporter::mNifVersion;
-      appSettings->NiUserVersion = Exporter::mNifUserVersion;
-      appSettings->WriteSettings(i);
-	}
+      if(!suppressPrompts)
+      {
+         if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_NIF_PANEL), GetActiveWindow(), NifExportOptionsDlgProc, (LPARAM)this) != IDOK)
+            return true;
+
+         // write config to registry
+         Exporter::writeConfig(i);
+         // write config to root node
+         Exporter::writeConfig(i->GetRootNode());
+
+         // Update the current app version
+         appSettings = FindAppSetting(Exporter::mGameName);
+         if (appSettings == NULL && !TheAppSettings.empty())
+            appSettings = &TheAppSettings.front();
+         appSettings->NiVersion = Exporter::mNifVersion;
+         appSettings->NiUserVersion = Exporter::mNifUserVersion;
+         appSettings->WriteSettings(i);
+      }
+
 
-	try
-	{
       int nifVersion = VER_20_0_0_5;
       int nifUserVer = Exporter::mNifUserVersion;
 
diff --git a/NifExport/NifExport.rc b/NifExport/NifExport.rc
index 5c6fc3a057fd45cc1c041fb16a9506a7af96a616..e9f8667ef76badcbcc0debc9b014428f172e567a 100755
--- a/NifExport/NifExport.rc
+++ b/NifExport/NifExport.rc
@@ -73,7 +73,32 @@ END
 // Dialog
 //
 
-IDD_PANEL DIALOGEX 0, 0, 205, 203
+IDD_KF_PANEL DIALOGEX 0, 0, 205, 130
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Export KF"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    GROUPBOX        "Export:",IDC_STATIC,7,7,81,66
+    CONTROL         "&Hidden Nodes",IDC_CHK_HIDDEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,17,67,10
+    CONTROL         "Transforms",IDC_CHK_TRANSFORMS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,31,67,10
+    CONTROL         "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,44,67,10
+    CONTROL         "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,58,67,10
+    GROUPBOX        "Behaviors:",IDC_STATIC,94,7,104,66
+    LTEXT           "Priority:",IDC_LBL_PRIORITY,104,24,37,8
+    EDITTEXT        IDC_ED_PRIORITY,145,22,39,12,ES_AUTOHSCROLL
+    LTEXT           "Game",IDC_STATIC,7,78,66,8
+    COMBOBOX        IDC_CB_GAME,7,89,105,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Version",IDC_STATIC,117,78,39,8
+    EDITTEXT        IDC_CB_VERSION,117,89,45,12,ES_AUTOHSCROLL
+    LTEXT           "User",IDC_STATIC,167,78,25,8
+    EDITTEXT        IDC_CB_USER_VERSION,167,89,30,12,ES_AUTOHSCROLL
+    DEFPUSHBUTTON   "&Export",IDOK,5,109,34,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,45,109,33,14
+    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
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_TOOLWINDOW
 CAPTION "Export Nif"
@@ -122,7 +147,15 @@ END
 #ifdef APSTUDIO_INVOKED
 GUIDELINES DESIGNINFO 
 BEGIN
-    IDD_PANEL, DIALOG
+    IDD_KF_PANEL, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 198
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 123
+    END
+
+    IDD_NIF_PANEL, DIALOG
     BEGIN
         LEFTMARGIN, 7
         RIGHTMARGIN, 198
@@ -139,8 +172,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,3,0
- PRODUCTVERSION 0,2,3,0
+ FILEVERSION 0,2,4,0
+ PRODUCTVERSION 0,2,4,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -156,12 +189,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Exporter"
-            VALUE "FileVersion", "0, 2, 3, 0"
+            VALUE "FileVersion", "0, 2, 4, 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, 3, 0"
+            VALUE "ProductVersion", "0, 2, 4, 0"
         END
     END
     BLOCK "VarFileInfo"
@@ -178,9 +211,10 @@ END
 
 STRINGTABLE 
 BEGIN
-    IDS_CLASS_NAME          "Nif Exporter"
+    IDS_NIF_CLASS_NAME      "Niftools NIF Exporter"
     IDS_PARAMS              "Parameters"
     IDS_SPIN                "Spin"
+    IDS_KF_CLASS_NAME       "Niftools KF Exporter"
 END
 
 #endif    // English (U.S.) resources
diff --git a/NifExport/resource.h b/NifExport/resource.h
index 2aeda3876b1813200b7f14bf54146135089fb35a..3d67a7f977ff854f1ab41c0ba34a65177ff3043a 100755
--- a/NifExport/resource.h
+++ b/NifExport/resource.h
@@ -5,9 +5,13 @@
 #define IDS_LIBDESCRIPTION              1
 #define IDS_CATEGORY                    2
 #define IDS_CLASS_NAME                  3
+#define IDS_NIF_CLASS_NAME              3
 #define IDS_PARAMS                      4
 #define IDS_SPIN                        5
+#define IDS_KF_CLASS_NAME               6
 #define IDD_PANEL                       101
+#define IDD_NIF_PANEL                   101
+#define IDD_KF_PANEL                    102
 #define IDC_CLOSEBUTTON                 1000
 #define IDC_DOSTUFF                     1000
 #define IDC_CHK_HIDDEN                  1003
@@ -18,8 +22,10 @@
 #define IDC_ED_WELDTHRESH               1008
 #define IDC_LBL_WELDTHRESH              1009
 #define IDC_CHK_COLL                    1010
+#define IDC_ED_PRIORITY                 1010
 #define IDC_LBL_LINK                    1011
 #define IDC_CHK_VCOLORS                 1012
+#define IDC_LBL_PRIORITY                1012
 #define IDC_CHK_REMAP                   1013
 #define IDC_CB_GAME                     1014
 #define IDC_CB_VERSION                  1015
@@ -36,6 +42,8 @@
 #define IDC_CHK_CAMERA                  1025
 #define IDC_CHK_SKEL_ONLY2              1026
 #define IDC_CHK_BONE_COLL               1026
+#define IDC_CHK_TRANSFORMS              1026
+#define IDC_EDIT1                       1027
 #define IDC_COLOR                       1456
 #define IDC_EDIT                        1490
 #define IDC_SPIN                        1496
@@ -46,7 +54,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        102
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1025
+#define _APS_NEXT_CONTROL_VALUE         1028
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
diff --git a/NifFurniture/NifFurniture.rc b/NifFurniture/NifFurniture.rc
index ce1e6e697d9b33904a342f40321a6c2190fb1e55..3c75f27838963c2b7681050ae1b370c57ee8180b 100755
--- a/NifFurniture/NifFurniture.rc
+++ b/NifFurniture/NifFurniture.rc
@@ -107,8 +107,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,3,0
- PRODUCTVERSION 0,2,3,0
+ FILEVERSION 0,2,4,0
+ PRODUCTVERSION 0,2,4,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, 3, 0"
+            VALUE "FileVersion", "0, 2, 4, 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, 3, 0"
+            VALUE "ProductVersion", "0, 2, 4, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp
index 72ee9f4f15dfe28230dc9ea07a190fde8caa44ad..58494607f163373e7991f65ffd03946a173b3287 100644
--- a/NifImport/ImportAnimation.cpp
+++ b/NifImport/ImportAnimation.cpp
@@ -18,6 +18,7 @@ HISTORY:
 #include "KFMImporter.h"
 #include "KFImporter.h"
 #include "AnimKey.h"
+#include "NifPlugins.h"
 #include <obj/NiInterpolator.h>
 #include <obj/NiTransformInterpolator.h>
 #include <obj/NiTransformData.h>
@@ -136,11 +137,20 @@ void NifImporter::ClearAnimation(INode *node)
 {
    if (node != NULL)
    {
+      if (node->HasNoteTracks()){
+         for (int i = node->NumNoteTracks()-1; i>=0; --i ){
+            if (NoteTrack *nt = node->GetNoteTrack(i))
+               node->DeleteNoteTrack(nt, TRUE);
+         }
+      }
       node->DeleteKeys(TRACK_DOALL);
       ::ClearAnimation(node->GetTMController());
       for (int i=0, n=node->NumberOfChildren(); i<n; ++i){
          ClearAnimation(node->GetChildNode(i));
       }
+
+      // Clear animation priority
+      node->SetUserPropFloat(NP_ANM_PRI, 0.0f);
    }
 }
 void NifImporter::ClearAnimation()
@@ -304,7 +314,48 @@ bool KFMImporter::ImportAnimation()
          if (addNoteTracks) {
             string target = cntr->GetTargetName();
             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;
+                        }
+                     }
+                     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);
+                  }
+               }
+
+#else
                TSTR script;
                script += 
                "fn getActorManager obj = (\n"
@@ -326,7 +377,7 @@ bool KFMImporter::ImportAnimation()
                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) + 1;
+                  TimeValue t = TimeToFrame(time + (*itr).time);
 
                   if (wildmatch("start*", (*itr).data)){
                      stringlist args = TokenizeCommandLine((*itr).data.c_str(), true);
@@ -363,6 +414,7 @@ bool KFMImporter::ImportAnimation()
                   //nt->keys.Append(1, &key);
                }
                ExecuteMAXScriptScript(script, TRUE, NULL);
+#endif
             }
          }
 
@@ -396,6 +448,10 @@ bool KFMImporter::ImportAnimation()
 
          INode *n = gi->GetINodeByName(name.c_str());
 
+         if ((*lnk).priority_ != 0.0f) {
+            npSetProp(n, NP_ANM_PRI, (*lnk).priority_);
+         }
+
          NiKeyframeDataRef data;
          Point3 p; Quat q; float s;
          if (ai.GetTransformData(*lnk, name, data, p, q, s)) {
diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp
index 0649cb40d39c33b5064beca07cf3f800906f4018..1d8cfc5b8a1372cd0837a187157bd81291883d25 100644
--- a/NifImport/ImportSkeleton.cpp
+++ b/NifImport/ImportSkeleton.cpp
@@ -686,6 +686,9 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse)
 
 bool NifImporter::ImportUPB(INode *node, Niflib::NiNodeRef block)
 {
+   if (!importUPB)
+      return false;
+
    bool ok = false;
    if (node && block)
    {
diff --git a/NifImport/MaxNifImport.cpp b/NifImport/MaxNifImport.cpp
index dcb540767ea78219ba64fafb500572834903f57c..acd397005f135bb0bd5a350d78bd082cfcad9c5c 100644
--- a/NifImport/MaxNifImport.cpp
+++ b/NifImport/MaxNifImport.cpp
@@ -203,20 +203,16 @@ int MaxNifImport::DoImport(const TCHAR *filename,ImpInterface *i, Interface *gi,
             return FALSE;
          ok = importer.DoImport();
       }
+   }
+   catch (exception &e)
+   {
+      MessageBox(NULL, e.what(), "Import Error", MB_OK);
+      return TRUE;
    }
-   catch( exception & e ) 
+   catch (...)
    {
-      e=e;
-      ok = false;
-   }
-   catch( exception * e ) 
-   {
-      e=e;
-      ok = false;
-   }
-   catch( ... ) 
-   {
-      ok = false;
+      MessageBox(NULL, "Unknown error.", "Import Error", MB_OK);
+      return TRUE;
    }
    return ok ? TRUE : FALSE;
 }
diff --git a/NifImport/MaxNifImport.rc b/NifImport/MaxNifImport.rc
index 158f7c58ee899eb2a3b38a5d2ab1d138e54a3762..6ca19508c6329bf51f5241e622a9db3dd1ccbcda 100644
--- a/NifImport/MaxNifImport.rc
+++ b/NifImport/MaxNifImport.rc
@@ -36,27 +36,28 @@ BEGIN
     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         "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,86,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
-    GROUPBOX        "Behaviors:",IDC_STATIC,94,6,101,92
     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         "Use &Biped",IDC_CHK_BIPED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,102,84,87,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
-    LTEXT           "Game:",IDC_STATIC,7,129,31,8
-    COMBOBOX        IDC_CB_GAME,47,127,131,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     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
-    CONTROL         "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,73,88,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
 END
 
 IDD_KF_PANEL DIALOGEX 0, 0, 118, 99
@@ -66,12 +67,12 @@ CAPTION "Import KF"
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
     GROUPBOX        "Import:",-1,7,6,104,51
-    DEFPUSHBUTTON   "&Import",IDOK,5,78,34,14
-    PUSHBUTTON      "&Cancel",IDCANCEL,45,78,33,14
-    LTEXT           "http://www.niftools.org",IDC_LBL_LINK,7,61,95,14,SS_NOTIFY | SS_CENTERIMAGE
     CONTROL         "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,72,10
     CONTROL         "Add Key Notes",IDC_CHK_KEYNOTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,31,72,10
     CONTROL         "Add Time Tags",IDC_CHK_TIMETAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,44,72,10
+    LTEXT           "http://www.niftools.org",IDC_LBL_LINK,7,61,95,14,SS_NOTIFY | SS_CENTERIMAGE
+    DEFPUSHBUTTON   "&Import",IDOK,5,78,34,14
+    PUSHBUTTON      "&Cancel",IDCANCEL,45,78,33,14
 END
 
 
@@ -134,8 +135,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,3,0
- PRODUCTVERSION 0,2,3,0
+ FILEVERSION 0,2,4,0
+ PRODUCTVERSION 0,2,4,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -151,12 +152,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Importer"
-            VALUE "FileVersion", "0, 2, 3, 0"
+            VALUE "FileVersion", "0, 2, 4, 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, 3, 0"
+            VALUE "ProductVersion", "0, 2, 4, 0"
         END
     END
     BLOCK "VarFileInfo"
@@ -175,7 +176,7 @@ STRINGTABLE
 BEGIN
     IDS_LIBDESCRIPTION      "Importer for NIF files"
     IDS_CATEGORY            "NifTools"
-    IDS_CLASS_NAME          "MaxNifImport"
+    IDS_CLASS_NAME          "Niftools_Nif_Importer"
     IDS_PARAMS              "Parameters"
     IDS_SPIN                "Spin"
 END
diff --git a/NifImport/NIFImport.cpp b/NifImport/NIFImport.cpp
index 001a36d737206f02b48ad30289abfc42ea93af89..cb52375cb6d692979d4ffa47116b8b558e91a5ee 100644
--- a/NifImport/NIFImport.cpp
+++ b/NifImport/NIFImport.cpp
@@ -147,6 +147,7 @@ void NifImporter::LoadIniSettings()
    vertexColorMode = GetIniValue<int>(NifImportSection, "VertexColorMode", 1);
    useCiv4Shader = GetIniValue(NifImportSection, "UseCiv4Shader", true);
    mergeNonAccum = GetIniValue(NifImportSection, "MergeNonAccum", true);
+   importUPB = GetIniValue(NifImportSection, "ImportUPB", true);
 
    // Biped
    importBones = GetIniValue(BipedImportSection, "ImportBones", true);
@@ -210,6 +211,7 @@ void NifImporter::SaveIniSettings()
    SetIniValue(NifImportSection, "EnableAutoSmooth", enableAutoSmooth);
    SetIniValue(NifImportSection, "RemoveIllegalFaces", removeIllegalFaces);
    SetIniValue(NifImportSection, "RemoveDegenerateFaces", removeDegenerateFaces);
+   SetIniValue(NifImportSection, "ImportUPB", importUPB);
 
    SetIniValue(BipedImportSection, "ImportBones", importBones);
    SetIniValue(BipedImportSection, "RemoveUnusedImportedBones", removeUnusedImportedBones);  
diff --git a/NifImport/NIFImporter.h b/NifImport/NIFImporter.h
index 087328b405962b56044304fa2905b90f7e6ffe0d..6d472028309dade4451d3ae70617d89c9130bb44 100644
--- a/NifImport/NIFImporter.h
+++ b/NifImport/NIFImporter.h
@@ -36,6 +36,7 @@ public:
    bool mergeNonAccum;
    bool enableLights;
    bool enableCameras;
+   bool importUPB;
 
    // Biped/Bones related settings
    bool importBones;
diff --git a/NifImport/NifDialog.cpp b/NifImport/NifDialog.cpp
index 2bf1152e9a8236f6b3e98b3fbbbe754e181f666c..4a36f8779db996420c8327b8c413b6a0ce578117 100644
--- a/NifImport/NifDialog.cpp
+++ b/NifImport/NifDialog.cpp
@@ -57,6 +57,8 @@ static BOOL CALLBACK MaxNifImportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wP
             CheckDlgButton(hWnd, IDC_CHK_CLEARANIM, imp->clearAnimation);
             
             CheckDlgButton(hWnd, IDC_CHK_BIPED, imp->useBiped);
+            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)
@@ -108,6 +110,7 @@ static BOOL CALLBACK MaxNifImportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wP
                   imp->removeUnusedImportedBones = IsDlgButtonChecked(hWnd, IDC_CHK_REM_BONES) ? true : false;
                   imp->clearAnimation = IsDlgButtonChecked(hWnd, IDC_CHK_CLEARANIM) ? true : false;
                   imp->useBiped = IsDlgButtonChecked(hWnd, IDC_CHK_BIPED) ? true : false;
+                  imp->importUPB = IsDlgButtonChecked(hWnd, IDC_CHK_UPB) ? false : true;
 
                   GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH);
                   if (AppSettings *appSettings = FindAppSetting(tmp)) {
diff --git a/NifImport/resource.h b/NifImport/resource.h
index a608a761e71fb321548495c9ddbdc68b35d7be4e..22c9238e83a9422022be341a1ddf40d92b7d6bbf 100644
--- a/NifImport/resource.h
+++ b/NifImport/resource.h
@@ -21,6 +21,7 @@
 #define IDC_ED_SKELETON                 1006
 #define IDC_CHK_BIPED                   1007
 #define IDC_CHK_LIGHTS                  1008
+#define IDC_CHK_UPB                     1009
 #define IDC_CHK_COLL                    1010
 #define IDC_LBL_LINK                    1011
 #define IDC_CHK_VCOLORS                 1012
diff --git a/NifProps/NifProps.cpp b/NifProps/NifProps.cpp
index 62b11aea08c3b295390abf2a3a8fa12858168ddf..af0afb2cf8e9060d7e581a3317a4c14e9043aaa1 100755
--- a/NifProps/NifProps.cpp
+++ b/NifProps/NifProps.cpp
@@ -27,11 +27,13 @@ public:
 
 	void			selectionChanged();
 
-	BOOL			dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+   BOOL			dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+   BOOL			dlgAnimProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
 private:
 		
-	HWND			mPanel;
+   HWND			mPanel;
+   HWND			mAnimPanel;
 	IUtil			*mIU;
 	Interface		*mIP;
 	INode			*mNode;
@@ -44,7 +46,7 @@ private:
 	NpComboBox		mCbMotionSystem;
 	NpComboBox		mCbQualityType;
 
-	void enableGUI(BOOL object, BOOL hvk);		
+	void enableGUI(BOOL object, BOOL hvk, BOOL anim);		
 };
 
 static NifProps plugin;
@@ -74,7 +76,12 @@ ClassDesc2* GetNifPropsDesc() { return &NifPropsDesc; }
 
 static BOOL CALLBACK NifPropsDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-	return plugin.dlgProc(hWnd, msg, wParam, lParam);
+   return plugin.dlgProc(hWnd, msg, wParam, lParam);
+}
+
+static BOOL CALLBACK NifAnimPropsDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+   return plugin.dlgAnimProc(hWnd, msg, wParam, lParam);
 }
 
 
@@ -86,6 +93,7 @@ NifProps::NifProps()
 	mIU = NULL;
 	mIP = NULL;	
 	mPanel = NULL;
+   mAnimPanel = NULL;
 }
 
 NifProps::~NifProps()
@@ -163,6 +171,17 @@ void NifProps::BeginEditParams(Interface *ip, IUtil *iu)
 		str++;
 	}
 
+   
+   //mAnimPanel = ip->AddRollupPage(
+   //   hInstance,
+   //   MAKEINTRESOURCE(IDD_ANIM_PANEL),
+   //   NifAnimPropsDlgProc,
+   //   GetString(IDS_ANIM_PARAMS),
+   //   0);
+
+   mSpins[IDC_SP_ANIM_PRIORITY] = 
+      SetupFloatSpinner(mPanel, IDC_SP_ANIM_PRIORITY, IDC_ED_ANIM_PRIORITY, 0, 255, 25, .1f);
+
 	selectionChanged();
 }
 	
@@ -179,7 +198,7 @@ void NifProps::EndEditParams(Interface *ip,IUtil *iu)
 	mNode = NULL;
 }
 
-void NifProps::enableGUI(BOOL obj, BOOL hvk)
+void NifProps::enableGUI(BOOL obj, BOOL hvk, BOOL anim)
 {
 	EnableWindow(GetDlgItem(mPanel, IDC_GRP_OBJECT), obj);
 	EnableWindow(GetDlgItem(mPanel, IDC_CHK_ISCOLL), obj);
@@ -190,8 +209,11 @@ void NifProps::enableGUI(BOOL obj, BOOL hvk)
 	EnableWindow(GetDlgItem(mPanel, IDC_LBL_LAYER), hvk);
 	EnableWindow(GetDlgItem(mPanel, IDC_CB_LAYER), hvk);
 */
-	for (int i=IDC_HVK_BEGIN; i<=IDC_HVK_END; i++)
-		EnableWindow(GetDlgItem(mPanel, i), hvk);
+   for (int i=IDC_HVK_BEGIN; i<=IDC_HVK_END; i++)
+      EnableWindow(GetDlgItem(mPanel, i), hvk);
+
+   for (int i=IDC_ANIM_BEGIN; i<=IDC_ANIM_END; i++)
+      EnableWindow(GetDlgItem(mPanel, i), anim);
 }
 
 void NifProps::SelectionSetChanged(Interface *ip, IUtil *iu)
@@ -205,7 +227,7 @@ void NifProps::selectionChanged()
 	if (numSel <= 0)
 	{
 		mNode = NULL;
-		enableGUI(false, false);
+		enableGUI(false, false, false);
 		return;
 	}
 
@@ -213,7 +235,7 @@ void NifProps::selectionChanged()
 	INode *nodeSel = mIP->GetSelNode(0);
 	bool isColl = npIsCollision(nodeSel);
 
-	enableGUI(singleSel, singleSel && isColl);
+	enableGUI(singleSel, singleSel && isColl, true);
 	mNode = singleSel?nodeSel:NULL;		
 	
 	if (!singleSel)
@@ -262,6 +284,9 @@ void NifProps::selectionChanged()
 	mSpins[IDC_SP_MAX_LINEAR_VELOCITY]->SetValue(maxlinvel, TRUE);
 	mSpins[IDC_SP_MAX_ANGULAR_VELOCITY]->SetValue(maxangvel, TRUE);
 
+   float priority;
+   npGetProp(nodeSel, NP_ANM_PRI, priority, NP_DEFAULT_ANM_PRI);
+   mSpins[IDC_SP_ANIM_PRIORITY]->SetValue(priority, TRUE);
 
 }
 
@@ -383,6 +408,12 @@ BOOL NifProps::dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 				case IDC_SP_PENETRATION_DEPTH:
 					npSetProp(mNode, NP_HVK_PENETRATION_DEPTH, mSpins[IDC_SP_PENETRATION_DEPTH]->GetFVal());
 					break;
+
+            case IDC_SP_ANIM_PRIORITY:
+               for (int i=0, n=mIP->GetSelNodeCount(); i<n; ++i) {
+                  npSetProp(mIP->GetSelNode(i), NP_ANM_PRI, mSpins[IDC_SP_ANIM_PRIORITY]->GetFVal());
+               }
+               break;
 			}
 			break;
 
diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc
index a070ca4e46c5465c23f6c4656e710f9099771d4c..68b5abcad3841198bf8997669839975917c566ce 100755
--- a/NifProps/NifProps.rc
+++ b/NifProps/NifProps.rc
@@ -73,7 +73,7 @@ END
 // Dialog
 //
 
-IDD_PANEL DIALOGEX 0, 0, 107, 401
+IDD_PANEL DIALOGEX 0, 0, 107, 360
 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_VISIBLE
 FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
@@ -84,11 +84,6 @@ BEGIN
     GROUPBOX        "Havok",IDC_GRP_HAVOK,5,39,95,285,WS_DISABLED
     GROUPBOX        "Object",IDC_GRP_OBJECT,5,5,95,32
     CONTROL         "Is Collision Mesh",IDC_CHK_ISCOLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,80,10
-    GROUPBOX        "Global",IDC_STATIC,5,329,95,65,WS_DISABLED
-    EDITTEXT        IDC_ED_BSXFLAGS,13,352,80,12,ES_AUTOHSCROLL | WS_DISABLED
-    CONTROL         "BSXFlags",IDC_LBL_BSXFLAGS,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_DISABLED | WS_GROUP,13,340,80,8
-    EDITTEXT        IDC_ED_STRINGSEXTRA,13,374,80,12,ES_AUTOHSCROLL | WS_DISABLED
-    CONTROL         "Strings Extra Data",IDC_LBL_STRINGSEXTRA,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_DISABLED | WS_GROUP,13,365,80,8
     CONTROL         "Center",IDC_LBL_CENTER,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_DISABLED | WS_GROUP,12,98,31,8
     CONTROL         "Mass",IDC_LBL_MASS,"Static",SS_LEFTNOWORDWRAP | WS_DISABLED | WS_GROUP,12,124,28,8
     CONTROL         "Friction",IDC_LBL_FRICTION,"Static",SS_LEFTNOWORDWRAP | WS_DISABLED | WS_GROUP,42,124,28,8
@@ -124,6 +119,20 @@ BEGIN
     LTEXT           "Penetration\r\nDepth",IDC_LBL_PENETRATION_DEPTH,12,229,40,16,WS_DISABLED
     CONTROL         "",IDC_ED_PENETRATION_DEPTH,"CustEdit",WS_DISABLED | WS_TABSTOP,12,249,35,10
     CONTROL         "",IDC_SP_PENETRATION_DEPTH,"SpinnerControl",WS_DISABLED,45,249,7,10
+    GROUPBOX        "Animation",IDC_GRP_ANIMATION,7,325,95,28
+    LTEXT           "Priority:",IDC_STATIC,10,338,24,8
+    CONTROL         "",IDC_ED_ANIM_PRIORITY,"CustEdit",WS_DISABLED | WS_TABSTOP,39,337,20,10
+    CONTROL         "",IDC_SP_ANIM_PRIORITY,"SpinnerControl",WS_DISABLED,57,337,7,10
+END
+
+IDD_ANIM_PANEL DIALOGEX 0, 0, 107, 41
+STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_VISIBLE
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    GROUPBOX        "Animation",IDC_GRP_ANIMATION,5,5,95,28
+    LTEXT           "Priority:",IDC_STATIC,8,18,24,8
+    CONTROL         "",IDC_ED_ANIM_PRIORITY,"CustEdit",WS_DISABLED | WS_TABSTOP,37,17,20,10
+    CONTROL         "",IDC_SP_ANIM_PRIORITY,"SpinnerControl",WS_DISABLED,55,17,7,10
 END
 
 
@@ -140,7 +149,15 @@ BEGIN
         LEFTMARGIN, 7
         RIGHTMARGIN, 100
         TOPMARGIN, 7
-        BOTTOMMARGIN, 394
+        BOTTOMMARGIN, 353
+    END
+
+    IDD_ANIM_PANEL, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 100
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 34
     END
 END
 #endif    // APSTUDIO_INVOKED
@@ -342,8 +359,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,3,0
- PRODUCTVERSION 0,2,3,0
+ FILEVERSION 0,2,4,0
+ PRODUCTVERSION 0,2,4,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -359,12 +376,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Reactor Properites Plugin"
-            VALUE "FileVersion", "0, 2, 3, 0"
+            VALUE "FileVersion", "0, 2, 4, 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, 3, 0"
+            VALUE "ProductVersion", "0, 2, 4, 0"
         END
     END
     BLOCK "VarFileInfo"
@@ -386,6 +403,7 @@ BEGIN
     IDS_CLASS_NAME          "NifProps"
     IDS_PARAMS              "Parameters"
     IDS_SPIN                "Spin"
+    IDS_ANIM_PARAMS         "Animation"
 END
 
 #endif    // English (U.S.) resources
diff --git a/NifProps/resource.h b/NifProps/resource.h
index d9cfbe897a9e3257b4e93d0b1f030f2e5afe385b..fc3cc8a3db05d5889094b7265ef816acfa5bd0d6 100755
--- a/NifProps/resource.h
+++ b/NifProps/resource.h
@@ -7,15 +7,17 @@
 #define IDS_CLASS_NAME                  3
 #define IDS_PARAMS                      4
 #define IDS_SPIN                        5
+#define IDS_ANIM_PARAMS                 6
 #define IDD_PANEL                       101
-#define IDC_LBL_BSXFLAGS				1001
-#define IDC_ED_BSXFLAGS					1002
-#define IDC_ED_STRINGSEXTRA				1003
-#define IDC_LBL_STRINGSEXTRA			1004
+#define IDD_ANIM_PANEL                  102
+#define IDC_LBL_BSXFLAGS                1001
+#define IDC_ED_BSXFLAGS                 1002
+#define IDC_ED_STRINGSEXTRA             1003
+#define IDC_LBL_STRINGSEXTRA            1004
 #define IDC_GRP_OBJECT                  1005
 #define IDC_CHK_ISCOLL                  1006
 #define IDC_GRP_HAVOK                   1007
-#define IDC_HVK_BEGIN					IDC_GRP_HAVOK
+#define IDC_HVK_BEGIN					    1007
 #define IDC_LBL_MATERIAL                1008
 #define IDC_CB_MATERIAL                 1009
 #define IDC_LBL_LAYER                   1010
@@ -51,11 +53,16 @@
 #define IDC_LBL_ANGULAR_DAMPING         1517
 #define IDC_ED_ANGULAR_DAMPING          1518
 #define IDC_SP_ANGULAR_DAMPING          1519
-#define IDC_LBL_MOTION_SYSTEM			1520
-#define IDC_CB_MOTION_SYSTEM			1521
-#define IDC_LBL_QUALITY_TYPE			1522
-#define IDC_CB_QUALITY_TYPE				1523
-#define IDC_HVK_END						IDC_CB_QUALITY_TYPE
+#define IDC_LBL_MOTION_SYSTEM           1520
+#define IDC_CB_MOTION_SYSTEM            1521
+#define IDC_LBL_QUALITY_TYPE            1522
+#define IDC_CB_QUALITY_TYPE             1523
+#define IDC_HVK_END						    1523
+#define IDC_ANIM_BEGIN                  1600
+#define IDC_GRP_ANIMATION               1600
+#define IDC_ED_ANIM_PRIORITY            1601
+#define IDC_SP_ANIM_PRIORITY            1602
+#define IDC_ANIM_END                    1602
 
 // Next default values for new objects
 // 
@@ -63,7 +70,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        103
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1035
+#define _APS_NEXT_CONTROL_VALUE         1700
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif