public virtual void resolve(float x, float y, int chainLength, com.brashmonkey.spriter.objects.SpriterAbstractObject
			 effector)
        {
            float xx = effector.getX() + (float)System.Math.Cos(SpriterCalculator.DegreeToRadian(effector
                .getAngle())) * SpriterCalculator.BONE_LENGTH * effector
                .getScaleX();
            float yy = effector.getY() + (float)System.Math.Sin(SpriterCalculator.DegreeToRadian(effector
                .getAngle())) * SpriterCalculator.BONE_LENGTH * effector
                .getScaleX();
            effector.setAngle(com.brashmonkey.spriter.SpriterCalculator.angleBetween(effector
                .getX(), effector.getY(), x, y));
            if (this.player.getFlipX() == -1)
            {
                effector.setAngle(effector.getAngle() + 180f);
            }
            com.brashmonkey.spriter.objects.SpriterBone parent = null;
            if (effector.hasParent())
            {
                parent = player.getRuntimeBones()[effector.getParentId()];
                effector.copyValuesTo(temp);
                com.brashmonkey.spriter.SpriterCalculator.reTranslateRelative(parent, temp);
                if (effector is com.brashmonkey.spriter.objects.SpriterBone)
                {
                    temp.copyValuesTo(player.lastFrame.getBones()[effector.getId()]);
                }
                else
                {
                    temp.copyValuesTo(player.lastFrame.getObjects()[effector.getId()]);
                }
            }
            for (int i = 0; i < chainLength && parent != null; i++)
            {
                if (com.brashmonkey.spriter.SpriterCalculator.distanceBetween(xx, yy, x, y) <= 1)
                {
                    return;
                }
                parent.setAngle(parent.getAngle() + com.brashmonkey.spriter.SpriterCalculator.angleDifference
                    (com.brashmonkey.spriter.SpriterCalculator.angleBetween(parent.getX(), parent.getY
                    (), x, y), com.brashmonkey.spriter.SpriterCalculator.angleBetween(parent.getX(),
                    parent.getY(), xx, yy)));
                this.player.updateRecursively(parent);
                if (parent.hasParent())
                {
                    parent = player.getRuntimeBones()[parent.getParent().getId()];
                }
                else
                {
                    parent = null;
                }
                xx = effector.getX() + (float)System.Math.Cos(SpriterCalculator.DegreeToRadian(effector.getAngle
                    ())) * SpriterCalculator.BONE_LENGTH * effector.getScaleX
                    ();
                yy = effector.getY() + (float)System.Math.Sin(SpriterCalculator.DegreeToRadian(effector.getAngle
                    ())) * SpriterCalculator.BONE_LENGTH * effector.getScaleX
                    ();
            }
        }
        public virtual com.brashmonkey.spriter.animation.SpriterKeyFrame getNextFrameFor(
			com.brashmonkey.spriter.objects.SpriterAbstractObject @object, com.brashmonkey.spriter.animation.SpriterKeyFrame
			 currentFrame, int direction)
        {
            com.brashmonkey.spriter.animation.SpriterKeyFrame nextFrame = null;
            int cnt = 0;
            bool isBone = @object is com.brashmonkey.spriter.objects.SpriterBone;
            for (int j = (currentFrame.getId() + direction + this.numberOfFrames()) % this.numberOfFrames();
                nextFrame == null && cnt < this.numberOfFrames(); j = (j + direction + this.numberOfFrames()) %
                this.numberOfFrames(), cnt++)
            {
                com.brashmonkey.spriter.animation.SpriterKeyFrame frame = this.frames[j];
                bool contains = (isBone) ? frame.containsBone((com.brashmonkey.spriter.objects.SpriterBone
                    )@object) : frame.containsObject((com.brashmonkey.spriter.objects.SpriterObject)
                    @object);
                if (contains)
                {
                    com.brashmonkey.spriter.objects.SpriterAbstractObject objectInFrame;
                    if(isBone) objectInFrame = frame.getBoneFor((com.brashmonkey.spriter.objects.SpriterBone)@object);
                    else objectInFrame = frame.getObjectFor((com.brashmonkey.spriter.objects.SpriterObject)@object);
                    if (@object.equals(objectInFrame))
                    {
                        nextFrame = frame;
                    }
                }
            }
            return nextFrame;
        }
        //import com.brashmonkey.spriter.converters.SpriterObjectConverter;
        //import com.discobeard.spriter.dom.AnimationObject;
        //final private SpriterObjectConverter objectConverter = new SpriterObjectConverter();
        public virtual com.brashmonkey.spriter.animation.SpriterAnimation buildAnimation(
			com.discobeard.spriter.dom.Animation animation)
        {
            com.discobeard.spriter.dom.MainLine mainline = animation.getMainline();
            System.Collections.Generic.IList<com.discobeard.spriter.dom.TimeLine> timeLines =
                animation.getTimeline();
            System.Collections.Generic.IList<com.discobeard.spriter.dom.Key> keyFrames = mainline
                .getKey();
            bonesToTween = new System.Collections.Generic.Dictionary<com.brashmonkey.spriter.objects.SpriterBone
                , int>();
            objectsToTween = new System.Collections.Generic.Dictionary<com.brashmonkey.spriter.objects.SpriterObject
                , int>();
            com.brashmonkey.spriter.animation.SpriterAnimation spriterAnimation = new com.brashmonkey.spriter.animation.SpriterAnimation
                (animation.getId(), animation.getName(), animation.getLength());
            for (int k = 0; k < keyFrames.Count; k++)
            {
                com.discobeard.spriter.dom.Key mainlineKey = keyFrames[k];
                System.Collections.Generic.IList<com.brashmonkey.spriter.objects.SpriterObject> tempObjects
                     = new System.Collections.Generic.List<com.brashmonkey.spriter.objects.SpriterObject
                    >();
                System.Collections.Generic.IList<com.brashmonkey.spriter.objects.SpriterBone> tempBones
                     = new System.Collections.Generic.List<com.brashmonkey.spriter.objects.SpriterBone
                    >();
                com.brashmonkey.spriter.animation.SpriterKeyFrame frame = new com.brashmonkey.spriter.animation.SpriterKeyFrame
                    ();
                frame.setTime(mainlineKey.getTime());
                frame.setId(mainlineKey.getId());
                foreach (com.discobeard.spriter.dom.BoneRef boneRef in mainlineKey.getBoneRef())
                {
                    com.discobeard.spriter.dom.TimeLine timeline = timeLines[boneRef.getTimeline()];
                    com.discobeard.spriter.dom.Key timelineKey = timeline.getKey()[boneRef.getKey()];
                    com.brashmonkey.spriter.objects.SpriterBone bone = boneMerger.merge(boneRef, timelineKey
                        );
                    bone.setName(timeline.getName());
                    if (mainlineKey.getTime() != timelineKey.getTime())
                    {
                        bonesToTween.Add(bone, k);
                    }
                    else
                    {
                        tempBones.Add(bone);
                    }
                }
                //}
                foreach (com.discobeard.spriter.dom.AnimationObjectRef objectRef in mainlineKey.getObjectRef
                    ())
                {
                    com.discobeard.spriter.dom.TimeLine timeline = timeLines[objectRef.getTimeline()];
                    com.discobeard.spriter.dom.Key timelineKey = timeline.getKey()[objectRef.getKey()
                        ];
                    com.brashmonkey.spriter.objects.SpriterObject @object = objectMerger.merge(objectRef
                        , timelineKey);
                    @object.setName(timeline.getName());
                    if (mainlineKey.getTime() != timelineKey.getTime())
                    {
                        objectsToTween.Add(@object, k);
                    }
                    else
                    {
                        tempObjects.Add(@object);
                    }
                }
                //}
                frame.setObjects(Sharpen.Collections.ToArray(tempObjects, new com.brashmonkey.spriter.objects.SpriterObject
                    [tempObjects.Count]));
                frame.setBones(Sharpen.Collections.ToArray(tempBones, new com.brashmonkey.spriter.objects.SpriterBone
                    [tempBones.Count]));
                spriterAnimation.frames.Add(frame);
            }
            this.tweenBones(spriterAnimation);
            this.tweenObjects(spriterAnimation);
            return spriterAnimation;
        }
        private void tweenBone(com.brashmonkey.spriter.objects.SpriterBone currentBone, com.brashmonkey.spriter.objects.SpriterBone
			 nextBone, int i, long startTime, long endTime)
        {
            currentBone.copyValuesTo(this.tempBones[i]);
            this.tempBones[i].setTimeline((nextBone != null) ? currentBone.getTimeline() : -1
                );
            com.brashmonkey.spriter.objects.SpriterAbstractObject parent = (this.tempBones[i]
                .hasParent()) ? this.tempBones[this.tempBones[i].getParentId()] : this.tempParent;
            if (nextBone != null)
            {
                if (parent != this.tempParent)
                {
                    if (!currentBone.getParent().equals(nextBone.getParent()))
                    {
                        nextBone = (com.brashmonkey.spriter.objects.SpriterBone)this.getTimelineObject(currentBone
                            , this.tempBones2);
                        com.brashmonkey.spriter.SpriterCalculator.reTranslateRelative(parent, nextBone);
                        nextBone.setAngle(nextBone.getAngle() * this.flippedX * this.flippedY);
                    }
                }
                else
                {
                    if (nextBone.hasParent())
                    {
                        nextBone = (com.brashmonkey.spriter.objects.SpriterBone)this.getTimelineObject(currentBone
                            , this.tempBones2);
                        com.brashmonkey.spriter.SpriterCalculator.reTranslateRelative(parent, nextBone);
                        nextBone.setAngle(nextBone.getAngle() * this.flippedX * this.flippedY);
                    }
                }
                if (this.tempBones[i].tween)
                {
                    this.interpolateAbstractObject(this.tempBones[i], currentBone, nextBone, startTime
                        , endTime);
                }
            }
            this.moddedBones[currentBone.getId()].modSpriterBone(this.tempBones[i]);
            if (this.transitionFixed)
            {
                this.tempBones[i].copyValuesTo(this.lastFrame.getBones()[i]);
            }
            else
            {
                this.tempBones[i].copyValuesTo(this.lastTempFrame.getBones()[i]);
            }
            if (!this.tempBones[i].hasParent() || !this.moddedBones[currentBone.getId()].isActive
                ())
            {
                this.tempBones[i].setX(this.tempBones[i].getX() + this.pivotX);
                this.tempBones[i].setY(this.tempBones[i].getY() + this.pivotY);
            }
            this.translateRelative(this.tempBones[i], parent);
        }
        protected internal virtual void updateBone(com.brashmonkey.spriter.objects.SpriterBone
			 bone)
        {
            if (bone.hasParent())
            {
                //if(this.moddedBones[bone.getId()].isActive()) bone.setAngle(this.lastFrame.getBones()[bone.getId()].getAngle()+this.tempBones[bone.getParentId()].getAngle());
                com.brashmonkey.spriter.SpriterCalculator.translateRelative(this.tempBones[bone.getParentId
                    ()], this.lastFrame.getBones()[bone.getId()].getX(), this.lastFrame.getBones()[bone
                    .getId()].getY(), bone);
            }
        }
        private void updateTempObject(com.brashmonkey.spriter.objects.SpriterAbstractObject
			 source, com.brashmonkey.spriter.objects.SpriterAbstractObject[] target)
        {
            bool found = false;
            for (int j = 0; j < target.Length && !found; j++)
            {
                if (source.getId() == target[j].getId())
                {
                    source.copyValuesTo(target[j]);
                    found = true;
                }
            }
        }
        private void tweenObject(com.brashmonkey.spriter.objects.SpriterObject currentObject
			, com.brashmonkey.spriter.objects.SpriterObject nextObject, int i, long startTime
			, long endTime)
        {
            com.brashmonkey.spriter.draw.DrawInstruction dI = this.instructions[i];
            currentObject.copyValuesTo(this.tempObjects[i]);
            com.brashmonkey.spriter.objects.SpriterAbstractObject parent = null;
            if (!currentObject.isTransientObject())
            {
                this.tempObjects[i].setTimeline((nextObject != null) ? currentObject.getTimeline(
                    ) : -1);
                parent = (currentObject.hasParent()) ? this.tempBones[currentObject.getParentId()
                    ] : this.tempParent;
                if (nextObject != null)
                {
                    if (parent != this.tempParent)
                    {
                        if (!currentObject.getParent().equals(nextObject.getParent()))
                        {
                            nextObject = (com.brashmonkey.spriter.objects.SpriterObject)this.getTimelineObject
                                (currentObject, this.tempObjects2);
                            com.brashmonkey.spriter.SpriterCalculator.reTranslateRelative(parent, nextObject);
                            nextObject.setAngle(nextObject.getAngle() * this.flippedX * this.flippedY);
                        }
                    }
                    else
                    {
                        if (nextObject.hasParent())
                        {
                            nextObject = (com.brashmonkey.spriter.objects.SpriterObject)this.getTimelineObject
                                (currentObject, this.tempObjects2);
                            com.brashmonkey.spriter.SpriterCalculator.reTranslateRelative(parent, nextObject);
                            nextObject.setAngle(nextObject.getAngle() * this.flippedX * this.flippedY);
                        }
                    }
                    if (this.tempObjects[i].tween)
                    {
                        this.interpolateSpriterObject(this.tempObjects[i], currentObject, nextObject, startTime
                            , endTime);
                    }
                }
                this.moddedObjects[currentObject.getId()].modSpriterObject(this.tempObjects[i]);
                if (this.transitionFixed)
                {
                    this.tempObjects[i].copyValuesTo(this.lastFrame.getObjects()[i]);
                }
                else
                {
                    this.tempObjects[i].copyValuesTo(this.lastTempFrame.getObjects()[i]);
                }
            }
            else
            {
                parent = this.tempParent;
            }
            if (!this.tempObjects[i].hasParent())
            {
                this.tempObjects[i].setX(this.tempObjects[i].getX() + this.pivotX);
                this.tempObjects[i].setY(this.tempObjects[i].getY() + this.pivotY);
            }
            this.translateRelative(this.tempObjects[i], parent);
            if (this.moddedObjects[currentObject.getId()].getRef() != null)
            {
                this.tempObjects[i].setRef(this.moddedObjects[currentObject.getId()].getRef());
            }
            /*if (this.moddedObjects[currentObject.getId()].getLoader() != null)
            {
                this.tempObjects[i].setLoader(this.moddedObjects[currentObject.getId()].getLoader
                    ());
            }*/
            this.tempObjects[i].copyValuesTo(dI);
            this.setInstructionRef(dI, this.tempObjects[i], nextObject);
        }