class AnimationManagerStateController extends AbstractModuleStateController {

    @Override
    public void activateState(String id, String description, Collection<? extends String> tags, Node node)
    {
        try
        {
            XPath xpath = StateXML.newXPath();

            Node timeNode = (Node)xpath.evaluate("/" + ModuleStateController.STATE_QNAME + "/:time", node, XPathConstants.NODE);
            Node animationNode = (Node)xpath.evaluate("/" + ModuleStateController.STATE_QNAME + "/:time/:animation", node,
                    XPathConstants.NODE);

            if (timeNode == null || animationNode == null)
            {
                return;
            }

            if (checkNoAnimation(node))
            {
                myAnimationManager.abandonPlan();
                String evaluate = xpath.evaluate("/" + ModuleStateController.STATE_QNAME + "/:time/:current", timeNode);
                if (StringUtils.isEmpty(evaluate))
                {
                    myTimeManager.setPrimaryActiveTimeSpan(TimeSpan.ZERO);
                }
                return;
            }

            try
            {
                ExportTimeState timeState = XMLUtilities.readXMLObject(timeNode, ExportTimeState.class);
                TimeSpan activeSpan = timeState.getCurrent();
                Duration advanceDuration = timeState.getAdvanceDuration();
                ExportAnimationState animState = XMLUtilities.readXMLObject(animationNode, ExportAnimationState.class);
                TimeSpan loopSpan = animState.getLoopInterval();

                // Fix the sequence
                List<? extends TimeSpan> sequence = timeState.getSequence() != null ? timeState.getSequence()
                        : Collections.<TimeSpan>emptyList();

                // Fix the loop span
                if (loopSpan == null)
                {
                    loopSpan = activeSpan;
                }

                activeSpan = fixActiveSpan(activeSpan, sequence, loopSpan, advanceDuration);

                AnimationPlan plan = createAnimationPlan(sequence, loopSpan, activeSpan, advanceDuration);

                AnimationState animationState = plan.findState(activeSpan, AnimationState.Direction.FORWARD);
                PlayState playState = animState.getPlayState();
                Direction animationDirection = playState == null || playState == PlayState.STOP ? null
                        : playState == PlayState.REVERSE ? Direction.BACKWARD : Direction.FORWARD;
                myAnimationManager.setPlan(plan, animationState, animationDirection,
                        new Milliseconds(getMillisPerFrame(animState)));
            }
            catch (JAXBException e)
            {
                LOGGER.error("Failed to read animation state: " + e, e);
            }
        }
        catch (XPathExpressionException e)
        {
            LOGGER.error(e, e);
        }
    }

    public  AnimationManagerStateController(AnimationManager animationManager, TimeManager timeManager);

}