public override void Serialize(XmlNode parentNode, String nodeName, XmlDocument document)
        {
            base.Serialize(parentNode, nodeName, document);
            bool exportAsPercentFTP = Options.Instance.ExportSportTracksPowerAsPercentFTP;
            GarminCategories category = Options.Instance.GetGarminCategory(BaseTarget.ParentStep.ParentWorkout.Category);
            float lastFTP = 0;

            if (category == GarminCategories.Biking)
            {
                GarminBikingActivityProfile profile = (GarminBikingActivityProfile)GarminProfileManager.Instance.UserProfile.GetProfileForActivity(category);

                lastFTP = profile.FTP;
            }
            else
            {
                exportAsPercentFTP = false;
            }

            // This node was added by our parent...
            parentNode = parentNode.LastChild;

            XmlAttribute attribute;
            XmlNode childNode;
            GarminFitnessBool exportAsPercentMax = new GarminFitnessBool(exportAsPercentFTP, Constants.PowerReferenceTCXString[1], Constants.PowerReferenceTCXString[0]);
            GarminFitnessUInt32Range lowValue = new GarminFitnessUInt32Range(0);
            GarminFitnessUInt32Range highValue = new GarminFitnessUInt32Range(0);

            // Type
            attribute = document.CreateAttribute(Constants.XsiTypeTCXString, Constants.xsins);
            attribute.Value = Constants.PowerRangeZoneTCXString[1];
            parentNode.Attributes.Append(attribute);

            if (exportAsPercentMax)
            {
                float baseMultiplier = Constants.MaxHRInPercentMax / lastFTP;

                lowValue.Value = (UInt32)Utils.Clamp(Math.Round(Zone.Low * baseMultiplier, 0, MidpointRounding.AwayFromZero), Constants.MinPowerInPercentFTP, Constants.MaxPowerInPercentFTP);
                highValue.Value = (UInt32)Utils.Clamp(Math.Round(Zone.High * baseMultiplier, 0, MidpointRounding.AwayFromZero), Constants.MinPowerInPercentFTP, Constants.MaxPowerInPercentFTP);
            }
            else
            {
                lowValue.Value = (UInt32)Utils.Clamp(Zone.Low, Constants.MinPowerInWatts, Constants.MaxPowerWorkoutInWatts);
                highValue.Value = (UInt32)Utils.Clamp(Zone.High, Constants.MinPowerInWatts, Constants.MaxPowerWorkoutInWatts);
            }

            // Low
            childNode = document.CreateElement("Low");
            parentNode.AppendChild(childNode);
            exportAsPercentMax.SerializeAttribute(childNode, Constants.XsiTypeTCXString, Constants.xsins, document);
            lowValue.Serialize(childNode, Constants.ValueTCXString, document);

            // High
            childNode = document.CreateElement("High");
            parentNode.AppendChild(childNode);
            exportAsPercentMax.SerializeAttribute(childNode, Constants.XsiTypeTCXString, Constants.xsins, document);
            highValue.Serialize(childNode, Constants.ValueTCXString, document);

            // Extension
            Utils.SerializeSTZoneInfoXML(BaseTarget.ParentStep,
                                         Options.Instance.PowerZoneCategory,
                                         Zone, document);
        }
        public void SerializeData(Stream stream)
        {
            switch (m_Type)
            {
                case DataType.Enum:
                case DataType.UInt8:
                case DataType.UInt8z:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessByteRange data = new GarminFitnessByteRange(m_ByteValues[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.SInt8:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessSByteRange data = new GarminFitnessSByteRange(m_SByteValues[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.UInt16:
                case DataType.UInt16z:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessUInt16Range data = new GarminFitnessUInt16Range(m_UInt16Values[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.SInt16:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessInt16Range data = new GarminFitnessInt16Range(m_Int16Values[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.UInt32:
                case DataType.UInt32z:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessUInt32Range data = new GarminFitnessUInt32Range(m_UInt32Values[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.SInt32:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessInt32Range data = new GarminFitnessInt32Range(m_Int32Values[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.Float32:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessFloatRange data = new GarminFitnessFloatRange(m_SingleValues[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.Float64:
                    {
                        for (int i = 0; i < ArraySize; ++i)
                        {
                            GarminFitnessDoubleRange data = new GarminFitnessDoubleRange(m_DoubleValues[i]);

                            data.Serialize(stream);
                        }
                        break;
                    }
                case DataType.String:
                    {
                        Byte[] valueStored = new Byte[FieldSize];

                        for(int i = 0; i < valueStored.Length; ++i)
                        {
                            if (i < m_ByteValues.Length)
                            {
                                valueStored[i] = m_ByteValues[i];
                            }
                            else
                            {
                                valueStored[i] = 0;
                            }
                        }
                        stream.Write(valueStored, 0, valueStored.Length);
                        break;
                    }
                case DataType.Byte:
                    {
                        stream.Write(m_ByteValues, 0, m_ByteValues.Length);
                        break;
                    }
                default:
                    {
                        Debug.Assert(false);
                        break;
                    }
            }
        }