private ResultType ExportGeometricNetwork()
        {
            // Create FeatureDataset filter for GxDialog
            IGxObjectFilter gxObjectFilter = new GxFilterGeometricNetworksClass();

            // Create GxDialog
            IGxDialog gxDialog = new GxDialogClass() {
                AllowMultiSelect = false,
                ButtonCaption = "Export",
                ObjectFilter = gxObjectFilter,
                RememberLocation = true,
                Title = "Save Geometric Network As"
            };

            // Open Dialog
            if (!gxDialog.DoModalSave(0)) { return ResultType.Cancelled; }

            // Must specify a name
            if (string.IsNullOrWhiteSpace(gxDialog.Name)) {
                GeometricNetworkViewModel.Default.AddMessage("You must specify a name", MessageType.Error);
                return ResultType.Error;
            }

            // Check parent feature dataset
            IGxObject fd = gxDialog.FinalLocation;
            if (fd == null || !fd.IsValid) {
                GeometricNetworkViewModel.Default.AddMessage(string.Format("Invalid feature dataset", gxDialog.Name), MessageType.Error);
                return ResultType.Error;
            }

            // Get feature dataset and workspace
            IGxDataset dataset = (IGxDataset)fd;
            IFeatureDataset d = (IFeatureDataset)dataset.Dataset;
            IWorkspace w = d.Workspace;

            // Check if geometric network already exists
            IGeometricNetwork gn = w.FindGeometricNetwork(gxDialog.Name);
            if (gn != null) {
                MessageBoxResult r = MessageBox.Show(
                    "The geometric network already exists. Remove?",
                    GeometricNetworkViewModel.Default.WindowTitle,
                    MessageBoxButton.YesNoCancel,
                    MessageBoxImage.Exclamation,
                    MessageBoxResult.Yes
                );
                switch (r) {
                    case MessageBoxResult.Yes:
                        IDataset dd = (IDataset)gn;

                        if (!dd.CanDelete()) {
                            GeometricNetworkViewModel.Default.AddMessage("Cannot delete geometric network", MessageType.Error);
                            return ResultType.Error;
                        }

                        try {
                            dd.Delete();
                            GeometricNetworkViewModel.Default.AddMessage("Deletion successful", MessageType.Information);
                        }
                        catch (Exception ex) {
                            GeometricNetworkViewModel.Default.AddMessage(ex.Message, MessageType.Error);
                            return ResultType.Error;
                        }

                        break;
                    case MessageBoxResult.No:
                    case MessageBoxResult.Cancel:
                    default:
                        return ResultType.Cancelled;
                }
            }

            // Initialize loader
            INetworkLoader3 networkLoader = new NetworkLoaderClass() {
                FeatureDatasetName = (IDatasetName)d.FullName,
                NetworkName = gxDialog.Name,
                NetworkType = esriNetworkType.esriNTUtilityNetwork,
                PreserveEnabledValues = PRESERVE_EXISTING_ENABLED_VALUES
            };
            INetworkLoaderProps networkLoadedProps = (INetworkLoaderProps)networkLoader;
            INetworkLoaderProgress_Event ne = (INetworkLoaderProgress_Event)networkLoader;
            ne.PutMessage += (a, b) => {
                GeometricNetworkViewModel.Default.AddMessage(string.Format("Progress: '{0}'", b), MessageType.Information);
            };

            // Assign XY snapping tolerance
            switch (SNAP_XY) {
                case SnapTolerance.None:
                    networkLoader.SnapTolerance = 0d;
                    networkLoader.UseXYsForSnapping = false;
                    break;
                case SnapTolerance.Default:
                    networkLoader.SnapTolerance = networkLoader.DefaultSnapTolerance;
                    networkLoader.UseXYsForSnapping = true;
                    break;
                case SnapTolerance.Minimum:
                    networkLoader.SnapTolerance = networkLoader.MinSnapTolerance;
                    networkLoader.UseXYsForSnapping = true;
                    break;
                case SnapTolerance.Maximum:
                    networkLoader.SnapTolerance = networkLoader.MaxSnapTolerance;
                    networkLoader.UseXYsForSnapping = true;
                    break;
                case SnapTolerance.Custom:
                    if (SNAP_XY_CUSTOM < networkLoader.MinSnapTolerance) {
                        networkLoader.SnapTolerance = networkLoader.MinSnapTolerance;
                    }
                    else if (SNAP_XY_CUSTOM > networkLoader.MaxSnapTolerance) {
                        networkLoader.SnapTolerance = networkLoader.MaxSnapTolerance;
                    }
                    else {
                        networkLoader.SnapTolerance = SNAP_XY_CUSTOM;
                    }
                    networkLoader.UseXYsForSnapping = true;
                    break;
            }

            // Assign Z snapping tolerance
            if (networkLoader.CanUseZs) {
                switch (SNAP_Z) {
                    case SnapTolerance.None:
                        networkLoader.ZSnapTolerance = 0d;
                        networkLoader.UseZs = false;
                        break;
                    case SnapTolerance.Default:
                        networkLoader.ZSnapTolerance = networkLoader.DefaultZSnapTolerance;
                        networkLoader.UseZs = true;
                        break;
                    case SnapTolerance.Minimum:
                        networkLoader.ZSnapTolerance = networkLoader.MinZSnapTolerance;
                        networkLoader.UseZs = true;
                        break;
                    case SnapTolerance.Maximum:
                        networkLoader.ZSnapTolerance = networkLoader.MaxZSnapTolerance;
                        networkLoader.UseZs = true;
                        break;
                    case SnapTolerance.Custom:
                        if (SNAP_Z_CUSTOM < networkLoader.MinZSnapTolerance) {
                            networkLoader.SnapTolerance = networkLoader.MinZSnapTolerance;
                        }
                        else if (SNAP_XY_CUSTOM > networkLoader.MaxZSnapTolerance) {
                            networkLoader.SnapTolerance = networkLoader.MaxZSnapTolerance;
                        }
                        else {
                            networkLoader.SnapTolerance = SNAP_Z_CUSTOM;
                        }
                        networkLoader.UseZs = true;
                        break;
                }
            }
            else {
                switch (SNAP_Z) {
                    case SnapTolerance.None:
                        break;
                    case SnapTolerance.Minimum:
                    case SnapTolerance.Maximum:
                    case SnapTolerance.Custom:
                        GeometricNetworkViewModel.Default.AddMessage("Z snapping is unavailable", MessageType.Warning);
                        break;
                }
            }

            // Check each feature class
            bool badfeatureclass = false;
            IFeatureClassContainer fcc = (IFeatureClassContainer)d;
            ZGeometricNetwork zgn = GeometricNetworkViewModel.Default.Dataset as ZGeometricNetwork;
            foreach (ZNetworkClass znc in zgn.NetworkClasses.Where(f => !f.IsOrphanJunctionFeatureClass)) {
                // Does the feature class exist?
                IFeatureClass fc = null;
                try {
                    fc = fcc.get_ClassByName(znc.Path.Table);
                }
                catch { }
                if (fc == null) {
                    GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' does not exists", znc.Path.Table), MessageType.Error);
                    badfeatureclass = true;
                    continue;
                }

                // Is the feature class compatiable?
                switch (networkLoader.CanUseFeatureClass(znc.Path.Table)) {
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCCannotOpen:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' cannot be opened", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCInAnotherNetwork:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' belongs to another network", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCInTerrain:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' belongs to a terrain", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCInTopology:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' belongs to a topology", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCInvalidFeatureType:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' has an invalid feature type", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCInvalidShapeType:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' has an invalid shape type", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCIsCompressedReadOnly:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' is compressed readonly", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCRegisteredAsVersioned:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' is registered as versioned", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCUnknownError:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("Feature class '{0}' has an unknown error", znc.Path.Table), MessageType.Error);
                        badfeatureclass = true;
                        break;
                    case esriNetworkLoaderFeatureClassCheck.esriNLFCCValid:
                        break;
                }
            }
            if (badfeatureclass) { return ResultType.Error; }

            // Add feature class to network
            bool snap = SNAP_XY == SnapTolerance.None;
            foreach (ZNetworkClass znc in zgn.NetworkClasses.Where(f => !f.IsOrphanJunctionFeatureClass)) {
                string table = znc.Path.Table;

                if (znc.IsJunction) {
                    // Add simple junction
                    UID uid = new UIDClass() {
                        Value = GUID_SIMPLEJUNCTION_CLSID
                    };
                    networkLoader.AddFeatureClass(table, esriFeatureType.esriFTSimpleJunction, uid, snap);

                    if (znc.IsSourceSink) {
                        // Check junction already has a role field
                        string field = networkLoadedProps.DefaultAncillaryRoleField;
                        switch (networkLoader.CheckAncillaryRoleField(table, field)) {
                            case esriNetworkLoaderFieldCheck.esriNLFCInvalidDomain:
                                GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - The AncillaryRole field has invalid domain", table, field), MessageType.Error);
                                return ResultType.Error;
                            case esriNetworkLoaderFieldCheck.esriNLFCInvalidType:
                                GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - The AncillaryRole field has invalid type", table, field), MessageType.Error);
                                return ResultType.Error;
                            case esriNetworkLoaderFieldCheck.esriNLFCNotFound:
                                GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - Adding AncillaryRole field", table, field), MessageType.Information);
                                networkLoader.PutAncillaryRole(table, esriNetworkClassAncillaryRole.esriNCARSourceSink, field);
                                break;
                            case esriNetworkLoaderFieldCheck.esriNLFCUnknownError:
                                GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - An unknown error was encountered", table, field), MessageType.Error);
                                return ResultType.Error;
                            case esriNetworkLoaderFieldCheck.esriNLFCValid:
                                GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - An AncillaryRole field already exists", table, field), MessageType.Warning);
                                networkLoader.PutAncillaryRole(table, esriNetworkClassAncillaryRole.esriNCARSourceSink, field);
                                break;
                        }
                    }
                }
                if (znc.IsEdge) {
                    if (znc.IsComplex) {
                        // Add simple junction
                        UID uid = new UIDClass() {
                            Value = GUID_COMPLEXEDGE_CLSID
                        };
                        networkLoader.AddFeatureClass(table, esriFeatureType.esriFTComplexEdge, uid, snap);
                    }
                    else {
                        // Add simple junction
                        UID uid = new UIDClass() {
                            Value = GUID_SIMPLEEDGE_CLSID
                        };
                        networkLoader.AddFeatureClass(table, esriFeatureType.esriFTSimpleEdge, uid, snap);
                    }
                }
            }

            // Check if network class has enabled field
            foreach (ZNetworkClass znc in zgn.NetworkClasses.Where(f =>!f.IsOrphanJunctionFeatureClass)) {
                string table = znc.Path.Table;
                string field = networkLoadedProps.DefaultEnabledField;

                switch (networkLoader.CheckEnabledDisabledField(table, field)) {
                    case esriNetworkLoaderFieldCheck.esriNLFCInvalidDomain:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - The enabled field has invalid domain", table, field), MessageType.Error);
                        return ResultType.Error;
                    case esriNetworkLoaderFieldCheck.esriNLFCInvalidType:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - The enabled field has invalid type", table, field), MessageType.Error);
                        return ResultType.Error;
                    case esriNetworkLoaderFieldCheck.esriNLFCNotFound:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - Adding enabled field", table, field), MessageType.Information);
                        networkLoader.PutEnabledDisabledFieldName(table, field);
                        break;
                    case esriNetworkLoaderFieldCheck.esriNLFCUnknownError:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - An unknown error was encountered", table, field), MessageType.Error);
                        return ResultType.Error;
                    case esriNetworkLoaderFieldCheck.esriNLFCValid:
                        GeometricNetworkViewModel.Default.AddMessage(string.Format("{0}:{1} - Enabled field already exists", table, field), MessageType.Warning);
                        break;
                }
            }

            // Import network weights
            foreach (ZNetWeight weight in zgn.Weights) {
                // Add weight
                GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding weight {0}", weight.Name), MessageType.Information);
                networkLoader.AddWeight(weight.Name, weight.WeightType.ToWeightType(), weight.BitGateSize);

                // Loop for each association
                foreach (ZNetWeightAssocation association in weight.NetWeightAssocations) {
                    // Add weight association
                    GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding weight association {0}:{1}", association.NetworkClass.Path.Table, association.Field.Name), MessageType.Information);
                    networkLoader.AddWeightAssociation(weight.Name, association.NetworkClass.Path.Table, association.Field.Name);
                }
            }

            // Load network
            try {
                networkLoader.LoadNetwork();
            }
            catch (Exception ex) {
                GeometricNetworkViewModel.Default.AddMessage(ex.Message, MessageType.Error);
                return ResultType.Error;
            }

            // Find new network
            IGeometricNetwork gn2 = w.FindGeometricNetwork(gxDialog.Name);
            if (gn2 == null) {
                GeometricNetworkViewModel.Default.AddMessage("Geometric network creation failed", MessageType.Error);
                return ResultType.Error;
            }

            // Update the name of the orphaned network class
            ZNetworkClass orphan = zgn.NetworkClasses.FirstOrDefault(n => n.IsOrphanJunctionFeatureClass);
            if (orphan != null) {
                orphan.Path.Table = string.Format("{0}_junctions", gxDialog.Name);
            }

            // Import junction rules
            foreach (ZJunctionConnectivityRule rule in zgn.JunctionRules) {
                GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding junction rule: {0}", rule.Id), MessageType.Information);
                IJunctionConnectivityRule2 r = new JunctionConnectivityRuleClass {
                    EdgeClassID = rule.Edge.Parent.ToVerfiedId(w).Value,
                    EdgeSubtypeCode = rule.Edge.Code,
                    JunctionClassID = rule.Junction.Parent.ToVerfiedId(w).Value,
                    JunctionSubtypeCode = rule.Junction.Code,
                    EdgeMinimumCardinality = rule.EdgeMinimum,
                    EdgeMaximumCardinality = rule.EdgeMaximum,
                    JunctionMinimumCardinality = rule.JunctionMinimum,
                    JunctionMaximumCardinality = rule.JunctionMaximum,
                    DefaultJunction = rule.IsDefault
                };
                gn2.AddRule(r);
            }

            // Import edge rules
            foreach (ZEdgeConnectivityRule rule in zgn.EdgeRules) {
                GeometricNetworkViewModel.Default.AddMessage(string.Format("Adding edge rule: {0}", rule.Id), MessageType.Information);
                IEdgeConnectivityRule r = new EdgeConnectivityRuleClass() {
                    FromEdgeClassID = rule.FromEdge.Parent.ToVerfiedId(w).Value,
                    FromEdgeSubtypeCode = rule.FromEdge.Code,
                    ToEdgeClassID = rule.ToEdge.Parent.ToVerfiedId(w).Value,
                    ToEdgeSubtypeCode = rule.ToEdge.Code
                };

                // Add junctions
                foreach (ZSubtype j in rule.Junctions) {
                    r.AddJunction(j.Parent.ToVerfiedId(w).Value, j.Code);
                }

                // Default junction?
                if (rule.DefaultJunction != null) {
                    r.DefaultJunctionClassID = rule.DefaultJunction.Parent.ToVerfiedId(w).Value;
                    r.DefaultJunctionSubtypeCode = rule.DefaultJunction.Code;
                }

                gn2.AddRule(r);
            }

            //
            GeometricNetworkViewModel.Default.AddMessage("Geometric network creation successful!", MessageType.Information);
            return ResultType.Successful;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (sender == this.MenuItemExit) {
                if (GeometricNetworkViewModel.Default.IsDirty) {
                    MessageBoxResult r = MessageBox.Show(
                        "Do you want to save before closing?",
                        GeometricNetworkViewModel.Default.WindowTitle,
                        MessageBoxButton.YesNoCancel,
                        MessageBoxImage.Exclamation,
                        MessageBoxResult.Yes
                    );
                    switch (r) {
                        case MessageBoxResult.Yes:
                            // Save document
                            GeometricNetworkViewModel.Default.Save();

                            // If user canceled save dialog then exit
                            if (GeometricNetworkViewModel.Default.IsDirty) { return; }

                            break;
                        case MessageBoxResult.No:
                            break;
                        case MessageBoxResult.Cancel:
                        default:
                            return;
                    }
                }

                // Exit application
                Application.Current.Shutdown(0);
            }
            else if (sender == this.ButtonOpen) {
                // Exit if dataset already open
                if (GeometricNetworkViewModel.Default.Dataset != null) {
                    MessageBox.Show(
                        "Please close the document first",
                        GeometricNetworkViewModel.Default.WindowTitle,
                        MessageBoxButton.OK,
                        MessageBoxImage.Information,
                        MessageBoxResult.OK
                    );
                    return;
                }

                OpenFileDialog openFileDialog = new OpenFileDialog() {
                    CheckFileExists = true,
                    Filter = "GN definition document" + " (*.esriGeoNet)|*.esriGeoNet",
                    FilterIndex = 1,
                    Multiselect = false,
                    Title = GeometricNetworkViewModel.Default.WindowTitle
                };

                // Check if user pressed "Save" and File is OK.
                bool? ok = openFileDialog.ShowDialog(this);
                if (!ok.HasValue || !ok.Value) { return; }
                if (string.IsNullOrWhiteSpace(openFileDialog.FileName)) { return; }

                //
                GeometricNetworkViewModel.Default.Load(openFileDialog.FileName);
            }
            else if (sender == this.ButtonSave) {
                // Handle event to prevent bubbling event to ButtonSave
                if (e != null) {
                    e.Handled = true;
                }

                // Exit if no dataset
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }

                // If no document, show "save as" dialog
                if (GeometricNetworkViewModel.Default.Document == null) {
                    this.Button_Click(this.ButtonSaveAs, null);
                    return;
                }

                // Save document
                GeometricNetworkViewModel.Default.Save();
            }
            else if (sender == this.ButtonSaveAs) {
                // Handle event to prevent bubbling event to ButtonSave
                if (e != null) {
                    e.Handled = true;
                }

                // Show save dialog
                SaveFileDialog saveFileDialog = new SaveFileDialog() {
                    DefaultExt = "esriGeoNet",
                    FileName = "Document1",
                    Filter = "GN definition document" + " (*.esriGeoNet)|*.esriGeoNet",
                    FilterIndex = 1,
                    OverwritePrompt = true,
                    RestoreDirectory = false,
                    Title = GeometricNetworkViewModel.Default.WindowTitle
                };

                // Check if user pressed "Save" and File is OK.
                bool? ok = saveFileDialog.ShowDialog(this);
                if (!ok.HasValue || !ok.Value) { return; }
                if (string.IsNullOrWhiteSpace(saveFileDialog.FileName)) { return; }

                //
                GeometricNetworkViewModel.Default.Save(saveFileDialog.FileName);
            }
            else if (sender == this.ButtonClose) {
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }
                if (GeometricNetworkViewModel.Default.IsDirty) {
                    MessageBoxResult r = MessageBox.Show(
                        "Do you want to save before closing?",
                        GeometricNetworkViewModel.Default.WindowTitle,
                        MessageBoxButton.YesNoCancel,
                        MessageBoxImage.Exclamation,
                        MessageBoxResult.Yes
                    );
                    switch (r) {
                        case MessageBoxResult.Yes:
                            GeometricNetworkViewModel.Default.Save();
                            break;
                        case MessageBoxResult.No:
                            break;
                        case MessageBoxResult.Cancel:
                        default:
                            return;
                    }
                }

                // Clear current dataset
                GeometricNetworkViewModel.Default.Clear();
            }
            else if (sender == this.ButtonImport) {
                // Create GxObjectFilter for GxDialog
                IGxObjectFilter gxObjectFilter = new GxFilterGeometricNetworksClass();

                // Create GxDialog
                IGxDialog gxDialog = new GxDialogClass() {
                    AllowMultiSelect = false,
                    ButtonCaption = "Import",
                    ObjectFilter = gxObjectFilter,
                    RememberLocation = true,
                    Title = "Please select a geometric network"
                };

                // Declare Enumerator to hold selected objects
                IEnumGxObject enumGxObject = null;

                // Open Dialog
                if (!gxDialog.DoModalOpen(0, out enumGxObject)) { return; }
                if (enumGxObject == null) { return; }

                // Get Selected Object (if any)
                IGxObject gxObject = enumGxObject.Next();
                if (gxObject == null) { return; }
                if (!gxObject.IsValid) { return; }

                // Get GxDataset
                if (!(gxObject is IGxDataset)) { return; }
                IGxDataset gxDataset = (IGxDataset)gxObject;

                // Load geometric network from named object
                IName name = (IName)gxDataset.DatasetName;
                GeometricNetworkLoader loader = new GeometricNetworkLoader(name);
                loader.Load();
            }
            else if (sender == this.ButtonExport) {
                ResultType ok = this.ExportGeometricNetwork();
                switch (ok) {
                    case ResultType.Cancelled:
                        break;
                    case ResultType.Error:
                        MessageBox.Show(
                            "Geometric network creation failed",
                            GeometricNetworkViewModel.Default.WindowTitle,
                            MessageBoxButton.OK,
                            MessageBoxImage.Information,
                            MessageBoxResult.OK
                        );
                        break;
                    case ResultType.Successful:
                        MessageBox.Show(
                           "Geometric network creation successful",
                           GeometricNetworkViewModel.Default.WindowTitle,
                           MessageBoxButton.OK,
                           MessageBoxImage.Information,
                           MessageBoxResult.OK
                       );
                        break;
                }
            }
            else if (sender == this.ButtonOutput) {
                if (this.DockableContentOutput.IsHidden) {
                    this.DockableContentOutput.Show();
                }
                else if (this.DockableContentOutput.IsAutoHidden) {
                    this.DockableContentOutput.ToggleAutoHide();
                }
            }
            else if (sender == this.ButtonJunctionAdd) {
                // Exit if invalid
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }
                if (GeometricNetworkViewModel.Default.SelectedJunctionRule != null) { return; }

                // Add junction rule
                if (this.DataGridJunctionRules.SelectedCells == null) { return; }
                if (this.DataGridJunctionRules.SelectedCells.Count == 0) { return; }
                DataGridCellInfo ci = this.DataGridJunctionRules.SelectedCells[0];
                object o = ci.Item;
                if (o == null) { return; }

                RuleDataGridColumn rdgc = ci.Column as RuleDataGridColumn;
                if (rdgc == null) { return; }

                ZGeometricNetwork zgn = GeometricNetworkViewModel.Default.Dataset as ZGeometricNetwork;
                if (zgn == null) { return; }

                // Create new rule
                ZSubtype e1 = o.GetType().GetProperty(RuleMatrix.EDGE_SUBTYPE).GetValue(o, null) as ZSubtype;
                ZSubtype j1 = zgn.FindSubtype(rdgc.ColumnName);
                ZJunctionConnectivityRule rule = new ZJunctionConnectivityRule(e1, j1);

                // Add rule to network
                zgn.JunctionRules.Add(rule);

                // Update data source
                o.GetType().GetProperty(rdgc.ColumnName).SetValue(o, rule, null);

                // Refresh display
                GeometricNetworkViewModel.Default.SelectedJunctionRule = (ZJunctionConnectivityRule)rule;
                GeometricNetworkViewModel.Default.JunctionRuleDataSource.Refresh();

                // Focus cell
                DataGridCellInfo cell = new DataGridCellInfo(o, rdgc);
                this.DataGridJunctionRules.CurrentCell = cell;
                this.DataGridJunctionRules.SelectedCells.Clear();
                this.DataGridJunctionRules.SelectedCells.Add(cell);

                // Make document dirty
                GeometricNetworkViewModel.Default.MakeDirty();
            }
            else if (sender == this.ButtonJunctionRemove) {
                // Exit if invalid
                if (GeometricNetworkViewModel.Default.Dataset == null) { return; }
                if (GeometricNetworkViewModel.Default.SelectedJunctionRule == null) { return; }

                // Get selected cell
                if (this.DataGridJunctionRules.SelectedCells == null) { return; }
                if (this.DataGridJunctionRules.SelectedCells.Count == 0) { return; }
                DataGridCellInfo ci = this.DataGridJunctionRules.SelectedCells[0];
                object o = ci.Item;
                if (o == null) { return; }

                // Get selected rule
                RuleDataGridColumn rdgc = ci.Column as RuleDataGridColumn;
                if (rdgc == null) { return; }
                ZRule rule = o.GetType().GetProperty(rdgc.ColumnName).GetValue(o, null) as ZRule;
                if (rule == null) { return; }

                // Update data source
                o.GetType().GetProperty(rdgc.ColumnName).SetValue(o, null, null);

                // Remove from dataset
                ZGeometricNetwork zgn = GeometricNetworkViewModel.Default.Dataset as ZGeometricNetwork;
                if (zgn == null) { return; }
                zgn.JunctionRules.Remove(rule);

                // Refresh display
                GeometricNetworkViewModel.Default.SelectedJunctionRule = (ZJunctionConnectivityRule)rule;
                GeometricNetworkViewModel.Default.JunctionRuleDataSource.Refresh();

                // Focus cell
                DataGridCellInfo cell = new DataGridCellInfo(o, rdgc);
                this.DataGridJunctionRules.CurrentCell = cell;
                this.DataGridJunctionRules.SelectedCells.Clear();
                this.DataGridJunctionRules.SelectedCells.Add(cell);

                // Make document dirty
                GeometricNetworkViewModel.Default.MakeDirty();
            }
        }