static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary<int, List<string>> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) {
			var animation = skeletonData.FindAnimation(name);

			var timelines = animation.Timelines;

			if (clip == null) {
				clip = new AnimationClip();
			} else {
				clip.ClearCurves();
				AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]);
			}

			clip.name = name;

			Skeleton skeleton = new Skeleton(skeletonData);

			List<int> ignoreRotateTimelineIndexes = new List<int>();

			if (bakeIK) {
				foreach (IkConstraint i in skeleton.IkConstraints) {
					foreach (Bone b in i.Bones) {
						int index = skeleton.FindBoneIndex(b.Data.Name);
						ignoreRotateTimelineIndexes.Add(index);
						BakeBoneConstraints(b, animation, clip);
					}
				}
			}

			foreach (Bone b in skeleton.Bones) {
				if (!b.Data.TransformMode.InheritsRotation()) {
					int index = skeleton.FindBoneIndex(b.Data.Name);

					if (ignoreRotateTimelineIndexes.Contains(index) == false) {
						ignoreRotateTimelineIndexes.Add(index);
						BakeBoneConstraints(b, animation, clip);
					}
				}
			}

			foreach (Timeline t in timelines) {
				skeleton.SetToSetupPose();

				if (t is ScaleTimeline) {
					ParseScaleTimeline(skeleton, (ScaleTimeline)t, clip);
				} else if (t is TranslateTimeline) {
					ParseTranslateTimeline(skeleton, (TranslateTimeline)t, clip);
				} else if (t is RotateTimeline) {
					//bypass any rotation keys if they're going to get baked anyway to prevent localEulerAngles vs Baked collision
					if (ignoreRotateTimelineIndexes.Contains(((RotateTimeline)t).BoneIndex) == false)
						ParseRotateTimeline(skeleton, (RotateTimeline)t, clip);
				} else if (t is AttachmentTimeline) {
					ParseAttachmentTimeline(skeleton, (AttachmentTimeline)t, slotLookup, clip);
				} else if (t is EventTimeline) {
					ParseEventTimeline((EventTimeline)t, clip, eventOptions);
				}

			}

			var settings = AnimationUtility.GetAnimationClipSettings(clip);
			settings.loopTime = true;
			settings.stopTime = Mathf.Max(clip.length, 0.001f);

			SetAnimationSettings(clip, settings);

			clip.EnsureQuaternionContinuity();

			EditorUtility.SetDirty(clip);

			return clip;
		}