/// <summary>
        /// Writes Motorized Printhead Type properties into XML.
        /// </summary>
        /// <param name="printheadTypeViewModel"></param>
        /// <returns></returns>
        public override void SerializePrintheadType(XmlWriter xmlWriter, PrintheadTypeViewModel printheadTypeViewModel)
        {
            if (printheadTypeViewModel != null)
            {
                MotorizedPrintheadTypeViewModel motorizedPrintheadTypeViewModel = (MotorizedPrintheadTypeViewModel)printheadTypeViewModel;

                //Outmost element should be "MotorizedPrintheadType".
                xmlWriter.WriteStartElement("MotorizedPrintheadType");

                //Motor Step Pin.
                if (motorizedPrintheadTypeViewModel.AttachedMotorStepGPIOPinViewModel != null)
                {
                    xmlWriter.WriteElementString("MotorStepPin", motorizedPrintheadTypeViewModel.AttachedMotorStepGPIOPinViewModel.PinID.ToString());
                }

                //Motor Direction Pin.
                if (motorizedPrintheadTypeViewModel.AttachedMotorDirectionGPIOPinViewModel != null)
                {
                    xmlWriter.WriteElementString("MotorDirectionPin", motorizedPrintheadTypeViewModel.AttachedMotorDirectionGPIOPinViewModel.PinID.ToString());
                }

                //Step Pulse Time.
                xmlWriter.WriteElementString("StepPulseTime", motorizedPrintheadTypeViewModel.StepPulseTime.ToString());

                //Limit Switch Pin.
                if (motorizedPrintheadTypeViewModel.AttachedLimitSwitchGPIOPinViewModel != null)
                {
                    xmlWriter.WriteElementString("LimitSwitchPin", motorizedPrintheadTypeViewModel.AttachedLimitSwitchGPIOPinViewModel.PinID.ToString());
                }

                //Max Speed.
                xmlWriter.WriteElementString("MaxSpeed", motorizedPrintheadTypeViewModel.MaxSpeed.ToString());

                //Max Acceleration.
                xmlWriter.WriteElementString("MaxAcceleration", motorizedPrintheadTypeViewModel.MaxAcceleration.ToString());

                //mm per Step.
                xmlWriter.WriteElementString("MmPerStep", motorizedPrintheadTypeViewModel.MmPerStep.ToString());

                //Max Position.
                xmlWriter.WriteElementString("MaxPosition", motorizedPrintheadTypeViewModel.MaxPosition.ToString());

                //Min Position.
                xmlWriter.WriteElementString("MinPosition", motorizedPrintheadTypeViewModel.MinPosition.ToString());

                //Close outmost element "MotorizedPrintheadType".
                xmlWriter.WriteEndElement();
            }
        }
        /// <summary>
        /// Calls OnPropertyChanged on the Min and Max Position properties for every Axis and Motorized Printhead.
        /// Typically called during automated calibration.
        /// </summary>
        public void UpdateMinMaxPositions()
        {
            foreach (AxisViewModel axisViewModel in _axisViewModelList)
            {
                axisViewModel.UpdateMinMaxPositions();
            }

            foreach (PrintheadViewModel printheadViewModel in _printheadViewModelList)
            {
                if (printheadViewModel.PrintheadType == PrintheadType.Motorized)
                {
                    MotorizedPrintheadTypeViewModel motorizedPrintheadTypeViewModel = (MotorizedPrintheadTypeViewModel)printheadViewModel.PrintheadTypeViewModel;
                    motorizedPrintheadTypeViewModel.UpdateMinMaxPositions();
                }
            }
        }
        /// <summary>
        /// Deserializes an XML file with Motorized Printhead Type properties then stores those properties into the input Valve PrintheadType.
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="printheadTypeViewModel"></param>
        public override void DeserializePrintheadType(XmlReader xmlReader, PrintheadTypeViewModel printheadTypeViewModel)
        {
            MotorizedPrintheadTypeViewModel motorizedPrintheadTypeViewModel = (MotorizedPrintheadTypeViewModel)printheadTypeViewModel;

            while (xmlReader.Read())
            {
                //Skip through newlines (this program's XML Writer uses newlines).
                if ((xmlReader.Name != "\n") && (!String.IsNullOrWhiteSpace(xmlReader.Name)))
                {
                    //End method if the end of "MotorizedPrintheadType" element is reached.
                    if ((xmlReader.Name == "MotorizedPrintheadType") && (xmlReader.NodeType == XmlNodeType.EndElement))
                    {
                        return;
                    }

                    switch (xmlReader.Name)
                    {
                    case "MotorStepPin":
                        motorizedPrintheadTypeViewModel.AttachedMotorStepGPIOPinViewModel = base._microcontrollerViewModel.FindPin(xmlReader.ReadElementContentAsInt());
                        motorizedPrintheadTypeViewModel.ExecuteRefreshPinBySettingListCommand("MotorStepPinViewModelList");
                        break;

                    case "MotorDirectionPin":
                        motorizedPrintheadTypeViewModel.AttachedMotorDirectionGPIOPinViewModel = base._microcontrollerViewModel.FindPin(xmlReader.ReadElementContentAsInt());
                        motorizedPrintheadTypeViewModel.ExecuteRefreshPinBySettingListCommand("MotorDirectionPinViewModelList");
                        break;

                    case "StepPulseTime":
                        motorizedPrintheadTypeViewModel.StepPulseTime = xmlReader.ReadElementContentAsInt();
                        break;

                    case "LimitSwitchPin":
                        motorizedPrintheadTypeViewModel.AttachedLimitSwitchGPIOPinViewModel = base._microcontrollerViewModel.FindPin(xmlReader.ReadElementContentAsInt());
                        motorizedPrintheadTypeViewModel.ExecuteRefreshPinBySettingListCommand("LimitSwitchPinViewModelList");
                        break;

                    case "MaxSpeed":
                        motorizedPrintheadTypeViewModel.MaxSpeed = xmlReader.ReadElementContentAsDouble();
                        break;

                    case "MaxAcceleration":
                        motorizedPrintheadTypeViewModel.MaxAcceleration = xmlReader.ReadElementContentAsDouble();
                        break;

                    case "MmPerStep":
                        motorizedPrintheadTypeViewModel.MmPerStep = xmlReader.ReadElementContentAsDouble();
                        break;

                    case "MaxPosition":
                        motorizedPrintheadTypeViewModel.MaxPosition = xmlReader.ReadElementContentAsDouble();
                        break;

                    case "MinPosition":
                        motorizedPrintheadTypeViewModel.MinPosition = xmlReader.ReadElementContentAsDouble();
                        break;

                    default:
                        base.ReportErrorUnrecognizedElement(xmlReader);
                        break;
                    }
                }
            }
        }