public static AECompositionTemplate ParseComposition(XmlNode composition)
    {
        AECompositionTemplate comp = new AECompositionTemplate ();

        comp.id = System.Convert.ToInt32(composition.Attributes.GetNamedItem("id").Value);
        comp.width = System.Convert.ToSingle(composition.Attributes.GetNamedItem("w").Value);
        comp.heigh = System.Convert.ToSingle(composition.Attributes.GetNamedItem("h").Value);

        XmlNode meta = composition.SelectSingleNode ("meta");
        comp.duration = GetFloat (meta, "duration");
        comp.totalFrames = GetInt (meta, "totalFrames");
        comp.frameDuration = frameDuration;

        XmlNodeList layersNodes = composition.SelectNodes("layer");

        foreach (XmlNode layerNode in layersNodes) {
            AELayerTemplate layer = new AELayerTemplate ();

            string layerType = layerNode.Attributes.GetNamedItem("type").Value;

            if(layerType.Equals("Composition")) {
                layer.type = AELayerType.COMPOSITION;
                layer.id  = System.Convert.ToInt32(layerNode.Attributes.GetNamedItem("id").Value);
            }

            if(layerType.Equals("Footage")) {
                layer.type = AELayerType.FOOTAGE;
                layer.source = layerNode.Attributes.GetNamedItem("source").Value;
            }

            layer.index  = Int32.Parse (layerNode.Attributes.GetNamedItem("index").Value);

            if(layerNode.Attributes.GetNamedItem("parent").Value != "none") {
                layer.parent = Int32.Parse (layerNode.Attributes.GetNamedItem("parent").Value);
            } else {
                layer.parent = 0;
            }

            layer.width  = System.Convert.ToInt32(layerNode.Attributes.GetNamedItem("w").Value);
            layer.height = System.Convert.ToInt32(layerNode.Attributes.GetNamedItem("h").Value);

            layer.name = layerNode.Attributes.GetNamedItem("name").Value;

            XmlNode sourceType = layerNode.Attributes.GetNamedItem("sourceType");
            if(sourceType != null) {
                layer.footageType = (AEFootageType) Enum.Parse(typeof(AEFootageType), sourceType.Value);
            }

            string blendMode = layerNode.Attributes.GetNamedItem("blending").Value;
            layer.blending = (AELayerBlendingType) System.Enum.Parse (typeof(AELayerBlendingType), blendMode);

            float inTime  = GetFloat (layerNode, "inPoint");
            float outTime = GetFloat (layerNode, "outPoint");
            layer.setInOutTime (inTime, outTime, comp);

            XmlNodeList frameNodes = layerNode.SelectNodes("keyframe");

            AEFrameTemplate lastFrame = null;
            foreach (XmlNode frameNode in frameNodes) {
                AEFrameTemplate frame = new AEFrameTemplate ();
                frame.index = Int32.Parse (frameNode.Attributes.GetNamedItem("frame").Value);
                //frame.time = System.Convert.ToSingle (frameNode.Attributes.GetNamedItem("time").Value);

                XmlNode source = frameNode.SelectSingleNode ("source");
                XmlNodeList propertyNodes = source.SelectNodes ("property");
                foreach(XmlNode propertyNode in propertyNodes) {
                    string propType = propertyNode.Attributes.GetNamedItem ("name").Value;

                    switch(propType) {
                        case AEPropertyType.ANCHOR_POINT:
                        frame.pivot = new Vector3 (GetFloat(propertyNode, "x"), GetFloat (propertyNode, "y"), GetFloat (propertyNode, "z"));
                        break;
                        case AEPropertyType.POSITION:
                        frame.SetPosition( new Vector3 (GetFloat(propertyNode, "x"), GetFloat (propertyNode, "y"), GetFloat (propertyNode, "z")) );
                        break;
                        case AEPropertyType.SCALE:
                        frame.scale = new Vector3 (GetFloat(propertyNode, "x"), GetFloat (propertyNode, "y"), GetFloat (propertyNode, "z")) * 0.01f;
                        break;
                        case AEPropertyType.ROTATION:
                        frame.rotation = GetFloat (propertyNode, "val");
                        break;
                        case AEPropertyType.OPACITY:
                        frame.opacity = GetFloat (propertyNode, "val");
                        break;
                    }
                }

                frame.CompareToFrame (lastFrame);

                lastFrame = frame;
                layer.addFrame (frame);

            }

            comp.addLayer (layer);
        }

        return comp;
    }
    public static AECompositionTemplate ParseComposition(XElement composition)
    {
        AECompositionTemplate comp = new AECompositionTemplate ();

        comp.id    = GetInt(composition.Attribute("id").Value);
        comp.width = GetFloat(composition.Attribute("w").Value);
        comp.heigh = GetFloat(composition.Attribute("h").Value);

        XElement meta_element = composition.Element("meta");
        comp.duration = GetFloat (meta_element.Attribute ("duration").Value);
        comp.totalFrames = GetInt (meta_element.Attribute ("totalFrames").Value);
        comp.frameDuration = frameDuration;

        foreach (XElement element in composition.Elements("layer")) {
                AELayerTemplate layer = new AELayerTemplate ();

                string layerType = element.Attribute("type").Value;

                if(layerType.Equals("Composition")) {
                    layer.type = AELayerType.COMPOSITION;
                    layer.id  = GetInt(element.Attribute("id").Value);
                }

                if(layerType.Equals("Footage")) {
                    layer.type = AELayerType.FOOTAGE;
                    layer.source = element.Attribute("source").Value;
                }

                layer.index = Int32.Parse (element.Attribute("index").Value);
                if(element.Attribute("parent").Value != "none") {
                    layer.parent = Int32.Parse(element.Attribute("parent").Value);
                }  else {
                    layer.parent = 0;
                }

                layer.width  = GetInt(element.Attribute("w").Value);
                layer.height = GetInt(element.Attribute("h").Value);
                layer.name = element.Attribute("name").Value;

                XAttribute sourceType = element.Attribute("sourceType");
                if(sourceType != null) {
                    layer.footageType = (AEFootageType) Enum.Parse(typeof(AEFootageType), sourceType.Value);
                }

                string blendMode = element.Attribute("blending").Value;
                layer.blending = (AELayerBlendingType) System.Enum.Parse (typeof(AELayerBlendingType), blendMode);

                float inTime  = GetFloat (element.Attribute("inPoint").Value);
                float outTime = GetFloat (element.Attribute("outPoint").Value);
                layer.setInOutTime (inTime, outTime, comp);

                AEFrameTemplate lastFrame = null;
                foreach (XElement sub_element in element.Elements()) {//keyframe
                    AEFrameTemplate frame = new AEFrameTemplate ();

                    frame.index = Int32.Parse(sub_element.Attribute("frame").Value);

                    foreach (XElement attribute in sub_element.Elements()) {//source

                        foreach (XElement sub_attribute in attribute.Elements()) {//property
                            string propType = sub_attribute.Attribute ("name").Value;

                            switch(propType) {
                                case AEPropertyType.ANCHOR_POINT:
                                    frame.pivot = new Vector3 (GetFloat(sub_attribute.Attribute ("x").Value), GetFloat(sub_attribute.Attribute ("y").Value), GetFloat (sub_attribute.Attribute ("z").Value));
                                    break;
                                case AEPropertyType.POSITION:
                                    frame.SetPosition(new Vector3 (GetFloat(sub_attribute.Attribute("x").Value),GetFloat(sub_attribute.Attribute("y").Value),GetFloat(sub_attribute.Attribute("z").Value)));
                                    break;
                                case AEPropertyType.SCALE:
                                    frame.scale = new Vector3 (GetFloat(sub_attribute.Attribute ("x").Value), GetFloat(sub_attribute.Attribute ("y").Value), GetFloat(sub_attribute.Attribute ("z").Value)) * 0.01f;
                                    break;
                                case AEPropertyType.ROTATION:
                                    frame.rotation = GetFloat(sub_attribute.Attribute ("val").Value);
                                    break;
                                case AEPropertyType.OPACITY:
                                    frame.opacity = GetFloat(sub_attribute.Attribute ("val").Value);
                                    break;
                            }
                        }

                        frame.CompareToFrame (lastFrame);

                        lastFrame = frame;
                        layer.addFrame (frame);
                    }

                }

                comp.addLayer (layer);
        }

        return comp;
    }