public static returnFeatArray ConnectClosestFeatureAtPoint(IApplication app, List<ConnectClosestDetails> connectClosestLayers, IPoint location, string LayerName, bool logOperation, Keys mod)
        {
            bool bSelectedOnly;
            bool bUseTemplate;
            if (mod == Keys.Shift)
            {

                bSelectedOnly = true;
                bUseTemplate = true;

            }
            else if (mod == (Keys.Control | Keys.Shift))
            {
                bSelectedOnly = true;
                bUseTemplate = false;

            }
            else if (mod == Keys.Control)
            {
                bSelectedOnly = false;
                bUseTemplate = false;

            }
            else
            {

                bSelectedOnly = false;
                bUseTemplate = true;
            }
            List<IFeature> pRetFeature = null;
            IEditor editor = null;
            IMouseCursor appCursor = null;
            IMxDocument mxdoc = null;
            IMap map = null;
            IFeatureLayer pTargetLayer = null;
            IEditLayers eLayers = null;
            IFeatureLayer pointFLayer = null;
            IFeatureLayer connectLineFLayer = null;
            IEditTemplate pEditTemp = null;
            IGeometry pNearestFeature = null;
            IPolyline pNewPoly = null;
            IFeature pLine = null;
            returnFeatArray retVal = new returnFeatArray();
            try
            {
                pRetFeature = new List<IFeature>();
                //Get edit session
                editor = Globals.getEditor(app);

                if (editor == null)
                    return null;

                if (editor.EditState != esriEditState.esriStateEditing)
                {
                    MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("MustBEditg"), _caption);
                    //editor = null;

                    return null;
                }

                //Change mouse cursor to wait - automatically changes back (ArcGIS Desktop only)
                appCursor = new MouseCursorClass();
                appCursor.SetCursor(2);

                app = editor.Parent;
                mxdoc = (IMxDocument)app.Document;
                map = editor.Map;

                //Find required layers
                if (connectClosestLayers == null)
                    return null;
                if (connectClosestLayers.Count == 0)
                    return null;

                // Set the properties of the Step Progressor
                System.Int32 int32_hWnd = app.hWnd;

                if (logOperation)
                {
                    try
                    {
                        editor.StartOperation();
                    }
                    catch
                    {
                        logOperation = false;
                    }

                }
                pTargetLayer = null;
                bool FCorLayerTarget = true;
                if (LayerName != "")
                {
                    pTargetLayer = Globals.FindLayer(map, LayerName, ref FCorLayerTarget) as IFeatureLayer;

                }

                for (int k = 0; k < connectClosestLayers.Count; k++)
                {
                    if (pTargetLayer.Name.ToString() != (connectClosestLayers[k] as ConnectClosestDetails).Point_Layer)
                    { continue; }

                    // int currentLayerSub;
                    bool FCorLayerPoint = true;
                    bool FCorLayerConnect = true;
                    pointFLayer = Globals.FindLayer(map, (connectClosestLayers[k] as ConnectClosestDetails).Point_Layer, ref FCorLayerPoint) as IFeatureLayer;
                    connectLineFLayer = Globals.FindLayer(map, (connectClosestLayers[k] as ConnectClosestDetails).Line_Layer, ref FCorLayerConnect) as IFeatureLayer;

                    //Report any problems before exiting
                    if (pointFLayer == null)
                    {
                        //MessageBox.Show("Layer representing connection points was not found.  Configuration indicated feature class name: '" + _pointLayerName + "'.", this._caption);
                        //return;
                        continue;
                    }
                    if (connectLineFLayer == null)
                    {
                        //MessageBox.Show("Layer representing connect was not found.  Configuration indicated feature class name: '" + _connectLineLayerName + "'.", this._caption);
                        //return;
                        continue;
                    }
                    if (pTargetLayer != null)
                    {
                        if (pTargetLayer.FeatureClass.CLSID.Value.ToString() != pointFLayer.FeatureClass.CLSID.Value.ToString())

                        { continue; }

                    }

                    //Confirm that target layer is editable and is a line layer
                    eLayers = (IEditLayers)editor;
                    if (!(eLayers.IsEditable(connectLineFLayer)) || (connectLineFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline))
                        continue;

                    //Confirm the other layers are the correct shape type
                    if (pointFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint)
                        continue;

                    try
                    {

                        if (bUseTemplate)
                        {
                            //pEditTemp = Globals.PromptAndGetEditTemplate(app, connectLineFLayer, (connectClosestLayers[k] as ConnectClosestDetails).Line_EditTemplate);
                            pEditTemp = Globals.PromptAndGetEditTemplateGraphic(connectLineFLayer, (connectClosestLayers[k] as ConnectClosestDetails).Line_EditTemplate);
                        }
                        else
                        {
                            //pEditTemp = Globals.PromptAndGetEditTemplate(app, connectLineFLayer, "");
                            pEditTemp = Globals.PromptAndGetEditTemplateGraphic(connectLineFLayer, "");
                        }

                        pNearestFeature = Globals.GetClosestFeatureIgnoreExistingLineFeature((connectClosestLayers[k] as ConnectClosestDetails).Search_Threshold,
                                                                        location, pointFLayer, connectLineFLayer, bSelectedOnly);

                        if (pNearestFeature == null)
                            break;

                        pNewPoly = new PolylineClass();
                        pNewPoly.FromPoint = pNearestFeature as IPoint;
                        pNewPoly.ToPoint = location as IPoint;

                        if (pEditTemp == null)
                        {
                            pLine = Globals.CreateFeature(pNewPoly, connectLineFLayer, editor, app, false, false, true);
                        }
                        else
                        {
                            pLine = Globals.CreateFeature(pNewPoly, pEditTemp, editor, app, false, false, true);
                        }
                        pLine.Store();
                        pRetFeature.Add(pLine);

                        if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow != null)
                        {
                            if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow.ToUpper() == "DIGITIZED")
                            {
                                retVal.Options = "DIGITIZED";

                            }
                            else if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow.ToUpper() == "ROLE")
                            {
                                retVal.Options = "ROLE";

                            }
                            else if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow.ToUpper() == "Ancillary".ToUpper())
                            {
                                retVal.Options = "Ancillary".ToUpper();

                            }
                            else
                            {
                            }

                        }

                    }

                    catch (Exception ex)
                    {
                        editor.AbortOperation();
                        MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("ErrorInThe") + "ConnectClosestFeatureAtPoint\n" + ex.Message, ex.Source);

                    }

                    if (logOperation)
                    {
                        try
                        {
                            // Stop the edit operation
                            editor.StopOperation(_caption);

                        }
                        catch
                        {
                            logOperation = false;
                        }

                    }
                }
                (map as IActiveView).Refresh();
                retVal.Features = pRetFeature;
                return retVal;
            }

            catch (Exception ex)
            {
                MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("ErrorInThe") + "ConnectClosestFeatureAtPoint\n" + ex.Message, A4LGSharedFunctions.Localizer.GetString("ConstructionToolsLbl_1"));
                return null;
            }
            finally
            {
                pRetFeature = null;
                editor = null;
                appCursor = null;
                mxdoc = null;
                map = null;
                pTargetLayer = null;
                eLayers = null;
                pointFLayer = null;
                connectLineFLayer = null;
                pEditTemp = null;
                pNearestFeature = null;
                pNewPoly = null;
                pLine = null;
            }
        }
        public static returnFeatArray ConnectClosestFeature(IApplication app, List<ConnectClosestDetails> connectClosestLayers, bool logOperation, bool suppressDialog, string LayerName)
        {
            bool bUseTemplate;
            bool bSelectedOnly;
            if (Control.ModifierKeys == Keys.Shift)
            {

                bSelectedOnly = true;
                bUseTemplate = true;

            }
            else if (Control.ModifierKeys == (Keys.Control | Keys.Shift))
            {
                bSelectedOnly = true;
                bUseTemplate = false;

            }
            else if (Control.ModifierKeys == Keys.Control)
            {
                bSelectedOnly = false;
                bUseTemplate = false;

            }
            else
            {

                bSelectedOnly = false;
                bUseTemplate = true;
            }

            //ProgressBar
            ESRI.ArcGIS.Framework.IProgressDialogFactory progressDialogFactory = null;
            ESRI.ArcGIS.esriSystem.IStepProgressor stepProgressor = null;
            ESRI.ArcGIS.Framework.IProgressDialog2 progressDialog = null;
            // Create a CancelTracker
            ESRI.ArcGIS.esriSystem.ITrackCancel trackCancel = null;

            List<IFeature> pRetFeature = new List<IFeature>();
            IEditor editor = null;
            IMouseCursor appCursor = null;
            IMxDocument mxdoc = null;
            IMap map = null;
            IFeatureLayer pTargetLayer = null;
            IFeatureLayer pointFLayer = null;
            IFeatureLayer connectLineFLayer = null;
            ICursor pointCursor = null;
            IFeature pointFeature = null;

            IEditTemplate pEditTemp = null;
            IFeatureSelection pointFeatureSelection = null;
            IGeometry pNearestFeature = null;
            ISelectionSet2 sel = null;
            IPolyline pNewPoly = null;
            IFeature pLine = null;
            IEditLayers eLayers = null;
            returnFeatArray retVal = new returnFeatArray();
            try
            {
                //Get edit session
                trackCancel = new ESRI.ArcGIS.Display.CancelTrackerClass();
                editor = Globals.getEditor(app);
                if (editor == null)
                    return null;

                if (editor.EditState != esriEditState.esriStateEditing)
                {
                    MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("MustBEditg"), _caption);
                    //_editor = null;

                    return null;
                }

                //Change mouse cursor to wait - automatically changes back (ArcGIS Desktop only)
                appCursor = new MouseCursorClass();
                appCursor.SetCursor(2);

                mxdoc = (IMxDocument)app.Document;
                map = mxdoc.FocusMap;

                //Find required layers
                if (connectClosestLayers == null)
                    return null;
                if (connectClosestLayers.Count == 0)
                    return null;

                // Set the properties of the Step Progressor
                System.Int32 int32_hWnd = app.hWnd;
                if (suppressDialog == false)
                {
                    progressDialogFactory = new ESRI.ArcGIS.Framework.ProgressDialogFactoryClass();
                    stepProgressor = progressDialogFactory.Create(trackCancel, int32_hWnd);

                    stepProgressor.StepValue = 1;
                    stepProgressor.Message = _caption;
                    // Create the ProgressDialog. This automatically displays the dialog
                    progressDialog = (ESRI.ArcGIS.Framework.IProgressDialog2)stepProgressor; // Explict Cast

                    // Set the properties of the ProgressDialog
                    progressDialog.CancelEnabled = true;
                    progressDialog.Title = _caption;
                    progressDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressGlobe;
                    progressDialog.ShowDialog();

                }
                // Create an edit operation enabling undo/redo

                bool FCorLayerTarget = true;
                if (LayerName != "")
                {
                    pTargetLayer = Globals.FindLayer(map, LayerName, ref  FCorLayerTarget) as IFeatureLayer;

                }

                for (int k = 0; k < connectClosestLayers.Count; k++)
                {
                    bool FCorLayerPoint = true;
                    bool FCorLayerConnect = true;
                    //int currentLayerSub;
                    pointFLayer = Globals.FindLayer(map, (connectClosestLayers[k] as ConnectClosestDetails).Point_Layer, ref FCorLayerPoint) as IFeatureLayer;
                    connectLineFLayer = Globals.FindLayer(map, (connectClosestLayers[k] as ConnectClosestDetails).Line_Layer, ref FCorLayerConnect) as IFeatureLayer;

                    //Report any problems before exiting
                    if (pointFLayer == null)
                    {
                        //MessageBox.Show("Layer representing connection points was not found.  Configuration indicated feature class name: '" + _pointLayerName + "'.", _caption);
                        //return;
                        continue;
                    }
                    if (connectLineFLayer == null)
                    {
                        //MessageBox.Show("Layer representing connect was not found.  Configuration indicated feature class name: '" + _connectLineLayerName + "'.", _caption);
                        //return;
                        continue;
                    }
                    if (pTargetLayer != null)
                    {
                        if (pTargetLayer.FeatureClass.CLSID.Value.ToString() != pointFLayer.FeatureClass.CLSID.Value.ToString())

                        { continue; }
                    }

                    //Verify that some points are selected

                    pointFeatureSelection = (IFeatureSelection)pointFLayer;
                    if (pointFeatureSelection.SelectionSet.Count == 0)
                        continue;

                    //Confirm that target layer is editable and is a line layer
                    eLayers = (IEditLayers)editor;
                    if (!(eLayers.IsEditable(connectLineFLayer)) || (connectLineFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline))
                        continue;

                    //Confirm the other layers are the correct shape type
                    if (pointFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint)
                        continue;
                    if (suppressDialog == false)
                    {
                        stepProgressor.MinRange = 0;
                        stepProgressor.MaxRange = connectClosestLayers.Count;
                        progressDialog.Title = (connectClosestLayers[k] as ConnectClosestDetails).Line_Layer;
                        stepProgressor.Message = (connectClosestLayers[k] as ConnectClosestDetails).Line_Layer;
                        progressDialog.Description = A4LGSharedFunctions.Localizer.GetString("ConnectAsset") + "1" + A4LGSharedFunctions.Localizer.GetString("Of") + pointFeatureSelection.SelectionSet.Count + ".";
                    }

                    int total = pointFeatureSelection.SelectionSet.Count;
                    int i = 0;

                    try
                    {

                        if (logOperation)
                        {
                            try
                            {
                                editor.StartOperation();
                            }
                            catch
                            {
                                logOperation = false;
                            }

                        }

                        if (bUseTemplate)
                        {
                            pEditTemp = Globals.PromptAndGetEditTemplateGraphic(connectLineFLayer, connectClosestLayers[k].Line_EditTemplate);
                            //pEditTemp = Globals.PromptAndGetEditTemplate(app, connectLineFLayer, connectClosestLayers[k].Line_EditTemplate);
                        }
                        else
                        {
                            //pEditTemp = Globals.PromptAndGetEditTemplate(app, connectLineFLayer, "");
                            pEditTemp = Globals.PromptAndGetEditTemplateGraphic(connectLineFLayer, "");
                        }

                        sel = pointFeatureSelection.SelectionSet as ISelectionSet2;
                        //sel.Update(null, false, out pointCursor);
                        sel.Search(null, false, out pointCursor);
                        while ((pointFeature = (IFeature)pointCursor.NextRow()) != null)
                        {
                            i += 1;
                            if (suppressDialog == false)
                            {
                                //Update progress bar
                                progressDialog.Description = A4LGSharedFunctions.Localizer.GetString("ConnectAsset") + i.ToString() + A4LGSharedFunctions.Localizer.GetString("Of") + total.ToString() + "." + Environment.NewLine +
                                  A4LGSharedFunctions.Localizer.GetString("CurrentOID") + pointFeature.OID;
                                stepProgressor.Step();
                            }
                            ESRI.ArcGIS.esriSystem.IStatusBar statusBar = app.StatusBar;
                            statusBar.set_Message(0, i.ToString());

                            //Check if the cancel button was pressed. If so, stop process
                            bool boolean_Continue = trackCancel.Continue();
                            if (!boolean_Continue)
                            {
                                break;
                            }

                            //IFeature pNearestFeature =
                            pNearestFeature = Globals.GetClosestFeatureIgnoreExistingLineFeature((connectClosestLayers[k] as ConnectClosestDetails).Search_Threshold,
                                                                             pointFeature.ShapeCopy, pointFLayer, connectLineFLayer, bSelectedOnly);

                            if (pNearestFeature == null)
                                break;

                            pNewPoly = new PolylineClass();
                            pNewPoly.FromPoint = pNearestFeature as IPoint;
                            pNewPoly.ToPoint = pointFeature.ShapeCopy as IPoint;

                            if (pEditTemp == null)
                            {
                                pLine = Globals.CreateFeature(pNewPoly, connectLineFLayer, editor, app, false, false, true);
                            }
                            else
                            {
                                pLine = Globals.CreateFeature(pNewPoly, pEditTemp, editor, app, false, false, true);
                            }
                            pLine.Store();
                            pRetFeature.Add(pLine);

                        }
                        if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow != null)
                        {
                            if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow.ToUpper() == "DIGITIZED")
                            {
                                retVal.Options = "DIGITIZED";

                            }
                            else if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow.ToUpper() == "ROLE")
                            {
                                retVal.Options = "ROLE";

                            }
                            else if ((connectClosestLayers[k] as ConnectClosestDetails).Reset_Flow.ToUpper() == "Ancillary".ToUpper())
                            {
                                retVal.Options = "ANCILLARY";

                            }
                            else
                            {
                            }

                        }

                        if (logOperation)
                        {
                            try
                            {
                                // Stop the edit operation
                                editor.StopOperation((connectClosestLayers[k] as ConnectClosestDetails).Point_Layer);

                            }
                            catch
                            {
                                logOperation = false;
                            }

                        }

                    }

                    catch (Exception ex)
                    {
                        editor.AbortOperation();
                        MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("ErrorInThe") + "ConnectClosestFeature\n" + ex.Message, ex.Source);

                        // Cleanup
                        if (progressDialog != null)
                            progressDialog.HideDialog();
                        return null;
                    }

                }
                (map as IActiveView).Refresh();
                retVal.Features = pRetFeature;
                return retVal;
            }

            catch (Exception ex)
            {
                MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("ErrorInThe") + "ConnectClosestFeature\n" + ex.Message, A4LGSharedFunctions.Localizer.GetString("ConstructionToolsLbl_1"));
                return null;
            }
            finally
            {// Cleanup
                if (progressDialog != null)
                    progressDialog.HideDialog();
                if (pointCursor != null)
                    Marshal.ReleaseComObject(pointCursor);
                progressDialogFactory = null;
                stepProgressor = null;
                progressDialog = null;
                trackCancel = null;

                pRetFeature = null;
                editor = null;
                appCursor = null;
                mxdoc = null;
                map = null;
                pTargetLayer = null;
                pointFLayer = null;
                connectLineFLayer = null;
                pointCursor = null;
                pointFeature = null;

                pEditTemp = null;
                pointFeatureSelection = null;
                pNearestFeature = null;
                sel = null;
                pNewPoly = null;
                pLine = null;
                eLayers = null;

            }
        }