diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt
index b853f3e943de7165a5c7832431114b88e9ef7bbc..dcf265b09e7f2ecddbf14ec5307ed6f76d69984d 100644
--- a/MaxNifPlugins_Readme.txt
+++ b/MaxNifPlugins_Readme.txt
@@ -27,6 +27,15 @@
 
     Change log
     ----------
+      0.2.3
+      -----
+    o Exporter
+      - Fix issue when exporting a mesh with a skin modifier that had bones
+         that were not used.
+      
+    o Importer
+      - Alter code to create Camera nodes when name begins with Camera.
+    
       0.2.2
       -----
     o Exporter
diff --git a/NifCommon/AnimKey.h b/NifCommon/AnimKey.h
index 507bceaa75947257275448602763c4e62df9592e..cc66775f5ca0b3610ceaedb6b186b5ac7cd613a8 100644
--- a/NifCommon/AnimKey.h
+++ b/NifCommon/AnimKey.h
@@ -94,10 +94,11 @@ template<typename T> void MergeKey(IKeyControl *keys, T& key)
 {
    for (int i=0, n=keys->GetNumKeys(); i<n; ++i)
    {
-      T tmp; keys->GetKey(i, &tmp);
-      if (tmp.time == key.time) {
-         MergeKey(tmp, key);
-         keys->SetKey(i, &tmp);
+      AnyKey buf; T *tmp = reinterpret_cast<T*>((IKey*)buf);
+      keys->GetKey(i, tmp);
+      if (tmp->time == key.time) {
+         MergeKey<T>(*(T*)tmp, key);
+         keys->SetKey(i, tmp);
          return;
       }
    }
@@ -125,9 +126,9 @@ inline void GetKeys(Control *subCtrl, vector<T>& keys, float time)
       int n = ikeys->GetKeySize();
       keys.reserve(n);
       for (int i=0; i<n; ++i){
-         U key;
-         ikeys->GetKey(i, &key);
-         keys.push_back( MapKey<T>(key, time) );
+         AnyKey buf; U *key = reinterpret_cast<U*>((IKey*)buf);
+         ikeys->GetKey(i, key);
+         keys.push_back( MapKey<T>(*key, time) );
       }
    }
 }
diff --git a/NifCommon/niutils.cpp b/NifCommon/niutils.cpp
index fc7b014a92900668a70e347a064969b4098606f2..5164417e5244defa59a3229fe7d40edd341c85fe 100644
--- a/NifCommon/niutils.cpp
+++ b/NifCommon/niutils.cpp
@@ -343,6 +343,10 @@ void PosRotScaleNode(INode *n, Point3 p, Quat& q, float s, PosRotScale prs, Time
          ||(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) 
          ||(c->ClassID() == FOOTPRINT_CLASS_ID))
       {
+         if (prs & prsRot && q.w == FloatNegINF) prs = PosRotScale(prs & ~prsRot);
+         if (prs & prsPos && p.x == FloatNegINF) prs = PosRotScale(prs & ~prsPos);
+         if (prs & prsScale && s == FloatNegINF) prs = PosRotScale(prs & ~prsScale);
+
          ScaleValue sv(Point3(s,s,s));
          // Get the Biped Export Interface from the controller 
          //IBipedExport *BipIface = (IBipedExport *) c->GetInterface(I_BIPINTERFACE);
@@ -353,12 +357,10 @@ void PosRotScaleNode(INode *n, Point3 p, Quat& q, float s, PosRotScale prs, Time
             BipIface->SetBipedRotation(q, t, n, 0/*???*/);
          if (prs & prsPos)
             BipIface->SetBipedPosition(p, t, n);
+         return;
       }
-      else
 #endif
-      {
-         PosRotScaleNode(c, p, q, s, prs, t);
-      }
+      PosRotScaleNode(c, p, q, s, prs, t);
    }
 }
 
diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp
index 57c2e09580ae43c7895d49697712751cdccb90be..f081dde2c9487879a38e4db40d3a1a93b46fa28c 100755
--- a/NifExport/Exporter.cpp
+++ b/NifExport/Exporter.cpp
@@ -33,12 +33,15 @@ Exporter::Result Exporter::doExport(NiNodeRef &root, INode *node)
 {
    //root->SetName("Scene Root");
 
-	BSXFlagsRef bsx = CreateNiObject<BSXFlags>();
-	bsx->SetName("BSX");
-	bsx->SetFlags(0x00000002);
-   root->AddExtraData(DynamicCast<NiExtraData>(bsx));
-   bool ok = exportUPB(root, node);
+   if (mExportCollision)
+   {
+	   BSXFlagsRef bsx = CreateNiObject<BSXFlags>();
+	   bsx->SetName("BSX");
+	   bsx->SetFlags(0x00000002);
+      root->AddExtraData(DynamicCast<NiExtraData>(bsx));
+   }
 
+   bool ok = exportUPB(root, node);
    if (!ok && Exporter::mExportCollision)
    {
       NiStringExtraDataRef strings = DynamicCast<NiStringExtraData>(CreateBlock("NiStringExtraData"));	
diff --git a/NifExport/Mesh.cpp b/NifExport/Mesh.cpp
index aef49418b47ed7619f4442f3863073288c82ef84..d0aad18150f064cccefd8c80f469dd5931ca0922 100755
--- a/NifExport/Mesh.cpp
+++ b/NifExport/Mesh.cpp
@@ -441,24 +441,33 @@ bool Exporter::makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, Ti
          weights.push_back(sw);
       }         
    }
+
+   // remove unused bones
+   vector<NiNodeRef>::iterator bitr = si->boneList.begin();
+   SkinInstance::BoneWeightList::iterator switr = si->boneWeights.begin();
+   for (int i=0; i<totalBones; ++i) {
+      vector<SkinWeight> &weights = (*switr);
+      if (weights.empty())
+      {
+         bitr = si->boneList.erase(bitr);
+         switr = si->boneWeights.erase(switr);
+      }
+      else
+      {
+         ++bitr, ++switr;
+      }      
+   }
+
    return true;
 }
 
 Exporter::Result SkinInstance::execute()
 {
-   SkinWeight emptyWeight; emptyWeight.index = 0; emptyWeight.weight = 0.0f;
-   vector<SkinWeight> emptyweights; emptyweights.assign(4, emptyWeight);
-
    shape->BindSkin(boneList);
    uint bone = 0;
    for (BoneWeightList::iterator bitr = boneWeights.begin(); bitr != boneWeights.end(); ++bitr, ++bone) {
-      vector<SkinWeight> &weights = (*bitr);
-      if (!weights.empty())
-         shape->SetBoneWeights(bone, weights);
-      else
-         shape->SetBoneWeights(bone, emptyweights);
+      shape->SetBoneWeights(bone, (*bitr));
    }
    shape->GenHardwareSkinInfo();
-
    return Exporter::Ok;
 }
diff --git a/NifExport/NifExport.rc b/NifExport/NifExport.rc
index aa2504b91a57f6d026c58e6ca646b8be2d5be6b0..4108ce9142fca89ec69322eb01a90e0cd8a1403b 100755
--- a/NifExport/NifExport.rc
+++ b/NifExport/NifExport.rc
@@ -138,8 +138,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,2,0
- PRODUCTVERSION 0,2,2,0
+ FILEVERSION 0,2,3,0
+ PRODUCTVERSION 0,2,3,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -155,12 +155,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Exporter"
-            VALUE "FileVersion", "0, 2, 2, 0"
+            VALUE "FileVersion", "0, 2, 3, 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, 2, 0"
+            VALUE "ProductVersion", "0, 2, 3, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/NifFurniture/NifFurniture.rc b/NifFurniture/NifFurniture.rc
index 84a94f067d7ebff296e1a9f0215ac2d695af7e14..ce1e6e697d9b33904a342f40321a6c2190fb1e55 100755
--- a/NifFurniture/NifFurniture.rc
+++ b/NifFurniture/NifFurniture.rc
@@ -107,8 +107,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,2,0
- PRODUCTVERSION 0,2,2,0
+ FILEVERSION 0,2,3,0
+ PRODUCTVERSION 0,2,3,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, 2, 0"
+            VALUE "FileVersion", "0, 2, 3, 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, 2, 0"
+            VALUE "ProductVersion", "0, 2, 3, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp
index f4c21f9a536cf683d6564d10a63f6681fde7a9b4..590949ba7d6602cb037a529cb659b06b62258387 100644
--- a/NifImport/ImportAnimation.cpp
+++ b/NifImport/ImportAnimation.cpp
@@ -48,6 +48,7 @@ struct AnimationImport
    bool AddValues(vector<NiObjectNETRef>& nodes);
 
    bool AddValues(Control *c, NiKeyframeDataRef data, float time);
+   bool AddBiped(Control *c, NiKeyframeDataRef data, float time);
 
    Control* MakePosition(Control *tmCont, Class_ID clsid);
    Control* MakePositionXYZ(Control *tmCont, Class_ID clsid);
@@ -99,13 +100,27 @@ static void ClearAnimation(Control *c)
       if (IKeyControl *ikeys = GetKeyControlInterface(c)){
          ikeys->SetNumKeys(0);
       }
-      ClearAnimation(c->GetWController());
-      ClearAnimation(c->GetXController());
-      ClearAnimation(c->GetYController());
-      ClearAnimation(c->GetZController());
-      ClearAnimation(c->GetRotationController());
-      ClearAnimation(c->GetPositionController());
-      ClearAnimation(c->GetScaleController());
+      if (Control *sc = c->GetWController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
+      if (Control *sc = c->GetXController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
+      if (Control *sc = c->GetYController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
+      if (Control *sc = c->GetZController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
+      if (Control *sc = c->GetRotationController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
+      if (Control *sc = c->GetPositionController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
+      if (Control *sc = c->GetScaleController()) { 
+         if (sc != c) ClearAnimation(sc); 
+      }
    }
 }
 
@@ -158,6 +173,8 @@ bool KFMImporter::ImportAnimation()
          if (NULL == c)
             continue;
 
+         INode *n = gi->GetINodeByName(name.c_str());
+
          float start = cntr->GetStartTime();
          float stop = cntr->GetStopTime();
          float total = (stop - start);
@@ -165,7 +182,7 @@ bool KFMImporter::ImportAnimation()
          NiKeyframeDataRef data;
          Point3 p; Quat q; float s;
          if (ai.GetTransformData(*lnk, name, data, p, q, s)) {
-            PosRotScaleNode(c, p, q, s, prsDefault, 0);
+            PosRotScaleNode(n, p, q, s, prsDefault, 0);
             if (ai.AddValues(c, data, time)) {
                minTime = min(minTime, start);
                maxTime = max(maxTime, stop);
@@ -261,14 +278,6 @@ Control *AnimationImport::GetTMController(const string& name)
    if (NULL == c)
       return NULL;
 
-#ifdef USE_BIPED
-   // ignore bipeds for now.
-   if ( (c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) 
-      ||(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) 
-      ||(c->ClassID() == FOOTPRINT_CLASS_ID))
-      return NULL;
-#endif
-
    return c;
 }
 
@@ -325,6 +334,16 @@ bool AnimationImport::AddValues(NiObjectNETRef nref)
 
 bool AnimationImport::AddValues(Control *c, NiKeyframeDataRef data, float time)
 {
+#ifdef USE_BIPED
+   // Bipeds are special.  And will crash if you dont treat them with care
+   if ( (c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) 
+      ||(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) 
+      ||(c->ClassID() == FOOTPRINT_CLASS_ID))
+   {
+      return AddBiped(c, data, time);
+   }
+#endif
+
    vector<Vector3Key> posKeys = data->GetTranslateKeys();
    vector<QuatKey> quatKeys = data->GetQuatRotateKeys();
    vector<FloatKey> sclKeys = data->GetScaleKeys();
@@ -524,3 +543,11 @@ Control* AnimationImport::MakePositionXYZ(Control *tmCont, Class_ID clsid)
    }
    return NULL;
 }
+
+
+#ifdef USE_BIPED
+bool AnimationImport::AddBiped(Control *c, NiKeyframeDataRef data, float time)
+{
+   return false;
+}
+#endif
\ No newline at end of file
diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp
index 7fd252017a592d69086c18459edd286e5fd037b7..e6c7df6c0e1d32cc03ca93885087f8d3862befef 100644
--- a/NifImport/ImportSkeleton.cpp
+++ b/NifImport/ImportSkeleton.cpp
@@ -521,6 +521,22 @@ INode *NifImporter::CreateHelper(const string& name, Point3 startPos)
    return  NULL;
 }
 
+INode *NifImporter::CreateCamera(const string& name)
+{
+   if (GenCamera *ob = (GenCamera *)gi->CreateInstance(CAMERA_CLASS_ID, Class_ID(SIMPLE_CAM_CLASS_ID,0))) {
+      ob->Enable(1);
+      ob->NewCamera(0);
+      ob->SetFOV(0, TORAD(75.0f));
+      if (INode *n = gi->CreateObjectNode(ob)) {
+         n->Hide(TRUE);
+         n->SetName(const_cast<TCHAR*>(name.c_str()));
+         n->BoneAsLine(1);
+         return n;
+      }
+   }
+   return NULL;
+}
+
 void NifImporter::ImportBones(vector<NiNodeRef>& bones)
 {
    for (vector<NiNodeRef>::iterator itr = bones.begin(), end = bones.end(); itr != end; ++itr){
@@ -621,7 +637,12 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse)
                      || (!dummyNodeMatches.empty() && wildmatch(dummyNodeMatches, name))
                      || (convertBillboardsToDummyNodes && node->IsDerivedType(NiBillboardNode::TypeConst()))
                       );
-         if (isDummy && createNubsForBones)
+         if (wildmatch("Camera*", name)) {
+            if (bone = CreateCamera(name)) {
+               PosRotScaleNode(bone, p, q, scale, prs);
+               bone->Hide(node->GetHidden() ? TRUE : FALSE);
+            }
+         }else if (isDummy && createNubsForBones)
             bone = CreateHelper(name, p);
          else if (bone = CreateBone(name, p, pp, zAxis))
          {
diff --git a/NifImport/MaxNifImport.rc b/NifImport/MaxNifImport.rc
index 41eb813649dece069041b4f3ad72728ac68d579b..0930a5bce1e0b8f434f8d9e0f935fc0a9fdbed6d 100644
--- a/NifImport/MaxNifImport.rc
+++ b/NifImport/MaxNifImport.rc
@@ -109,8 +109,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,2,0
- PRODUCTVERSION 0,2,2,0
+ FILEVERSION 0,2,3,0
+ PRODUCTVERSION 0,2,3,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -126,12 +126,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Importer"
-            VALUE "FileVersion", "0, 2, 2, 0"
+            VALUE "FileVersion", "0, 2, 3, 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, 2, 0"
+            VALUE "ProductVersion", "0, 2, 3, 0"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/NifImport/NIFImporter.h b/NifImport/NIFImporter.h
index 1d1bb84a626973a6cfb8e5bf60c71a79360d5c61..5f864741a3dce7cdbe49c5440f6d076124463cad 100644
--- a/NifImport/NIFImporter.h
+++ b/NifImport/NIFImporter.h
@@ -108,6 +108,7 @@ public:
    Texmap* CreateTexture(Niflib::TexDesc& desc);
    INode *CreateBone(const string& name, Point3 startPos, Point3 endPos, Point3 zAxis);
    INode *CreateHelper(const string& name, Point3 startPos);
+   INode *CreateCamera(const string& name);
 
    // Primary Collision entry point.  Tests for bhk objects
    bool ImportCollision(Niflib::NiNodeRef node);
diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc
index a31d730a74ddac09c8232045a6922339fe359318..a070ca4e46c5465c23f6c4656e710f9099771d4c 100755
--- a/NifProps/NifProps.rc
+++ b/NifProps/NifProps.rc
@@ -342,8 +342,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,2,2,0
- PRODUCTVERSION 0,2,2,0
+ FILEVERSION 0,2,3,0
+ PRODUCTVERSION 0,2,3,0
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -359,12 +359,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "3ds Max Nif Reactor Properites Plugin"
-            VALUE "FileVersion", "0, 2, 2, 0"
+            VALUE "FileVersion", "0, 2, 3, 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, 2, 0"
+            VALUE "ProductVersion", "0, 2, 3, 0"
         END
     END
     BLOCK "VarFileInfo"