/// <summary>
        /// Runs the perturb-and-observe experiment.
        /// </summary>
        public void RunPerturbAndObserve()
        {
            controller.NetworkFilename = NetworkFilename;
            controller.ClearNetworkCache();
            controller.CacheNetwork     = true;
            controller.ExperimentDriver = null;
            //hook this in here so we can capture the no-change state.
            var observeTransform = new ObserveResultsTransform <TObserve>(ObserveElementSelector, ObserveElementValuesSelector);

            controller.ResultsTransformer = observeTransform;
            controller.Execute();

            BeforeValues = observeTransform.WatchedElements;
            var afterValues = new Dictionary <Tuple <IDTypePair, Object>, Dictionary <IDTypePair, TObserve> >();

            var experimentor = new StringFormatExperimentor();

            controller.ExperimentDriver     = experimentor;
            experimentor.ExperimentCommands = PerturbCommands;

            foreach (var elem in PerturbElementSelector(controller.Network))
            {
                var perturbValues = PerturbElementValuesSelector(elem);
                experimentor.ExperimentValues = perturbValues;
                controller.Execute();
                afterValues[Tuple.Create(new IDTypePair(elem.ID, elem.GetType()), PerturbValuesToRecord(perturbValues))]
                    = observeTransform.WatchedElements;
            }
            AfterValues = afterValues;
        }