/// <summary>
        /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class
        /// using the data read from persistent storage.
        /// </summary>
        /// <param name="editDeserializer">The mechanism for reading back content.</param>
        internal LineSubdivisionOperation(EditDeserializer editDeserializer)
            : base(editDeserializer)
        {
            m_Line = editDeserializer.ReadFeatureRef <LineFeature>(DataField.Line);
            m_Face = editDeserializer.ReadPersistent <LineSubdivisionFace>(DataField.Face);
            //FeatureStub[] sections = editDeserializer.ReadFeatureStubArray(DataField.Result);

            if (editDeserializer.IsNextField(DataField.OtherSide))
            {
                InternalIdValue id = editDeserializer.ReadInternalId(DataField.OtherSide);
                OtherSide = (LineSubdivisionOperation)editDeserializer.MapModel.FindOperation(id);
                Debug.Assert(OtherSide != null);
                OtherSide.OtherSide = this;
            }

            Project p         = editDeserializer.Project;
            IEntity pointType = editDeserializer.ReadEntity(DataField.PointType);

            FeatureStub[] sections = CreateStubs(p, pointType, m_Line.EntityType);

            DeserializationFactory result = new DeserializationFactory(this, sections);

            ProcessFeatures(result);

            // Apply any IDs
            if (editDeserializer.IsNextField(DataField.Ids))
            {
                editDeserializer.ReadIdMappings(DataField.Ids);
            }
        }
        private void LineSubdivisionUpdateForm_Shown(object sender, EventArgs e)
        {
            // Get the object that was selected for update.
            Feature feat = m_UpdCmd.GetUpdate();
            if (feat == null)
                throw new InvalidOperationException("Unexpected update object");

            // Get the edit that created the primary face
            m_pop = (feat.Creator as LineSubdivisionOperation);
            Debug.Assert(m_pop != null);

            if (!m_pop.IsPrimaryFace)
            {
                m_pop = m_pop.OtherSide;
                Debug.Assert(m_pop != null);
                Debug.Assert(m_pop.IsPrimaryFace);
            }

            // Grab something we throw away if the user decides to cancel
            m_Face1 = CreateWorkingFace(m_pop.Face, true);
            m_Face2 = (m_pop.OtherSide == null ? null : CreateWorkingFace(m_pop.OtherSide.Face, false));

            // If we have two faces, the "New Face" button means you want to switch to the other face.
            if (m_Face2 != null)
                newFaceButton.Text = "&Other Face";

            // Default to the face containing the initially selected feature
            m_CurrentFace = (feat.Creator == m_pop ? m_Face1 : m_Face2);

            // If a line was selected, remember where it is in our working copy (and if it's actually on
            // the alternate face, make that the initial face for editing).
            m_SelectedLine = null;
            LineFeature selectedLine = (feat as LineFeature);
            if (selectedLine != null)
            {
                LineFeature[] sections = (m_CurrentFace == m_Face1 ? m_pop.Face.Sections : m_pop.OtherSide.Face.Sections);
                int lineIndex = Array.FindIndex<LineFeature>(sections, t => t == selectedLine);

                if (lineIndex >= 0)
                    m_SelectedLine = m_CurrentFace.Sections[lineIndex];
            }

            // Disable the option to flip annotation if annotation is currently invisible
            if (!EditingController.Current.AreLineAnnotationsDrawn)
                flipDistButton.Enabled = false;

            // Reload the list and repaint
            RefreshList();
        }
        /// <summary>
        /// Saves a new edit that defines an alternate face for a previously subdivided line.
        /// </summary>
        /// <param name="firstSide">The edit that initially subdivided the line.</param>
        /// <param name="altFace">The definition of the alternate face</param>
        void AddOtherSide(LineSubdivisionOperation firstSide, LineSubdivisionFace altFace)
        {
            try
            {
                LineSubdivisionOperation op = new LineSubdivisionOperation(firstSide.Parent, altFace.ObservedLengths, altFace.IsEntryFromEnd);
                op.OtherSide = firstSide;
                op.Execute();
                firstSide.OtherSide = op;
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace, ex.Message);
            }
        }
        internal void Save()
        {
            // Return if we do not have at least 2 distances
            if (m_Distances.Count<2)
            {
                MessageBox.Show("At least two distances must be specified.");
                return;
            }

            // Subdivide the line...
            LineSubdivisionOperation op = null;

            try
            {
                Distance[] distances = GetDistances();
                op = new LineSubdivisionOperation(m_Line, distances, !m_FromStart);
                op.Execute();
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace, ex.Message);
            }
        }