diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index 856696c2428520383e64705d54e05d18fcd002e8..8e3c6a231b616a45954aa84b66457c5e2c2e19bb 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -21,10 +21,10 @@
 bl_info = {
     "name": "Autodesk FBX format",
     "author": "Campbell Barton",
-    "blender": (2, 5, 7),
-    "api": 35622,
+    "blender": (2, 5, 8),
+    "api": 38691,
     "location": "File > Import-Export",
-    "description": "Import-Export FBX meshes, UV's, vertex colors, materials, textures, cameras and lamps",
+    "description": "Export FBX meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
     "warning": "",
     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
         "Scripts/Import-Export/Autodesk_FBX",
@@ -62,8 +62,8 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
     # to the class instance from the operator settings before calling.
 
     use_selection = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=False)
-# 	EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
-    global_scale = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
+    # XNA does not support scaled armatures (JCB)
+    global_scale = FloatProperty(name="Scale", description="Scale all data. Some importers do not support scaled armatures!", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
 
     axis_forward = EnumProperty(
             name="Forward",
@@ -71,7 +71,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
                    ('Y', "Y Forward", ""),
                    ('Z', "Z Forward", ""),
                    ('-X', "-X Forward", ""),
-                   ('-Y', "-Y Forward", ""),
+                   ('-Y', "-Y Forward (Blender)", ""),
                    ('-Z', "-Z Forward", ""),
                    ),
             default='-Z',
@@ -81,7 +81,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
             name="Up",
             items=(('X', "X Up", ""),
                    ('Y', "Y Up", ""),
-                   ('Z', "Z Up", ""),
+                   ('Z', "Z Up (Blender)", ""),
                    ('-X', "-X Up", ""),
                    ('-Y', "-Y Up", ""),
                    ('-Z', "-Z Up", ""),
@@ -112,13 +112,21 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
             default='FACE',
             )
 
+    # XNA does not use the edge information (JCB)
+    use_edges = BoolProperty(name="Include Edges", description="Edges may not be necessary and can cause errors with some importers!", default=False)
 #    EXP_MESH_HQ_NORMALS = BoolProperty(name="HQ Normals", description="Generate high quality normals", default=True)
     # armature animation
-    ANIM_ENABLE = BoolProperty(name="Enable Animation", description="Export keyframe animation", default=True)
+    ANIM_ENABLE = BoolProperty(name="Include Animation", description="Export keyframe animation", default=True)
+    ANIM_ACTION_ALL = BoolProperty(name="All Actions", description="Export all actions for armatures or just the currently selected action", default=True)
     ANIM_OPTIMIZE = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True)
     ANIM_OPTIMIZE_PRECISSION = FloatProperty(name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0)
-# 	ANIM_ACTION_ALL = BoolProperty(name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True)
-    ANIM_ACTION_ALL = BoolProperty(name="All Actions", description="Use all actions for armatures, if false, use current action", default=False)
+    # XNA needs different names for each take having the first one always called Default_Take is unhelpful (JCB)
+    # XNA usually errors if the textures are not in the same folder as the FBX file (JCB)
+    # XNA - validation to avoid incompatible settings.  I will understand if this is not kept in the generic version. (JCB)
+    # It would be nice to have this for XNA, UDK, Unity and Sunburn if others could provide the details. (JCB)
+    xna_validate = BoolProperty(name="XNA Strict Options", description="Make sure options are compatible with Microsoft XNA", default=False)
+    # The armature rotation does not work for XNA and setting the global matrix to identity is not sufficient on its own (JCB)
+    use_rotate_workaround = BoolProperty(name="XNA Rotate Fix", description="Disable global rotation, for XNA compatibility", default=False)
 
     batch_mode = EnumProperty(
             name="Batch Mode",
@@ -133,23 +141,51 @@ class ExportFBX(bpy.types.Operator, ExportHelper):
 
     path_mode = path_reference_mode
 
+    # Validate that the options are compatible with XNA (JCB)
+    def _validate_xna_options(self):
+        if not self.xna_validate:
+            return False
+        changed = False
+        if not self.use_rotate_workaround:
+            changed = True
+            self.use_rotate_workaround = True
+        if self.global_scale != 1.0 or self.mesh_smooth_type != 'OFF':
+            changed = True
+            self.global_scale = 1.0
+            self.mesh_smooth_type = 'OFF'
+        if self.ANIM_OPTIMIZE or self.use_edges:
+            changed = True
+            self.ANIM_OPTIMIZE = False
+            self.use_edges = False
+        if self.object_types & {'CAMERA', 'LAMP', 'EMPTY'}:
+            changed = True
+            self.object_types -= {'CAMERA', 'LAMP', 'EMPTY'}
+        return changed
+
     @property
     def check_extension(self):
         return self.batch_mode == 'OFF'
 
     def check(self, context):
-        return axis_conversion_ensure(self, "axis_forward", "axis_up")
+        is_xna_change = self._validate_xna_options()
+        is_axis_change = axis_conversion_ensure(self, "axis_forward", "axis_up")
+        if is_xna_change or is_axis_change:
+            return True
+        else:
+            return False
 
     def execute(self, context):
         from mathutils import Matrix
         if not self.filepath:
             raise Exception("filepath not set")
 
+        # Armature rotation causes a mess in XNA there are also other changes in the main script to avoid rotation (JCB)
         global_matrix = Matrix()
         global_matrix[0][0] = global_matrix[1][1] = global_matrix[2][2] = self.global_scale
-        global_matrix = global_matrix * axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up).to_4x4()
+        if not self.use_rotate_workaround:
+            global_matrix = global_matrix * axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up).to_4x4()
 
-        keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "global_scale", "check_existing", "filter_glob"))
+        keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "global_scale", "check_existing", "filter_glob", "xna_validate"))
         keywords["global_matrix"] = global_matrix
 
         from . import export_fbx
diff --git a/io_scene_fbx/export_fbx.py b/io_scene_fbx/export_fbx.py
index 61c27059cc1145f46d2404c7ebcec570051f0eaf..ce64ebee6fea30eb613f2463369e5e6b6bc788e9 100644
--- a/io_scene_fbx/export_fbx.py
+++ b/io_scene_fbx/export_fbx.py
@@ -202,12 +202,20 @@ def save_single(operator, scene, filepath="",
         ANIM_ACTION_ALL=False,
         use_metadata=True,
         path_mode='AUTO',
+        use_edges=True,
+        use_rotate_workaround=False,
     ):
 
     import bpy_extras.io_utils
 
+    # Only used for camera and lamp rotations
     mtx_x90 = Matrix.Rotation(math.pi / 2.0, 3, 'X')
+    # Used for mesh and armature rotations
     mtx4_z90 = Matrix.Rotation(math.pi / 2.0, 4, 'Z')
+    # Rotation does not work for XNA animations.  I do not know why but they end up a mess! (JCB)
+    if use_rotate_workaround:
+        # Set rotation to Matrix Identity for XNA (JCB)
+        mtx4_z90.identity()
 
     if global_matrix is None:
         global_matrix = Matrix()
@@ -449,6 +457,11 @@ def save_single(operator, scene, filepath="",
             loc = tuple(loc)
             rot = tuple(rot.to_euler())  # quat -> euler
             scale = tuple(scale)
+                
+            # Essential for XNA to use the original matrix not rotated nor scaled (JCB)
+            if use_rotate_workaround:
+                matrix = ob.matrix_local
+            
         else:
             # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore
             #if ob and not matrix: matrix = ob.matrix_world * global_matrix
@@ -1010,12 +1023,12 @@ def save_single(operator, scene, filepath="",
                    )
 
     # matrixOnly is not used at the moment
-    def write_null(my_null=None, fbxName=None):
+    def write_null(my_null=None, fbxName=None, fbxType="Null", fbxTypeFlags="Null"):
         # ob can be null
         if not fbxName:
             fbxName = my_null.fbxName
 
-        file.write('\n\tModel: "Model::%s", "Null" {' % fbxName)
+        file.write('\n\tModel: "Model::%s", "%s" {' % (fbxName, fbxType))
         file.write('\n\t\tVersion: 232')
 
         if my_null:
@@ -1024,15 +1037,16 @@ def save_single(operator, scene, filepath="",
             poseMatrix = write_object_props()[3]
 
         pose_items.append((fbxName, poseMatrix))
+        
+        file.write('\n\t\t}'
+                   '\n\t\tMultiLayer: 0'
+                   '\n\t\tMultiTake: 1'
+                   '\n\t\tShading: Y'
+                   '\n\t\tCulling: "CullingOff"'
+                   )
 
-        file.write('''
-		}
-		MultiLayer: 0
-		MultiTake: 1
-		Shading: Y
-		Culling: "CullingOff"
-		TypeFlags: "Null"
-	}''')
+        file.write('\n\t\tTypeFlags: "%s"' % fbxTypeFlags)
+        file.write('\n\t}')
 
     # Material Settings
     if world:
@@ -1312,7 +1326,7 @@ def save_single(operator, scene, filepath="",
 
         # convert into lists once.
         me_vertices = me.vertices[:]
-        me_edges = me.edges[:]
+        me_edges = me.edges[:] if use_edges else ()
         me_faces = me.faces[:]
 
         poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3]
@@ -2059,13 +2073,31 @@ def save_single(operator, scene, filepath="",
 
     del tmp_obmapping
     # Finished finding groups we use
+    
+    # == WRITE OBJECTS TO THE FILE ==
+    # == From now on we are building the FBX file from the information collected above (JCB)
 
     materials = [(sane_matname(mat_tex_pair), mat_tex_pair) for mat_tex_pair in materials.keys()]
     textures = [(sane_texname(tex), tex) for tex in textures.keys()  if tex]
     materials.sort(key=lambda m: m[0])  # sort by name
     textures.sort(key=lambda m: m[0])
 
-    camera_count = 8
+    camera_count = 8 if 'CAMERA' in object_types else 0
+
+    # sanity checks
+    try:
+        assert(not (ob_meshes and ('MESH' not in object_types)))
+        assert(not (materials and ('MESH' not in object_types)))
+        assert(not (textures and ('MESH' not in object_types)))
+        assert(not (textures and ('MESH' not in object_types)))
+
+        assert(not (ob_lights and ('LAMP' not in object_types)))
+
+        assert(not (ob_cameras and ('CAMERA' not in object_types)))
+    except AssertionError:
+        import traceback
+        traceback.print_exc()
+
     file.write('''
 
 ; Object definitions
@@ -2137,8 +2169,7 @@ Definitions:  {
 	}''' % tmp)
     del tmp
 
-    # we could avoid writing this possibly but for now just write it
-
+    # Bind pose is essential for XNA if the 'MESH' is included (JCB)
     file.write('''
 	ObjectType: "Pose" {
 		Count: 1
@@ -2163,14 +2194,17 @@ Definitions:  {
 
 Objects:  {''')
 
-    # To comply with other FBX FILES
-    write_camera_switch()
+    if 'CAMERA' in object_types:
+        # To comply with other FBX FILES
+        write_camera_switch()
 
     for my_null in ob_null:
         write_null(my_null)
 
+    # XNA requires the armature to be a Limb (JCB)
+    # Note, 2.58 and previous wrote these as normal empties and it worked mostly (except for XNA)
     for my_arm in ob_arms:
-        write_null(my_arm)
+        write_null(my_arm, fbxType="Limb", fbxTypeFlags="Skeleton")
 
     for my_cam in ob_cameras:
         write_camera(my_cam)
@@ -2185,7 +2219,8 @@ Objects:  {''')
     for my_bone in ob_bones:
         write_bone(my_bone)
 
-    write_camera_default()
+    if 'CAMERA' in object_types:
+        write_camera_default()
 
     for matname, (mat, tex) in materials:
         write_material(matname, mat)  # We only need to have a material per image pair, but no need to write any image info into the material (dumb fbx standard)
@@ -2220,9 +2255,10 @@ Objects:  {''')
                 if me in iter(my_bone.blenMeshes.values()):
                     write_sub_deformer_skin(my_mesh, my_bone, weights)
 
-    # Write pose's really weird, only needed when an armature and mesh are used together
-    # each by themselves dont need pose data. for now only pose meshes and bones
+    # Write pose is really weird, only needed when an armature and mesh are used together
+    # each by themselves do not need pose data. For now only pose meshes and bones
 
+    # Bind pose is essential for XNA if the 'MESH' is included (JCB)
     file.write('''
 	Pose: "Pose::BIND_POSES", "BindPose" {
 		Type: "BindPose"
@@ -2265,11 +2301,15 @@ Objects:  {''')
 
 Relations:  {''')
 
+    # Nulls are likely to cause problems for XNA
+
     for my_null in ob_null:
         file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_null.fbxName)
 
+    # Armature must be a Limb for XNA
+    # Note, 2.58 and previous wrote these as normal empties and it worked mostly (except for XNA)
     for my_arm in ob_arms:
-        file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_arm.fbxName)
+        file.write('\n\tModel: "Model::%s", "Limb" {\n\t}' % my_arm.fbxName)
 
     for my_mesh in ob_meshes:
         file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % my_mesh.fbxName)
@@ -2337,7 +2377,7 @@ Relations:  {''')
 
 Connections:  {''')
 
-    # NOTE - The FBX SDK dosnt care about the order but some importers DO!
+    # NOTE - The FBX SDK does not care about the order but some importers DO!
     # for instance, defining the material->mesh connection
     # before the mesh->parent crashes cinema4d
 
@@ -2369,20 +2409,19 @@ Connections:  {''')
         for texname, tex in textures:
             file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname))
 
-    for my_mesh in ob_meshes:
-        if my_mesh.fbxArm:
-            file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName))
+    if 'MESH' in object_types:
+        for my_mesh in ob_meshes:
+            if my_mesh.fbxArm:
+                file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName))
 
-    #for bonename, bone, obname, me, armob in ob_bones:
-    for my_bone in ob_bones:
-        for fbxMeshObName in my_bone.blenMeshes:  # .keys()
-            file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName))
+        for my_bone in ob_bones:
+            for fbxMeshObName in my_bone.blenMeshes:  # .keys()
+                file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName))
 
-    # limbs -> deformers
-    # for bonename, bone, obname, me, armob in ob_bones:
-    for my_bone in ob_bones:
-        for fbxMeshObName in my_bone.blenMeshes:  # .keys()
-            file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName))
+        # limbs -> deformers
+        for my_bone in ob_bones:
+            for fbxMeshObName in my_bone.blenMeshes:  # .keys()
+                file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName))
 
     #for bonename, bone, obname, me, armob in ob_bones:
     for my_bone in ob_bones:
@@ -2400,8 +2439,10 @@ Connections:  {''')
                 for fbxGroupName in ob_base.fbxGroupNames:
                     file.write('\n\tConnect: "OO", "Model::%s", "GroupSelection::%s"' % (ob_base.fbxName, fbxGroupName))
 
-    for my_arm in ob_arms:
-        file.write('\n\tConnect: "OO", "Model::%s", "Model::Scene"' % my_arm.fbxName)
+
+    # I think the following always duplicates the armature connection because it is also in ob_all_typegroups above! (JCB)
+    # for my_arm in ob_arms:
+    #     file.write('\n\tConnect: "OO", "Model::%s", "Model::Scene"' % my_arm.fbxName)
 
     file.write('\n}')
 
@@ -2864,24 +2905,29 @@ def save(operator, context,
 
         return {'FINISHED'}  # so the script wont run after we have batch exported.
 
-
-
-
+# APPLICATION REQUIREMENTS
+# Please update the lists for UDK, Unity, XNA etc. on the following web page:
+#   http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Import-Export/UnifiedFBX
+
+# XNA FBX Requirements (JCB 29 July 2011)
+# - Armature must be parented to the scene
+# - Armature must be a 'Limb' never a 'null'.  This is in several places.
+# - First bone must be parented to the armature.
+# - Rotation must be completely disabled including
+#       always returning the original matrix in In object_tx().
+#       It is the animation that gets distorted during rotation!
+# - Lone edges cause intermittent errors in the XNA content pipeline!
+#       I have added a warning message and excluded them.
+# - Bind pose must be included with the 'MESH'
+# Typical settings for XNA export
+#   No Cameras, No Lamps, No Edges, No face smoothing, No Default_Take, Armature as bone, Disable rotation
+
+# NOTE TO Campbell - 
+#   Can any or all of the following notes be removed because some have been here for a long time? (JCB 27 July 2011)
 # NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
-# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print
 # - get rid of bpy.path.clean_name somehow
-# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565
 # + get rid of BPyObject_getObjectArmature, move it in RNA?
-# - BATCH_ENABLE and BATCH_GROUP options: line 327
 # - implement all BPyMesh_* used here with RNA
 # - getDerivedObjects is not fully replicated with .dupli* funcs
-# - talk to Campbell, this code won't work? lines 1867-1875
 # - don't know what those colbits are, do we need them? they're said to be deprecated in DNA_object_types.h: 1886-1893
 # - no hq normals: 1900-1901
-
-# TODO
-
-# - bpy.data.remove_scene: line 366
-# - bpy.sys.time move to bpy.sys.util?
-# - new scene creation, activation: lines 327-342, 368
-# - uses bpy.path.abspath, *.relpath - replace at least relpath