/// <summary>
        /// Returns true if all the following conditions are met:
        /// 1) Timestep group contains timesteps.
        /// 2) Timesteps contained within group are consecutive.
        /// </summary>
        /// <returns></returns>
        public bool TimestepGroupIsLoopable(TimestepGroup tsg)
        {
            if (tsg == null)
                return false;
            if (!TimestepGroups.Contains(tsg))
                return false;

            List<TimeStep> memberSteps = new List<TimeStep>();
            List<int> memberStepIds = new List<int>();
            foreach (TimeStep step in TimeSteps)
            {
                if (step.MyTimestepGroup == tsg)
                {
                    memberSteps.Add(step);
                    memberStepIds.Add(TimeSteps.IndexOf(step));
                }
            }

            if (memberStepIds.Count == 0)
                return false;

            int firstVal = memberStepIds[0];
            for (int i = 0; i < memberStepIds.Count; i++)
            {
                if (memberStepIds[i] != firstVal + i)
                    return false;
            }
            return true;
        }
        private void insertSequenceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<TimeStep> markedSteps = markedTimesteps();

            DialogResult result;

            if (markedSteps.Count == 0)
            {
                result = MessageBox.Show("This operation will insert a sequence at the beginning of the currently open sequence. To insert a sequence elsewhere in the open sequence, mark the timestep that you would like to insertion to come after.", "Insert sequence.", MessageBoxButtons.OKCancel);
            }
            else if (markedSteps.Count == 1)
            {
                result = MessageBox.Show("This operation will insert a sequence into the currently open sequence, after the marked timestep.", "Insert Sequence.", MessageBoxButtons.OKCancel);
            }
            else
            {
                MessageBox.Show("There are " + markedSteps.Count + " marked timesteps. Please mark at most 1 timestep when using this feature.");
                return;
            }

            if (result == DialogResult.Cancel)
            {
                return;
            }

            SequenceData insertMe = Storage.SaveAndLoad.LoadSequenceWithFileDialog();
            if (insertMe != null)
            {

                bool insertAsTimestepGroup = false;

                insertAsTimestepGroup = (MessageBox.Show("Would you like a new Timestep Group to be created, and for all the inserted timesteps to be placed in that group?", "Insert as group?", MessageBoxButtons.YesNo) == DialogResult.Yes);
                TimestepGroup newGroup;
                if (insertAsTimestepGroup)
                {
                    MessageBox.Show("The inserted subsequence will be assigned to a new timestep group named Inserted Sequence.", "Inserting as a group.");
                    newGroup = new TimestepGroup("Inserted Sequence.");
                    Storage.sequenceData.TimestepGroups.Add(newGroup);
                    foreach (TimeStep step in insertMe.TimeSteps)
                    {
                        step.MyTimestepGroup = newGroup;
                    }
                }

                string response;

                bool dupAnalogs = false ;
                bool dupPulses = false;
                bool dupVariables=false;
                bool dupgpibs=false;
                bool duprs232s=false;
                bool dupTsGs = false;

                SequenceData seq = Storage.sequenceData;

                foreach (AnalogGroup ag in seq.AnalogGroups)
                {
                    foreach (AnalogGroup ag2 in insertMe.AnalogGroups)
                    {
                        if (ag.GroupName == ag2.GroupName)
                            dupAnalogs = true;
                    }
                }

                foreach (Pulse p1 in seq.DigitalPulses)
                    foreach (Pulse p2 in insertMe.DigitalPulses)
                        if (p1.PulseName == p2.PulseName)
                            dupPulses = true;

                foreach (Variable v1 in seq.Variables)
                    foreach (Variable v2 in insertMe.Variables)
                        if (!v1.IsSpecialVariable)
                            if (!v2.IsSpecialVariable)
                                if (v1.VariableName == v2.VariableName)
                                    dupVariables = true;

                foreach (GPIBGroup g1 in seq.GpibGroups)
                    foreach (GPIBGroup g2 in insertMe.GpibGroups)
                        if (g1.GroupName == g2.GroupName)
                            dupgpibs = true;

                foreach (RS232Group g1 in seq.RS232Groups)
                    foreach (RS232Group g2 in insertMe.RS232Groups)
                        if (g1.GroupName == g2.GroupName)
                            duprs232s = true;

                foreach (TimestepGroup tg1 in seq.TimestepGroups)
                    foreach (TimestepGroup tg2 in insertMe.TimestepGroups)
                        if (tg1.TimestepGroupName == tg2.TimestepGroupName)
                            dupTsGs = true;

                if (markedSteps.Count == 0)
                {
                    response = Storage.sequenceData.insertSequence(insertMe, 0);
                }
                else
                {
                    response = Storage.sequenceData.insertSequence(insertMe, markedSteps[0]);
                }

                if (response != null)
                {
                    MessageBox.Show(response);
                }

                if (dupAnalogs)
                    MessageBox.Show("The insertion operation has created duplicate Analog groups with identical names. To reduce confusion, it is recommended that the user now cleans these up.", "Analog Group duplicates detected.");
                if (dupgpibs)
                    MessageBox.Show("The insertion operation has created duplicate GPIB groups with identical names. To reduce confusion, it is recommended that the user now cleans these up.", "GPIB Group duplicates detected.");
                if (dupPulses)
                    MessageBox.Show("The insertion operation has created duplicate Pulses with identical names. To reduce confusion, it is recommended that the user now cleans these up.", "Pulse duplicates detected.");
                if (duprs232s)
                    MessageBox.Show("The insertion operation has created duplicate RS232 groups with identical names. To reduce confusion, it is recommended that the user now cleans these up.", "RS232 Group duplicates detected.");
                if (dupVariables)
                    MessageBox.Show("The insertion operation has created duplicate Variables with identical names. To reduce confusion, it is recommended that the user now cleans these up.", "Variable duplicates detected.");
                if (dupTsGs)
                    MessageBox.Show("The insertion operation has created duplicate Timestep Groups with identical names. To reduce confusion, it is recommended that the user now cleans these up.", "Timestep Group duplicates detected.");

                RefreshSequenceDataToUI(Storage.sequenceData);
            }
        }