private static void LoadCreatives(XElement adElement, Ad ad)
        {
            var vastCreatives = adElement.Element("Creatives");
            if (vastCreatives != null)
            {
                foreach (var vastCreative in vastCreatives.Elements("Creative"))
                {
                    var vastItem = vastCreative.Elements().FirstOrDefault();
                    if (vastItem != null)
                    {
                        ICreative creative = null;
                        switch (vastItem.Name.LocalName)
                        {
                            case "Linear":
                                var vastLinear = vastItem;
                                var linearCreative = new CreativeLinear();
                                creative = linearCreative;

                                foreach (var trackingEvent in GetTrackingEvents(vastLinear))
                                    linearCreative.TrackingEvents.Add(trackingEvent);

                                if (vastLinear.Elements("AdParameters").Any())
                                {
                                    var xmlEncoded = (bool?)vastLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                    linearCreative.AdParameters = xmlEncoded ? XmlDecode((string)vastLinear.Element("AdParameters")) : (string)vastLinear.Element("AdParameters");
                                }

                                LoadVideoClicks(vastLinear, linearCreative);

                                if (vastLinear.Elements("CreativeExtensions").Any())
                                {
                                    foreach (var vastExtension in vastLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                    {
                                        linearCreative.Extensions.Add(new Extension()); // TODO
                                    }
                                }

                                linearCreative.Duration = ToNullableTimeSpan((string)vastLinear.Element("Duration"));
                                linearCreative.SkipOffset = FlexibleOffset.Parse((string)vastLinear.Attribute("skipoffset"));

                                var vastIcons = vastLinear.Element("Icons");
                                if (vastIcons != null)
                                {
                                    foreach (var vastIcon in vastIcons.Elements("Icon"))
                                    {
                                        var icon = new Icon();

                                        if (vastIcon.Elements("IconClicks").Any())
                                        {
                                            var iconClicks = vastIcon.Element("IconClicks");

                                            icon.ClickThrough = GetUriValue(iconClicks.Element("IconClickThrough"));

                                            foreach (var clickTracking in iconClicks.Elements("IconClickTracking"))
                                            {
                                                icon.ClickTracking.Add((string)clickTracking);
                                            }
                                        }

                                        icon.ApiFramework = (string)vastIcon.Attribute("apiFramework") ?? string.Empty;
                                        icon.Duration = ToNullableTimeSpan((string)vastIcon.Attribute("duration")) ?? new TimeSpan?();
                                        icon.Height = (int?)vastIcon.Attribute("height");
                                        icon.Width = (int?)vastIcon.Attribute("width");
                                        icon.Offset = ToNullableTimeSpan((string)vastIcon.Attribute("offset")) ?? new TimeSpan?();
                                        icon.Program = (string)vastIcon.Attribute("program") ?? string.Empty;
                                        icon.XPosition = (string)vastIcon.Attribute("xPosition") ?? string.Empty;
                                        icon.YPosition = (string)vastIcon.Attribute("yPosition") ?? string.Empty;
                                        icon.Item = GetResources(vastIcon).FirstOrDefault();
                                        foreach (var viewTrackingUrl in vastIcon.Elements("IconViewTracking"))
                                        {
                                            icon.ViewTracking.Add((string)viewTrackingUrl);
                                        }
                                        linearCreative.Icons.Add(icon);
                                    }
                                }

                                if (vastLinear.Elements("MediaFiles").Any())
                                {
                                    foreach (var vastMedia in vastLinear.Element("MediaFiles").Elements("MediaFile"))
                                    {
                                        var mediaFile = new MediaFile();
                                        mediaFile.ApiFramework = (string)vastMedia.Attribute("apiFramework") ?? string.Empty;
                                        mediaFile.Bitrate = ToNullableLong((string)vastMedia.Attribute("bitrate"));
                                        mediaFile.Codec = (string)vastMedia.Attribute("codec") ?? string.Empty;
                                        mediaFile.Delivery = (MediaFileDelivery)Enum.Parse(typeof(MediaFileDelivery), (string)vastMedia.Attribute("delivery"), true);
                                        mediaFile.Height = (int?)vastMedia.Attribute("height") ?? 0;
                                        mediaFile.Width = (int?)vastMedia.Attribute("width") ?? 0;
                                        mediaFile.Id = (string)vastMedia.Attribute("id");
                                        mediaFile.MaintainAspectRatio = (bool?)vastMedia.Attribute("maintainAspectRatio") ?? false;
                                        mediaFile.MaxBitrate = (long?)vastMedia.Attribute("maxBitrate") ?? 0;
                                        mediaFile.MinBitrate = (long?)vastMedia.Attribute("minBitrate") ?? 0;
                                        mediaFile.Scalable = (bool?)vastMedia.Attribute("scalable") ?? false;
                                        mediaFile.Type = (string)vastMedia.Attribute("type");
                                        mediaFile.Value = GetUriValue(vastMedia);
                                        linearCreative.MediaFiles.Add(mediaFile);
                                    }
                                }
                                break;
                            case "CompanionAds":
                                var vastCompanions = vastItem;
                                creative = LoadCompanions(vastCompanions);
                                break;
                            case "NonLinearAds":
                                var vastNonLinears = vastItem;
                                var nonLinearCreative = new CreativeNonLinears();
                                creative = nonLinearCreative;

                                foreach (var trackingEvent in GetTrackingEvents(vastNonLinears))
                                    nonLinearCreative.TrackingEvents.Add(trackingEvent);

                                foreach (var vastNonLinear in vastNonLinears.Elements("NonLinear"))
                                {
                                    var nonLinear = new NonLinear();

                                    if (vastNonLinear.Elements("AdParameters").Any())
                                    {
                                        var xmlEncoded = (bool?)vastNonLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                        nonLinear.AdParameters = xmlEncoded ? XmlDecode((string)vastNonLinear.Element("AdParameters")) : (string)vastNonLinear.Element("AdParameters");
                                    };
                                    nonLinear.ApiFramework = (string)vastNonLinear.Attribute("apiFramework");
                                    nonLinear.ClickThrough = GetUriValue(vastNonLinear.Element("NonLinearClickThrough"));
                                    foreach (var vastTracking in vastNonLinear.Elements("NonLinearClickTracking"))
                                    {
                                        nonLinear.ClickTracking.Add((string)vastTracking);
                                    }

                                    if (vastNonLinear.Elements("CreativeExtensions").Any())
                                    {
                                        foreach (var vastExtension in vastNonLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                        {
                                            nonLinear.Extensions.Add(new Extension()); // TODO
                                        }
                                    }
                                    nonLinear.ExpandedHeight = (int?)vastNonLinear.Attribute("expandedHeight");
                                    nonLinear.ExpandedWidth = (int?)vastNonLinear.Attribute("expandedWidth");
                                    nonLinear.Height = (int?)vastNonLinear.Attribute("height") ?? 0;
                                    nonLinear.Width = (int?)vastNonLinear.Attribute("width") ?? 0;
                                    nonLinear.MaintainAspectRatio = (bool?)vastNonLinear.Attribute("maintainAspectRatio") ?? false;
                                    nonLinear.MinSuggestedDuration = ToNullableTimeSpan((string)vastNonLinear.Attribute("minSuggestedDuration")) ?? new TimeSpan?();
                                    nonLinear.Scalable = (bool?)vastNonLinear.Attribute("scalable") ?? false;
                                    nonLinear.Item = GetResources(vastNonLinear).FirstOrDefault();
                                    nonLinearCreative.NonLinears.Add(nonLinear);
                                }
                                break;
                        }
                        if (creative != null)
                        {
                            creative.AdId = (string)vastCreative.Attribute("AdID");
                            creative.Id = (string)vastCreative.Attribute("id");
                            creative.Sequence = ToNullableInt((string)vastCreative.Attribute("sequence"));
                            ad.Creatives.Add(creative);
                        }
                    }
                }
            }
        }
 internal NonLinearSource(NonLinear nonLinear, CreativeNonLinears nonLinears)
 {
     NonLinear = nonLinear;
     NonLinears = nonLinears;
 }
        private static void LoadCreatives(XElement adElement, Ad ad)
        {
            var vastCreatives = adElement.Element("Creatives");

            if (vastCreatives != null)
            {
                foreach (var vastCreative in vastCreatives.Elements("Creative"))
                {
                    var vastItem = vastCreative.Elements().FirstOrDefault();
                    if (vastItem != null)
                    {
                        ICreative creative = null;
                        switch (vastItem.Name.LocalName)
                        {
                        case "Linear":
                            var vastLinear     = vastItem;
                            var linearCreative = new CreativeLinear();
                            creative = linearCreative;

                            foreach (var trackingEvent in GetTrackingEvents(vastLinear))
                            {
                                linearCreative.TrackingEvents.Add(trackingEvent);
                            }

                            if (vastLinear.Elements("AdParameters").Any())
                            {
                                var xmlEncoded = (bool?)vastLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                linearCreative.AdParameters = xmlEncoded ? XmlDecode((string)vastLinear.Element("AdParameters")) : (string)vastLinear.Element("AdParameters");
                            }

                            LoadVideoClicks(vastLinear, linearCreative);

                            if (vastLinear.Elements("CreativeExtensions").Any())
                            {
                                foreach (var vastExtension in vastLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                {
                                    linearCreative.Extensions.Add(new Extension());     // TODO
                                }
                            }

                            linearCreative.Duration   = ToNullableTimeSpan((string)vastLinear.Element("Duration"));
                            linearCreative.SkipOffset = FlexibleOffset.Parse((string)vastLinear.Attribute("skipoffset"));

                            var vastIcons = vastLinear.Element("Icons");
                            if (vastIcons != null)
                            {
                                foreach (var vastIcon in vastIcons.Elements("Icon"))
                                {
                                    var icon = new Icon();

                                    if (vastIcon.Elements("IconClicks").Any())
                                    {
                                        var iconClicks = vastIcon.Element("IconClicks");

                                        icon.ClickThrough = GetUriValue(iconClicks.Element("IconClickThrough"));

                                        foreach (var clickTracking in iconClicks.Elements("IconClickTracking"))
                                        {
                                            icon.ClickTracking.Add((string)clickTracking);
                                        }
                                    }

                                    icon.ApiFramework = (string)vastIcon.Attribute("apiFramework") ?? string.Empty;
                                    icon.Duration     = ToNullableTimeSpan((string)vastIcon.Attribute("duration")) ?? new TimeSpan?();
                                    icon.Height       = (int?)vastIcon.Attribute("height");
                                    icon.Width        = (int?)vastIcon.Attribute("width");
                                    icon.Offset       = ToNullableTimeSpan((string)vastIcon.Attribute("offset")) ?? new TimeSpan?();
                                    icon.Program      = (string)vastIcon.Attribute("program") ?? string.Empty;
                                    icon.XPosition    = (string)vastIcon.Attribute("xPosition") ?? string.Empty;
                                    icon.YPosition    = (string)vastIcon.Attribute("yPosition") ?? string.Empty;
                                    icon.Item         = GetResources(vastIcon).FirstOrDefault();
                                    foreach (var viewTrackingUrl in vastIcon.Elements("IconViewTracking"))
                                    {
                                        icon.ViewTracking.Add((string)viewTrackingUrl);
                                    }
                                    linearCreative.Icons.Add(icon);
                                }
                            }

                            if (vastLinear.Elements("MediaFiles").Any())
                            {
                                foreach (var vastMedia in vastLinear.Element("MediaFiles").Elements("MediaFile"))
                                {
                                    var mediaFile = new MediaFile();
                                    mediaFile.ApiFramework        = (string)vastMedia.Attribute("apiFramework") ?? string.Empty;
                                    mediaFile.Bitrate             = ToNullableLong((string)vastMedia.Attribute("bitrate"));
                                    mediaFile.Codec               = (string)vastMedia.Attribute("codec") ?? string.Empty;
                                    mediaFile.Delivery            = (MediaFileDelivery)Enum.Parse(typeof(MediaFileDelivery), (string)vastMedia.Attribute("delivery"), true);
                                    mediaFile.Height              = (int?)vastMedia.Attribute("height") ?? 0;
                                    mediaFile.Width               = (int?)vastMedia.Attribute("width") ?? 0;
                                    mediaFile.Id                  = (string)vastMedia.Attribute("id");
                                    mediaFile.MaintainAspectRatio = (bool?)vastMedia.Attribute("maintainAspectRatio") ?? false;
                                    mediaFile.MaxBitrate          = (long?)vastMedia.Attribute("maxBitrate") ?? 0;
                                    mediaFile.MinBitrate          = (long?)vastMedia.Attribute("minBitrate") ?? 0;
                                    mediaFile.Scalable            = (bool?)vastMedia.Attribute("scalable") ?? false;
                                    mediaFile.Type                = (string)vastMedia.Attribute("type");
                                    mediaFile.Value               = GetUriValue(vastMedia);
                                    linearCreative.MediaFiles.Add(mediaFile);
                                }
                            }
                            break;

                        case "CompanionAds":
                            var vastCompanions = vastItem;
                            creative = LoadCompanions(vastCompanions);
                            break;

                        case "NonLinearAds":
                            var vastNonLinears    = vastItem;
                            var nonLinearCreative = new CreativeNonLinears();
                            creative = nonLinearCreative;

                            foreach (var trackingEvent in GetTrackingEvents(vastNonLinears))
                            {
                                nonLinearCreative.TrackingEvents.Add(trackingEvent);
                            }

                            foreach (var vastNonLinear in vastNonLinears.Elements("NonLinear"))
                            {
                                var nonLinear = new NonLinear();

                                if (vastNonLinear.Elements("AdParameters").Any())
                                {
                                    var xmlEncoded = (bool?)vastNonLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                    nonLinear.AdParameters = xmlEncoded ? XmlDecode((string)vastNonLinear.Element("AdParameters")) : (string)vastNonLinear.Element("AdParameters");
                                }
                                ;
                                nonLinear.ApiFramework = (string)vastNonLinear.Attribute("apiFramework");
                                nonLinear.ClickThrough = GetUriValue(vastNonLinear.Element("NonLinearClickThrough"));
                                foreach (var vastTracking in vastNonLinear.Elements("NonLinearClickTracking"))
                                {
                                    nonLinear.ClickTracking.Add((string)vastTracking);
                                }

                                if (vastNonLinear.Elements("CreativeExtensions").Any())
                                {
                                    foreach (var vastExtension in vastNonLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                    {
                                        nonLinear.Extensions.Add(new Extension());     // TODO
                                    }
                                }
                                nonLinear.ExpandedHeight       = (int?)vastNonLinear.Attribute("expandedHeight");
                                nonLinear.ExpandedWidth        = (int?)vastNonLinear.Attribute("expandedWidth");
                                nonLinear.Height               = (int?)vastNonLinear.Attribute("height") ?? 0;
                                nonLinear.Width                = (int?)vastNonLinear.Attribute("width") ?? 0;
                                nonLinear.MaintainAspectRatio  = (bool?)vastNonLinear.Attribute("maintainAspectRatio") ?? false;
                                nonLinear.MinSuggestedDuration = ToNullableTimeSpan((string)vastNonLinear.Attribute("minSuggestedDuration")) ?? new TimeSpan?();
                                nonLinear.Scalable             = (bool?)vastNonLinear.Attribute("scalable") ?? false;
                                nonLinear.Item = GetResources(vastNonLinear).FirstOrDefault();
                                nonLinearCreative.NonLinears.Add(nonLinear);
                            }
                            break;
                        }
                        if (creative != null)
                        {
                            creative.AdId     = (string)vastCreative.Attribute("AdID");
                            creative.Id       = (string)vastCreative.Attribute("id");
                            creative.Sequence = ToNullableInt((string)vastCreative.Attribute("sequence"));
                            ad.Creatives.Add(creative);
                        }
                    }
                }
            }
        }
 internal NonLinearSource(NonLinear nonLinear, CreativeNonLinears nonLinears)
 {
     NonLinear  = nonLinear;
     NonLinears = nonLinears;
 }