public void PasteNeurons()
        {
            NeuronArray myClipBoard = MainWindow.myClipBoard;

            if (targetNeuronIndex == -1)
            {
                return;
            }
            if (myClipBoard == null)
            {
                return;
            }

            //We are pasting neurons from the clipboard.
            //The arrays have different sizes so we may by row-col.

            //first check to see if the destination is claar and warn
            List <int> targetNeurons = new List <int>();

            for (int i = 0; i < myClipBoard.arraySize; i++)
            {
                if (myClipBoard.GetNeuron(i, true) != null)
                {
                    targetNeurons.Add(GetNeuronArrayId(i));
                }
            }

            MainWindow.theNeuronArray.GetNeuronLocation(targetNeuronIndex, out int col, out int row);
            if (col + myClipBoard.Cols > MainWindow.theNeuronArray.Cols ||
                row + myClipBoard.rows > MainWindow.theNeuronArray.rows)
            {
                MessageBoxResult result = MessageBox.Show("Paste would exceed neuron array boundary!", "Error", MessageBoxButton.OK);
                return;
            }

            if (!IsDestinationClear(targetNeurons, 0, true))
            {
                MessageBoxResult result = MessageBox.Show("Some desination neurons are in use and will be overwritten, continue?", "Continue", MessageBoxButton.YesNo);
                if (result == MessageBoxResult.No)
                {
                    return;
                }
            }

            MainWindow.theNeuronArray.SetUndoPoint();
            //now paste the neurons
            for (int i = 0; i < myClipBoard.arraySize; i++)
            {
                if (myClipBoard.GetNeuron(i) != null)
                {
                    int destID = GetNeuronArrayId(i);
                    MainWindow.theNeuronArray.GetNeuron(destID).AddUndoInfo();
                    Neuron n = myClipBoard.GetCompleteNeuron(i, true);
                    n.Owner    = myClipBoard;
                    n.synapses = myClipBoard.GetSynapsesList(i);

                    Neuron sourceNeuron = n.Clone();
                    sourceNeuron.id = destID;
                    while (sourceNeuron.label != "" && MainWindow.theNeuronArray.GetNeuron(sourceNeuron.label) != null)
                    {
                        int num        = 0;
                        int digitCount = 0;
                        while (sourceNeuron.label != "" && Char.IsDigit(sourceNeuron.label[sourceNeuron.label.Length - 1]))
                        {
                            int.TryParse(sourceNeuron.label[sourceNeuron.label.Length - 1].ToString(), out int digit);
                            num = num + (int)Math.Pow(10, digitCount) * digit;
                            digitCount++;
                            sourceNeuron.label = sourceNeuron.label.Substring(0, sourceNeuron.label.Length - 1);
                        }
                        num++;
                        sourceNeuron.label = sourceNeuron.label + num.ToString();
                    }
                    sourceNeuron.Owner = MainWindow.theNeuronArray;
                    sourceNeuron.Label = sourceNeuron.label;
                    MainWindow.theNeuronArray.SetNeuron(destID, sourceNeuron);


                    foreach (Synapse s in n.Synapses)
                    {
                        MainWindow.theNeuronArray.GetNeuron(destID).
                        AddSynapseWithUndo(GetNeuronArrayId(s.TargetNeuron), s.Weight, s.model);
                    }
                }
            }

            //handle boundary synapses
            foreach (BoundarySynapse b in boundarySynapsesOut)
            {
                int    sourceID     = GetNeuronArrayId(b.innerNeuronID);
                Neuron targetNeuron = MainWindow.theNeuronArray.GetNeuron(b.outerNeuronID);
                if (targetNeuron != null)
                {
                    MainWindow.theNeuronArray.GetNeuron(sourceID).AddSynapseWithUndo(targetNeuron.id, b.weight, b.model);
                }
            }
            foreach (BoundarySynapse b in boundarySynapsesIn)
            {
                int    targetID     = GetNeuronArrayId(b.innerNeuronID);
                Neuron sourceNeuron = MainWindow.theNeuronArray.GetNeuron(b.outerNeuronID);
                if (sourceNeuron != null)
                {
                    sourceNeuron.AddSynapseWithUndo(targetID, b.weight, b.model);
                }
            }

            //paste modules
            foreach (ModuleView mv in myClipBoard.modules)
            {
                ModuleView newMV = new ModuleView()
                {
                    FirstNeuron = GetNeuronArrayId(mv.FirstNeuron),
                    TheModule   = mv.TheModule,
                    Color       = mv.Color,
                    Height      = mv.Height,
                    Width       = mv.Width,
                    Label       = mv.Label,
                    CommandLine = mv.CommandLine,
                };

                MainWindow.theNeuronArray.modules.Add(newMV);
            }

            Update();
        }
        //copy the selection to a clipboard
        public void CopyNeurons()
        {
            //get list of neurons to copy
            List <int> neuronsToCopy = theSelection.EnumSelectedNeurons();

            theSelection.GetSelectedBoundingRectangle(out int X1o, out int Y1o, out int X2o, out int Y2o);
            MainWindow.myClipBoard = new NeuronArray();
            NeuronArray myClipBoard;

            myClipBoard = MainWindow.myClipBoard;
            myClipBoard.Initialize((X2o - X1o + 1) * (Y2o - Y1o + 1), (Y2o - Y1o + 1), true);
            boundarySynapsesOut.Clear();
            boundarySynapsesIn.Clear();

            //copy the neurons
            foreach (int nID in neuronsToCopy)
            {
                int destId = GetClipboardId(X1o, Y1o, nID);
                //copy the source neuron to the clipboard
                Neuron sourceNeuron = MainWindow.theNeuronArray.GetNeuron(nID);
                Neuron destNeuron   = sourceNeuron.Clone();
                destNeuron.Owner = myClipBoard;
                destNeuron.Id    = destId;
                destNeuron.Label = sourceNeuron.Label;
                myClipBoard.SetNeuron(destId, destNeuron);
            }

            //copy the synapses (this is two-pass so we make sure all neurons exist prior to copying
            foreach (int nID in neuronsToCopy)
            {
                Neuron sourceNeuron = MainWindow.theNeuronArray.GetNeuron(nID);
                if (MainWindow.useServers)
                {
                    sourceNeuron.synapses = NeuronClient.GetSynapses(sourceNeuron.id);
                }

                int    destId     = GetClipboardId(X1o, Y1o, nID);
                Neuron destNeuron = myClipBoard.GetNeuron(destId);
                destNeuron.Owner = myClipBoard;
                if (sourceNeuron.Synapses != null)
                {
                    foreach (Synapse s in sourceNeuron.Synapses)
                    {
                        //only copy synapses with both ends in the selection
                        if (neuronsToCopy.Contains(s.TargetNeuron))
                        {
                            destNeuron.AddSynapse(GetClipboardId(X1o, Y1o, s.TargetNeuron), s.Weight, s.model);
                        }
                        else
                        {
                            string targetName = MainWindow.theNeuronArray.GetNeuron(s.targetNeuron).label;
                            if (targetName != "")
                            {
                                boundarySynapsesOut.Add(new BoundarySynapse
                                {
                                    innerNeuronID = destNeuron.id,
                                    outerNeuronID = s.targetNeuron,
                                    weight        = s.weight,
                                    model         = s.model
                                });
                            }
                        }
                    }
                }
                if (sourceNeuron.SynapsesFrom != null)
                {
                    foreach (Synapse s in sourceNeuron.SynapsesFrom)
                    {
                        if (!neuronsToCopy.Contains(s.TargetNeuron))
                        {
                            string sourceName = MainWindow.theNeuronArray.GetNeuron(s.targetNeuron).label;
                            if (sourceName != "")
                            {
                                boundarySynapsesIn.Add(new BoundarySynapse
                                {
                                    innerNeuronID = destNeuron.id,
                                    outerNeuronID = s.targetNeuron,
                                    weight        = s.weight,
                                    model         = s.model
                                });;
                            }
                        }
                    }
                }
            }

            //copy modules
            foreach (ModuleView mv in MainWindow.theNeuronArray.modules)
            {
                if (theSelection.NeuronInSelection(mv.FirstNeuron) > 0 && theSelection.NeuronInSelection(mv.LastNeuron) > 0)
                {
                    ModuleView newMV = new ModuleView()
                    {
                        FirstNeuron = GetClipboardId(X1o, Y1o, mv.FirstNeuron),
                        TheModule   = mv.TheModule,
                        Color       = mv.Color,
                        Height      = mv.Height,
                        Width       = mv.Width,
                        Label       = mv.Label,
                        CommandLine = mv.CommandLine,
                    };

                    myClipBoard.modules.Add(newMV);
                }
            }
        }
        //copy the selection to a clipboard
        public void CopyNeurons()
        {
            //get list of neurons to copy
            List <int> neuronsToCopy = theSelection.EnumSelectedNeurons();

            theSelection.GetSelectedBoundingRectangle(out int X1o, out int Y1o, out int X2o, out int Y2o);
            MainWindow.myClipBoard = new NeuronArray();
            NeuronArray myClipBoard;

            myClipBoard = MainWindow.myClipBoard;
            myClipBoard.Initialize((X2o - X1o + 1) * (Y2o - Y1o + 1), (Y2o - Y1o + 1));

            //copy the neurons
            foreach (int nID in neuronsToCopy)
            {
                int destId = GetClipboardId(X1o, Y1o, nID);
                //copy the source neuron to the clipboard
                Neuron sourceNeuron = MainWindow.theNeuronArray.GetNeuron(nID);
                Neuron destNeuron   = sourceNeuron.Clone();
                destNeuron.Owner = myClipBoard;
                destNeuron.Id    = destId;
                myClipBoard.SetNeuron(destId, destNeuron);
            }
            //copy the synapses (this is two-pass so we make sure all neurons exist prior to copying
            foreach (int nID in neuronsToCopy)
            {
                Neuron sourceNeuron = MainWindow.theNeuronArray.GetNeuron(nID);
                int    destId       = GetClipboardId(X1o, Y1o, nID);
                Neuron destNeuron   = myClipBoard.GetNeuron(destId);
                destNeuron.Owner = myClipBoard;
                if (sourceNeuron.Synapses != null)
                {
                    foreach (Synapse s in sourceNeuron.Synapses)
                    {
                        //only copy synapses with both ends in the selection
                        if (neuronsToCopy.Contains(s.TargetNeuron))
                        {
                            destNeuron.AddSynapse(GetClipboardId(X1o, Y1o, s.TargetNeuron), s.Weight, s.isHebbian);
                        }
                    }
                }
            }

            //copy modules
            foreach (ModuleView mv in MainWindow.theNeuronArray.modules)
            {
                if (theSelection.NeuronInSelection(mv.FirstNeuron) > 0 && theSelection.NeuronInSelection(mv.LastNeuron) > 0)
                {
                    ModuleView newMV = new ModuleView()
                    {
                        FirstNeuron = GetClipboardId(X1o, Y1o, mv.FirstNeuron),
                        TheModule   = mv.TheModule,
                        Color       = mv.Color,
                        Height      = mv.Height,
                        Width       = mv.Width,
                        Label       = mv.Label,
                        CommandLine = mv.CommandLine,
                    };

                    myClipBoard.modules.Add(newMV);
                }
            }
        }