protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container)
        {
            YAMLMappingNode node = base.ExportYAMLRoot(container);

            node.Add(ConnectedBodyName, ConnectedBody.ExportYAML(container));
            node.Add(AnchorName, Anchor.ExportYAML(container));
            node.Add(AxisName, Axis.ExportYAML(container));
            node.Add(AutoConfigureConnectedAnchorName, AutoConfigureConnectedAnchor);
            node.Add(ConnectedAnchorName, ConnectedAnchor.ExportYAML(container));

            node.AddSerializedVersion(GetSerializedVersion(container.ExportVersion));
            node.Add(SecondaryAxisName, SecondaryAxis.ExportYAML(container));
            node.Add(XMotionName, (int)XMotion);
            node.Add(YMotionName, (int)YMotion);
            node.Add(ZMotionName, (int)ZMotion);
            node.Add(AngularXMotionName, (int)AngularXMotion);
            node.Add(AngularYMotionName, (int)AngularYMotion);
            node.Add(AngularZMotionName, (int)AngularZMotion);
            node.Add(LinearLimitSpringName, LinearLimitSpring.ExportYAML(container));
            node.Add(LinearLimitName, LinearLimit.ExportYAML(container));
            node.Add(AngularXLimitSpringName, AngularXLimitSpring.ExportYAML(container));
            node.Add(LowAngularXLimitName, LowAngularXLimit.ExportYAML(container));
            node.Add(HighAngularXLimitName, HighAngularXLimit.ExportYAML(container));
            node.Add(AngularYZLimitSpringName, AngularYZLimitSpring.ExportYAML(container));
            node.Add(AngularYLimitName, AngularYLimit.ExportYAML(container));
            node.Add(AngularZLimitName, AngularZLimit.ExportYAML(container));
            node.Add(TargetPositionName, TargetPosition.ExportYAML(container));
            node.Add(TargetVelocityName, TargetVelocity.ExportYAML(container));
            node.Add(XDriveName, XDrive.ExportYAML(container));
            node.Add(YDriveName, YDrive.ExportYAML(container));
            node.Add(ZDriveName, ZDrive.ExportYAML(container));
            node.Add(TargetRotationName, TargetRotation.ExportYAML(container));
            node.Add(TargetAngularVelocityName, TargetAngularVelocity.ExportYAML(container));
            node.Add(RotationDriveModeName, (int)RotationDriveMode);
            node.Add(AngularXDriveName, AngularXDrive.ExportYAML(container));
            node.Add(AngularYZDriveName, AngularYZDrive.ExportYAML(container));
            node.Add(SlerpDriveName, SlerpDrive.ExportYAML(container));
            node.Add(ProjectionModeName, (int)ProjectionMode);
            node.Add(ProjectionDistanceName, ProjectionDistance);
            node.Add(ProjectionAngleName, ProjectionAngle);
            node.Add(ConfiguredInWorldSpaceName, ConfiguredInWorldSpace);
            node.Add(SwapBodiesName, SwapBodies);

            node.Add(BreakForceName, BreakForce);
            node.Add(BreakTorqueName, BreakTorque);
            node.Add(EnableCollisionName, EnableCollision);
            node.Add(EnablePreprocessingName, EnablePreprocessing);
            node.Add(MassScaleName, MassScale);
            node.Add(ConnectedMassScaleName, ConnectedMassScale);
            return(node);
        }
        /// <summary>
        /// Create a new job in the Windows Azure Import/Export service.
        /// </summary>
        /// <param name="jobName">Name of the job.</param>
        /// <param name="configFilePath"></param>
        public void CreateJob(string jobName, string configFilePath)
        {
            var XConf = XDocument.Load(configFilePath);

            // ReturnAddress: Specifies the return address information for the job.
            var XReturnAddress = XConf.Descendants("ReturnAddress").First();
            var returnAddress  = new ReturnAddress(
                XReturnAddress.Element("Name").Value,
                XReturnAddress.Element("Address").Value,
                XReturnAddress.Element("Phone").Value,
                XReturnAddress.Element("Email").Value
                );

            // ReturnShipping: Specifies the return carrier and customer’s account with the carrier
            var XReturnShipping = XConf.Descendants("ReturnShipping").First();
            var returnShipping  = new ReturnShipping(
                XReturnShipping.Element("CarrierName").Value,
                XReturnShipping.Element("CarrierAccountNumber").Value
                );

            // Properties: The list of properties for the job.
            // refer to https://msdn.microsoft.com/en-us/library/azure/dn529110.aspx for more details
            var XJobProperty     = XConf.Descendants("JobProperty").First();
            var putJobProperties = new PutJobProperties(
                backupDriveManifest: bool.Parse(XJobProperty.Element("BackupDriveManifest").Value),
                description: XJobProperty.Element("Description").Value,
                enableVerboseLog: bool.Parse(XJobProperty.Element("EnableVerboseLog").Value),
                friendlyName: XJobProperty.Element("FriendlyName").Value,
                type: (XJobProperty.Element("JobType").Value.Equals("Import", StringComparison.InvariantCultureIgnoreCase)? JobType.Import: JobType.Export),
                location: XJobProperty.Element("Location").Value,
                storageAccountKey: XJobProperty.Element("StorageAccountKey").Value,
                storageAccountName: XJobProperty.Element("StorageAccountName").Value,
                importExportStatesPath: XJobProperty.Element("ImportExportStatesPath").Value,
                returnAddress: returnAddress,
                returnShipping: returnShipping
                );

            // must include either StorageAccountKey or ContainerSas in the request
            if (string.IsNullOrEmpty(XJobProperty.Element("StorageAccountKey").Value))
            {
                putJobProperties.StorageAccountKey = null;
                putJobProperties.ContainerSas      = XJobProperty.Element("ContainerSas").Value;
            }

            var putJobParameters = new PutJobParameters(jobName, putJobProperties);

            if (putJobProperties.Type == JobType.Export)
            {
                // BlobList: contain information about the blobs to be exported for an export job.
                var XBlobList = XConf.Descendants("BlobList").First().Elements();
                var blobList  = new BlobList(new List <string>(), new List <string>());
                foreach (var XBlob in XBlobList)
                {
                    if (!String.IsNullOrWhiteSpace(XBlob.Attribute("BlobPaths").Value))
                    {
                        blobList.BlobPath.Add(XBlob.Attribute("BlobPaths").Value);
                    }
                    if (!String.IsNullOrWhiteSpace(XBlob.Attribute("BlobPathPrefixes").Value))
                    {
                        blobList.BlobPathPrefix.Add(XBlob.Attribute("BlobPathPrefixes").Value);
                    }
                }
                putJobParameters.Export = new Export(blobList: blobList);
            }
            else
            {
                // DriveList: List of up to ten drives that comprise the job.
                var XDriveList = XConf.Descendants("DriveList").First().Elements();
                var driveList  = new List <Drive>();
                foreach (var XDrive in XDriveList)
                {
                    driveList.Add(new Drive(
                                      driveId: XDrive.Element("DriveId").Value,
                                      bitLockerKey: XDrive.Element("BitLockerKey").Value,
                                      manifestFile: XDrive.Element("ManifestFile").Value,
                                      manifestHash: XDrive.Element("ManifestHash").Value
                                      ));
                }
                putJobParameters.DriveList = driveList;
            }

            client.PutJob(XJobProperty.Element("StorageAccountName").Value, jobName, putJobParameters);
        }