Index: core/com/jme3/animation/AnimChannel.java
===================================================================
--- core/com/jme3/animation/AnimChannel.java	(revision 7846)
+++ core/com/jme3/animation/AnimChannel.java	(working copy)
@@ -208,7 +208,7 @@
         if (blendTime < 0f)
             throw new IllegalArgumentException("blendTime cannot be less than zero");
 
-        BoneAnimation anim = control.animationMap.get(name);
+        BoneAnimation anim = control.getAnim(name);
         if (anim == null)
             throw new IllegalArgumentException("Cannot find animation named: '"+name+"'");
 
Index: core/com/jme3/animation/AnimControl.java
===================================================================
--- core/com/jme3/animation/AnimControl.java	(revision 7846)
+++ core/com/jme3/animation/AnimControl.java	(working copy)
@@ -79,9 +79,9 @@
     private SkeletonControl skeletonControl;
 
     /**
-     * List of animations
+     * An Animationprovider
      */
-    HashMap<String, BoneAnimation> animationMap;
+    private AnimationProvider animationProvider = new HashMapAnimationProvider();
 
     /**
      * Animation channels
@@ -113,6 +113,10 @@
      */
     public AnimControl() {
     }
+    
+    public void setAnimationProvider(AnimationProvider pro){
+    	this.animationProvider = pro;
+    }
 
     /**
      * Internal use only.
@@ -137,7 +141,7 @@
      * with the skeleton given in the constructor.
      */
     public void setAnimations(HashMap<String, BoneAnimation> animations) {
-        animationMap = animations;
+    	animationProvider.setAnimations(animations);
     }
 
     /**
@@ -147,7 +151,7 @@
      * such named animation exists.
      */
     public BoneAnimation getAnim(String name) {
-        return animationMap.get(name);
+        return animationProvider.getAnimation(name, this);
     }
 
     /**
@@ -156,7 +160,7 @@
      * @param anim The animation to add.
      */
     public void addAnim(BoneAnimation anim) {
-        animationMap.put(anim.getName(), anim);
+       animationProvider.addAnimation(anim);
     }
 
     /**
@@ -164,12 +168,7 @@
      * @param anim The animation to remove.
      */
     public void removeAnim(BoneAnimation anim) {
-        if (!animationMap.containsKey(anim.getName())) {
-            throw new IllegalArgumentException("Given animation does not exist "
-                    + "in this AnimControl");
-        }
-
-        animationMap.remove(anim.getName());
+        animationProvider.removeAnimation(anim.getName());
     }
 
     /**
@@ -296,7 +295,7 @@
      * can play.
      */
     public Collection<String> getAnimationNames() {
-        return animationMap.keySet();
+        return animationProvider.getAnimationNames();
     }
 
     /**
@@ -305,13 +304,7 @@
      * @return The length of time, in seconds, of the named animation.
      */
     public float getAnimationLength(String name) {
-        BoneAnimation a = animationMap.get(name);
-        if (a == null) {
-            throw new IllegalArgumentException("The animation " + name
-                    + " does not exist in this AnimControl");
-        }
-
-        return a.getLength();
+        return animationProvider.getAnimationLength(name);
     }
     
     /**
@@ -340,7 +333,7 @@
         super.write(ex);
         OutputCapsule oc = ex.getCapsule(this);
         oc.write(skeleton, "skeleton", null);
-        oc.writeStringSavableMap(animationMap, "animations", null);
+        oc.write(animationProvider, "animationProvider", null);
     }
 
     @Override
@@ -348,7 +341,7 @@
         super.read(im);
         InputCapsule in = im.getCapsule(this);
         skeleton = (Skeleton) in.readSavable("skeleton", null);
-        animationMap = (HashMap<String, BoneAnimation>) in.readStringSavableMap("animations", null);
+        animationProvider = (AnimationProvider) in.readSavable("animationProvider", null);
 
         if (im.getFormatVersion() == 0){
             //changed for backward compatibility with j3o files generated before the AnimControl/SkeletonControl split
Index: core/com/jme3/animation/AnimationProvider.java
===================================================================
--- core/com/jme3/animation/AnimationProvider.java	(revision 0)
+++ core/com/jme3/animation/AnimationProvider.java	(revision 0)
@@ -0,0 +1,32 @@
+package com.jme3.animation;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.Savable;
+
+public abstract class AnimationProvider implements Savable {
+
+	public AnimationProvider() {
+	}
+
+	public abstract void setAnimations(HashMap<String, BoneAnimation> animations);
+
+	public abstract BoneAnimation getAnimation(String name, AnimControl animControl);
+	
+	public abstract float getAnimationLength(String name);
+
+	public abstract void removeAnimation(String name);
+
+	public abstract void addAnimation(BoneAnimation anim);
+
+	public abstract Collection<String> getAnimationNames();
+
+	public abstract void write(JmeExporter ex) throws IOException;
+	
+	public abstract void read(JmeImporter im) throws IOException;
+
+}
\ No newline at end of file
Index: core/com/jme3/animation/Bone.java
===================================================================
--- core/com/jme3/animation/Bone.java	(revision 7692)
+++ core/com/jme3/animation/Bone.java	(working copy)
@@ -493,7 +493,7 @@
      * Used internally after model cloning.
      * @param attachNode
      */
-    void setAttachmentsNode(Node attachNode) {
+    public void setAttachmentsNode(Node attachNode) {
         this.attachNode = attachNode;
     }
 
Index: core/com/jme3/animation/BoneAnimation.java
===================================================================
--- core/com/jme3/animation/BoneAnimation.java	(revision 7846)
+++ core/com/jme3/animation/BoneAnimation.java	(working copy)
@@ -177,4 +177,22 @@
             System.arraycopy(sav, 0, tracks, 0, sav.length);
         }
     }
+    
+    /**
+     * BoneTracks without a bone index but a bone name can be
+     * bound to the specified bone index. This can be used for
+     * loading animation tracks only and being able to play them
+     * on any bone or any skeleton, as long as the bone name does
+     * match
+     */
+    public void rewireBoneTracks(Skeleton skeleton) {
+		if(tracks != null){
+			for(BoneTrack tr : tracks){
+				if(tr.getTargetBoneIndex() < 0)
+					tr.setTargetBoneIndex(skeleton.getBoneIndex(tr.getTargetBoneName()));
+				else
+					return;
+			}
+		}
+	}
 }
Index: core/com/jme3/animation/BoneTrack.java
===================================================================
--- core/com/jme3/animation/BoneTrack.java	(revision 7846)
+++ core/com/jme3/animation/BoneTrack.java	(working copy)
@@ -50,7 +50,11 @@
     /**
      * Bone index in the skeleton which this track effects.
      */
-    private int targetBoneIndex;
+    private int targetBoneIndex = -1;
+    /**
+     * Bone name in the skeleton which this track affects.
+     */
+    private String targetBoneName;
     /**
      * Transforms and times for track.
      */
@@ -105,11 +109,26 @@
         this.targetBoneIndex = targetBoneIndex;
     }
 
+    public BoneTrack(String boneName) {
+		this.targetBoneName = boneName;
+	}
+    
+    /**
+     * @return Target bone for this bonetrack
+     */
+    public String getTargetBoneName() {
+		return targetBoneName;
+	}
+    	
+	public void setTargetBoneIndex(int index) {
+        targetBoneIndex = index;
+    }
+
     /**
      * returns the bone index of this bone track
      * @return 
      */
-    public int getTargetBoneIndex() {
+	public int getTargetBoneIndex() {
         return targetBoneIndex;
     }
 
@@ -248,7 +267,8 @@
     @Override
     public void write(JmeExporter ex) throws IOException {
         OutputCapsule oc = ex.getCapsule(this);
-        oc.write(targetBoneIndex, "boneIndex", 0);
+        oc.write(targetBoneIndex, "boneIndex", -1);
+        oc.write(targetBoneName, "boneName", null);
         oc.write(translations, "translations", null);
         oc.write(rotations, "rotations", null);
         oc.write(times, "times", null);
@@ -258,7 +278,8 @@
     @Override
     public void read(JmeImporter im) throws IOException {
         InputCapsule ic = im.getCapsule(this);
-        targetBoneIndex = ic.readInt("boneIndex", 0);
+        targetBoneIndex = ic.readInt("boneIndex", -1);
+        targetBoneName = ic.readString("boneName", null);
 
         translations = (CompactVector3Array) ic.readSavable("translations", null);
 
Index: core/com/jme3/animation/HashMapAnimationProvider.java
===================================================================
--- core/com/jme3/animation/HashMapAnimationProvider.java	(revision 0)
+++ core/com/jme3/animation/HashMapAnimationProvider.java	(revision 0)
@@ -0,0 +1,86 @@
+package com.jme3.animation;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+
+/**
+ * An AnimationProvider based on a hasmap of animations
+ * 
+ */
+public class HashMapAnimationProvider extends AnimationProvider {
+
+	/**
+	 * List of animations
+	 */
+	protected HashMap<String, BoneAnimation> animationMap = new HashMap<String, BoneAnimation>();
+
+	/**
+	 * Sets the animations to the provided map of animation names to boneanimations
+	 */
+	public void setAnimations(HashMap<String, BoneAnimation> animations) {
+		this.animationMap = animations;
+	}
+
+	/**
+	 * Returns the boneanimation requested by name or null if the animation does not exist
+	 */
+	public BoneAnimation getAnimation(String name, AnimControl control) {
+		return this.animationMap.get(name);
+	}
+
+	/**
+	 * Removes the specified animation specified by name or throws an IllegalStateException if the animation does not exisit in this provider
+	 */
+	public void removeAnimation(String name) {
+		if (!animationMap.containsKey(name)) {
+			throw new IllegalArgumentException(
+					"Given animation does not exist " + "in this AnimControl");
+		}
+
+		animationMap.remove(name);
+	}
+
+	/**
+	 * Adds an animation to the hash map
+	 */
+	public void addAnimation(BoneAnimation anim) {
+		animationMap.put(anim.getName(), anim);
+	}
+
+	/**
+	 * Returns a collection of the currently present animationnames
+	 */
+	public Collection<String> getAnimationNames() {
+		return animationMap.keySet();
+	}
+
+	/**
+	 * Returns the length of the given animation identified by name or throws an IllegalStateException if that animation is not present
+	 */
+	public float getAnimationLength(String name) {
+		BoneAnimation a = animationMap.get(name);
+		if (a == null) {
+			throw new IllegalArgumentException("The animation " + name
+					+ " does not exist in this AnimControl");
+		}
+
+		return a.getLength();
+	}
+
+	public void write(JmeExporter ex) throws IOException {
+		OutputCapsule oc = ex.getCapsule(this);
+		oc.writeStringSavableMap(animationMap, "animations", null);
+	}
+
+	public void read(JmeImporter im) throws IOException {
+		InputCapsule in = im.getCapsule(this);
+		animationMap = (HashMap<String, BoneAnimation>) in
+				.readStringSavableMap("animations", null);
+	}
+}
Index: core/com/jme3/asset/AssetConfig.java
===================================================================
--- core/com/jme3/asset/AssetConfig.java	(revision 7554)
+++ core/com/jme3/asset/AssetConfig.java	(working copy)
@@ -76,6 +76,8 @@
                 String rootPath = scan.next();
                 String locatorClass = scan.nextLine().trim();
                 manager.registerLocator(rootPath, locatorClass);
+            }else if (cmd.startsWith("#")){
+            	scan.nextLine();
             }else{
                 throw new IOException("Expected command, got '"+cmd+"'");
             }
Index: desktop/com/jme3/asset/Desktop.cfg
===================================================================
--- desktop/com/jme3/asset/Desktop.cfg	(revision 7805)
+++ desktop/com/jme3/asset/Desktop.cfg	(working copy)
@@ -16,6 +16,7 @@
 LOADER com.jme3.scene.plugins.MTLLoader : mtl
 LOADER com.jme3.scene.plugins.ogre.MeshLoader : meshxml, mesh.xml
 LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : skeletonxml, skeleton.xml
+LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : anim.xml
 LOADER com.jme3.scene.plugins.ogre.MaterialLoader : material
 LOADER com.jme3.scene.plugins.ogre.SceneLoader : scene
 LOADER com.jme3.scene.plugins.blender.BlenderModelLoader : blend
Index: ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
===================================================================
--- ogre/com/jme3/scene/plugins/ogre/MeshLoader.java	(revision 7847)
+++ ogre/com/jme3/scene/plugins/ogre/MeshLoader.java	(working copy)
@@ -31,7 +31,34 @@
  */
 package com.jme3.scene.plugins.ogre;
 
-import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey;
+import static com.jme3.util.xml.SAXUtil.parseBool;
+import static com.jme3.util.xml.SAXUtil.parseFloat;
+import static com.jme3.util.xml.SAXUtil.parseInt;
+import static com.jme3.util.xml.SAXUtil.parseString;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
 import com.jme3.animation.AnimControl;
 import com.jme3.animation.BoneAnimation;
 import com.jme3.animation.SkeletonControl;
@@ -52,34 +79,10 @@
 import com.jme3.scene.VertexBuffer.Format;
 import com.jme3.scene.VertexBuffer.Type;
 import com.jme3.scene.VertexBuffer.Usage;
-import com.jme3.system.JmeSystem;
+import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.IntMap;
 import com.jme3.util.IntMap.Entry;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-import static com.jme3.util.xml.SAXUtil.*;
 
 /**
  * Loads Ogre3D mesh.xml files.
@@ -214,8 +217,20 @@
                 mat = materialList.get(matName);
             }
             if (mat == null) {
+                Object o = assetManager.loadAsset(matName+".material");
+                if(o instanceof MaterialList){
+                	if(materialList != null)
+                		materialList.putAll((Map<? extends String, ? extends Material>) o);
+                	else {
+                		materialList = new MaterialList();
+                		materialList.putAll((Map<? extends String, ? extends Material>) o);
+                	}
+                	mat = materialList.get(matName);
+                }
+                else {
                 logger.log(Level.WARNING, "Material {0} not found. Applying default material", matName);
                 mat = (Material) assetManager.loadAsset(new AssetKey("Common/Materials/RedColor.j3m"));
+                }
             }
         }
 
@@ -251,16 +266,16 @@
         }
 
         if (meshName == null) {
-            geom = new Geometry("OgreSubmesh-" + (++meshIndex), mesh);
+            geom = new Geometry("OgreSubmesh");// + (++geomIdx), mesh);
         } else {
-            geom = new Geometry(meshName + "-geom-" + (++meshIndex), mesh);
+            geom = new Geometry(meshName, mesh);// + "-geom-" + (++geomIdx), mesh);
         }
-        
+
         if (usesSharedVerts){
             // this mesh is shared!
             geom.setUserData(UserData.JME_SHAREDMESH, sharedMesh);
         }
-
+        
         applyMaterial(geom, matName);
         geoms.add(geom);
     }
@@ -692,7 +707,7 @@
     }
 
     private Node compileModel() {
-        Node model = new Node(meshName + "-ogremesh");
+        Node model = new Node(meshName);// + "-ogremesh");
         
         for (int i = 0; i < geoms.size(); i++) {
             Geometry g = geoms.get(i);
@@ -781,6 +796,11 @@
             if (folderName != null && folderName.length() > 0) {
                 meshName = meshName.substring(folderName.length());
             }
+            //Hack for Windows names not properly done in AssetKey
+            int last = meshName.lastIndexOf("\\");
+            if(last != -1)
+            	meshName = (meshName.substring(last+1));
+            
             assetManager = info.getManager();
 
             OgreMeshKey meshKey = null;
Index: ogre/com/jme3/scene/plugins/ogre/SkeletonLoader.java
===================================================================
--- ogre/com/jme3/scene/plugins/ogre/SkeletonLoader.java	(revision 7847)
+++ ogre/com/jme3/scene/plugins/ogre/SkeletonLoader.java	(working copy)
@@ -107,8 +107,11 @@
             assert elementStack.peek().equals("tracks");
             String boneName = SAXUtil.parseString(attribs.getValue("bone"));
             Bone bone = nameToBone.get(boneName);
-            int index = skeleton.getBoneIndex(bone);
-            track = new BoneTrack(index);
+            if(skeleton != null){
+	            int index = skeleton.getBoneIndex(bone);
+	            track = new BoneTrack(index);
+            }else
+            	track = new BoneTrack(boneName);
         } else if (qName.equals("boneparent")) {
             assert elementStack.peek().equals("bonehierarchy");
             String boneName = attribs.getValue("bone");
@@ -131,7 +134,8 @@
             assert elementStack.peek().equals("animations");
             String name = SAXUtil.parseString(attribs.getValue("name"));
             float length = SAXUtil.parseFloat(attribs.getValue("length"));
-            animation = new BoneAnimation(name, length);
+            //TR HACK, otherwise names in anim and boneanim do not match, FIX YOUR ASSETS and remove this !
+            animation = new BoneAnimation(name.toLowerCase(), length);
         } else if (qName.equals("bonehierarchy")) {
             assert elementStack.peek().equals("skeleton");
         } else if (qName.equals("animations")) {
@@ -171,6 +175,8 @@
             indexToBone.clear();
             skeleton = new Skeleton(bones);
         } else if (qName.equals("animation")) {
+        	if(animations == null)
+        		animations = new ArrayList<BoneAnimation>();
             animations.add(animation);
             animation = null;
         } else if (qName.equals("track")) {
