class DefaultAnimationPlan implements AnimationPlan {

    @Override
    public DefaultAnimationState determinePreviousState(AnimationState state)
    {
        DefaultAnimationState animationState = getDefaultAnimationState(state);
        validateStepNumber(animationState.getStepNumber());
        int prevIndex;
        Direction prevDirection = animationState.getDirection();
        if (getAnimationSequence().size() > 1)
        {
            if (animationState.getDirection() == Direction.BACKWARD)
            {
                prevIndex = animationState.getStepNumber() + 1;
                if (prevIndex >= getAnimationSequence().size())
                {
                    switch (getEndBehavior())
                    {
                        case BOUNCE:
                            prevDirection = animationState.getDirection().opposite();
                            prevIndex = animationState.getStepNumber() - 1;
                            break;
                        case STOP:
                            prevDirection = animationState.getDirection();
                            prevIndex = -1;
                            break;
                        case WRAP:
                            prevDirection = animationState.getDirection();
                            prevIndex = 0;
                            break;
                        default:
                            throw new UnexpectedEnumException(getEndBehavior());
                    }
                }
            }
            else
            {
                prevIndex = animationState.getStepNumber() - 1;
                if (prevIndex < 0)
                {
                    switch (getEndBehavior())
                    {
                        case BOUNCE:
                            prevDirection = animationState.getDirection().opposite();
                            prevIndex = animationState.getStepNumber() + 1;
                            break;
                        case STOP:
                            prevDirection = animationState.getDirection();
                            prevIndex = -1;
                            break;
                        case WRAP:
                            prevDirection = animationState.getDirection();
                            prevIndex = getAnimationSequence().size() - 1;
                            break;
                        default:
                            throw new UnexpectedEnumException(getEndBehavior());
                    }
                }
            }
        }
        else if (getEndBehavior() == EndBehavior.STOP)
        {
            return null;
        }
        else
        {
            prevDirection = Direction.FORWARD;
            prevIndex = 0;
        }

        return prevIndex >= 0 ? new DefaultAnimationState(prevIndex, prevDirection) : null;
    }

    public  DefaultAnimationPlan(List<? extends TimeSpan> sequence, EndBehavior endBehavior);

}