Example #1
0
        /// <summary>
        /// Remove a linked parameter from the linked parameters
        /// </summary>
        /// <param name="linkedParameter">The linked parameter to remove</param>
        /// <param name="error">If an error occurs this will contain a message to describe it.</param>
        /// <returns>If the command was successful or not.</returns>
        public bool RemoveLinkedParameter(LinkedParameterModel linkedParameter, ref string error)
        {
            var lp = new LinkedParameterChange();

            return(this.Session.RunCommand(
                       XTMFCommand.CreateCommand((ref string e) =>
            {
                if ((lp.Index = this.LinkedParameters.IndexOf(linkedParameter)) < 0)
                {
                    e = "The linked parameter was not found!";
                    return false;
                }
                lp.Model = this.LinkedParameters[lp.Index];
                LinkedParameters.RemoveAt(lp.Index);
                RealLinkedParameters.RemoveAt(lp.Index);
                return true;
            },
                                                 (ref string e) =>
            {
                LinkedParameters.Insert(lp.Index, lp.Model);
                RealLinkedParameters.Insert(lp.Index, lp.Model.RealLinkedParameter);
                return true;
            },
                                                 (ref string e) =>
            {
                LinkedParameters.RemoveAt(lp.Index);
                RealLinkedParameters.RemoveAt(lp.Index);
                return true;
            }),
                       ref error
                       ));
        }
        public bool RunCommand(XTMFCommand command, ref string error)
        {
            lock (_SessionLock)
            {
                if (command.Do(ref error))
                {
                    HasChanged = true;
                    if (_InCombinedContext)
                    {
                        var list = _CombinedCommands;
                        list.Add(command);
                    }
                    else
                    {
                        if (command.CanUndo())
                        {
                            _UndoStack.Add(command);
                        }

                        CommandExecuted?.Invoke(this, new EventArgs());
                    }

                    // if we do something new, redo no long is available
                    _RedoStack.Clear();
                    return(true);
                }

                return(false);
            }
        }
Example #3
0
        /// <summary>
        /// Create a new Linked Parameter with the given name
        /// </summary>
        /// <param name="name">The name of the linked parameter</param>
        /// <param name="error">If an error occurs this will contain a message to describe it.</param>
        /// <returns>True if it executed successfully</returns>
        public bool NewLinkedParameter(string name, ref string error)
        {
            var lp = new LinkedParameterChange();

            return(_Session.RunCommand(
                       XTMFCommand.CreateCommand("New Linked Parameter", (ref string e) =>
            {
                LinkedParameter linkedParameter = new LinkedParameter(name);
                LinkedParameterModel newModel = new LinkedParameterModel(linkedParameter, _Session, _ModelSystem);
                _RealLinkedParameters.Add(linkedParameter);
                LinkedParameters.Add(newModel);
                lp.Model = newModel;
                lp.Index = LinkedParameters.Count - 1;
                return true;
            },
                                                 (ref string e) =>
            {
                LinkedParameters.RemoveAt(lp.Index);
                _RealLinkedParameters.RemoveAt(lp.Index);
                InvokeRemoved(lp);
                return true;
            },
                                                 (ref string e) =>
            {
                LinkedParameters.Insert(lp.Index, lp.Model);
                _RealLinkedParameters.Insert(lp.Index, lp.Model.RealLinkedParameter);
                return true;
            }),
                       ref error
                       ));
        }
Example #4
0
        /// <summary>
        /// Removes a parameter from this linked parameter
        /// </summary>
        /// <param name="toRemove">The parameter to remove</param>
        /// <param name="error">An error message if this is not possible</param>
        /// <returns>True if the parameter was removed, false if it was not.</returns>
        public bool RemoveParameter(ParameterModel toRemove, ref string error)
        {
            LinkedParameterChange change = new LinkedParameterChange();

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          // do
                                          (ref string e) =>
            {
                // we need this outer lock to make sure that it doesn't change while we are checking to make sure that it is contained
                lock (ParameterModelsLock)
                {
                    if (!ParameterModels.Contains(toRemove))
                    {
                        e = "The parameter does not exist inside of the linked parameter!";
                        return false;
                    }
                    change.Index = NoCommandRemove(toRemove);
                }
                return true;
            },
                                          // undo
                                          (ref string e) =>
            {
                return NoCommandAdd(toRemove, change.Index, ref e);
            },
                                          // redo
                                          (ref string e) =>
            {
                NoCommandRemove(toRemove);
                return true;
            }
                                          ), ref error));
        }
Example #5
0
        /// <summary>
        /// Attempts to set the value of the parameter to the new given value
        /// </summary>
        /// <param name="newValue">The value to change the parameter to</param>
        /// <param name="error">If the value is invalid this will contain a message as to why.</param>
        /// <returns>True if the parameter was set to the new value, false otherwise with an error message in error.</returns>
        public bool SetValue(string newValue, ref string error)
        {
            ParameterChange change = new ParameterChange();

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          // do
                                          ((ref string e) =>
            {
                // Check to see if we are in a linked parameter
                change.ContainedIn = Session.ModelSystemModel.LinkedParameters.GetContained(this);
                if (change.ContainedIn == null)
                {
                    change.NewValue = newValue;
                    change.OldValue = _Value;
                    if (!ArbitraryParameterParser.Check(RealParameter.Type, change.NewValue, ref e))
                    {
                        return false;
                    }
                    Value = change.NewValue;
                }
                else
                {
                    change.NewValue = newValue;
                    change.OldValue = change.ContainedIn.GetValue();
                    return change.ContainedIn.SetWithoutCommand(change.NewValue, ref e);
                }
                return true;
            }),
                                          // undo
                                          (ref string e) =>
            {
                if (change.ContainedIn == null)
                {
                    Value = change.OldValue;
                }
                else
                {
                    return change.ContainedIn.SetWithoutCommand(change.OldValue, ref e);
                }
                return true;
            },
                                          // redo
                                          (ref string e) =>
            {
                if (change.ContainedIn == null)
                {
                    Value = change.NewValue;
                }
                else
                {
                    return change.ContainedIn.SetWithoutCommand(change.NewValue, ref e);
                }
                return true;
            }
                                          ), ref error));
        }
Example #6
0
        /// <summary>
        /// Add a new collection member to a collection using the given type
        /// </summary>
        /// <param name="type">The type to add</param>
        /// <param name="name">The name to use, pass a null to automatically name the module</param>
        public bool AddCollectionMember(Type type, ref string error, string name = null)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (!IsCollection)
            {
                throw new InvalidOperationException("You can not add collection members to a module that is not a collection!");
            }

            CollectionChangeData data = new CollectionChangeData();

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          (ref string e) =>
            {
                if (!ValidateType(type, ref e))
                {
                    return false;
                }
                if (RealModelSystemStructure.IsCollection)
                {
                    RealModelSystemStructure.Add(RealModelSystemStructure.CreateCollectionMember(name == null ? CreateNameFromType(type) : name, type));
                }
                else
                {
                    RealModelSystemStructure.Add(name == null ? CreateNameFromType(type) : name, type);
                }
                data.Index = RealModelSystemStructure.Children.Count - 1;
                data.StructureInQuestion = RealModelSystemStructure.Children[data.Index] as ModelSystemStructure;
                if (Children == null)
                {
                    Children = new ObservableCollection <ModelSystemStructureModel>();
                }
                Children.Add(data.ModelInQuestion = new ModelSystemStructureModel(Session, data.StructureInQuestion));
                return true;
            },
                                          (ref string e) =>
            {
                Children.RemoveAt(data.Index);
                RealModelSystemStructure.Children.RemoveAt(data.Index);
                return true;
            },
                                          (ref string e) =>
            {
                Children.Insert(data.Index, data.ModelInQuestion);
                RealModelSystemStructure.Children.Insert(data.Index, data.StructureInQuestion);
                return true;
            }),
                                      ref error));
        }
        public void ExecuteCombinedCommands(string name, Action combinedCommandContext)
        {
            lock (_SessionLock)
            {
                _InCombinedContext = true;
                var list = _CombinedCommands = new List <XTMFCommand>();
                combinedCommandContext();
                // only add to the undo list if a command was added successfully
                if (list.Count > 0)
                {
                    // create a command to undo everything in a single shot [do is empty]
                    _UndoStack.Add(XTMFCommand.CreateCommand(name, (ref string error) => { return(true); },
                                                             (ref string error) =>
                    {
                        foreach (var command in ((IEnumerable <XTMFCommand>)list).Reverse())
                        {
                            if (command.CanUndo())
                            {
                                if (!command.Undo(ref error))
                                {
                                    return(false);
                                }
                            }
                        }

                        return(true);
                    },
                                                             (ref string error) =>
                    {
                        foreach (var command in list)
                        {
                            if (command.CanUndo())
                            {
                                if (!command.Redo(ref error))
                                {
                                    return(false);
                                }
                            }
                        }

                        return(true);
                    }));
                    CommandExecuted?.Invoke(this, new EventArgs());
                }

                _InCombinedContext = false;
                _CombinedCommands  = null;
            }
        }
Example #8
0
        /// <summary>
        /// Add a new parameter to this linked parameter
        /// </summary>
        /// <param name="toAdd">The parameter to add</param>
        /// <param name="error">This contains an error message if this returns false</param>
        /// <returns>True if we added the parameter to the linked parameter, false if it failed.</returns>
        public bool AddParameter(ParameterModel toAdd, ref string error)
        {
            LinkedParameterChange change = new LinkedParameterChange();
            var originalValue            = toAdd.Value;

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          // do
                                          (ref string e) =>
            {
                if (ParameterModels.Contains(toAdd))
                {
                    e = "The parameter was already contained in the linked parameter!";
                    return false;
                }
                // remove from the linked parameter it was already in
                if ((change.OriginalContainedIn = ModelSystem.LinkedParameters.LinkedParameters.FirstOrDefault((lp) => lp.Contains(toAdd))) != null)
                {
                    change.OriginalIndex = change.OriginalContainedIn.NoCommandRemove(toAdd);
                }
                NoCommandAdd(toAdd, (change.Index = ParameterModels.Count));
                return true;
            },
                                          // undo
                                          (ref string e) =>
            {
                NoCommandRemove(toAdd);
                if (change.OriginalContainedIn != null)
                {
                    change.OriginalContainedIn.NoCommandAdd(toAdd, change.OriginalIndex);
                }
                else
                {
                    // if it isn't part of another linked parameter just add the value back
                    toAdd.SetValue(originalValue, ref e);
                }
                return true;
            },
                                          // redo
                                          (ref string e) =>
            {
                if (change.OriginalContainedIn != null)
                {
                    change.OriginalContainedIn.NoCommandRemove(toAdd);
                }
                NoCommandAdd(toAdd, change.Index);
                return true;
            }
                                          ), ref error));
        }
Example #9
0
        public void TestEditingStackOperations()
        {
            var commands = new XTMFCommand[20];

            for (int i = 0; i < commands.Length; i++)
            {
                commands[i] = new TestCommand();
            }
            EditingStack stack = new EditingStack(10);

            Assert.AreEqual(0, stack.Count, "The stack's count is incorrect!");
            // fill the stack
            for (int i = 0; i < 10; i++)
            {
                stack.Add(commands[i]);
                Assert.AreEqual(i + 1, stack.Count, "The stack's count is incorrect!");
            }
            // over fill the stack
            for (int i = 10; i < 20; i++)
            {
                stack.Add(commands[i]);
                Assert.AreEqual(10, stack.Count, "The stack's count is incorrect!");
            }
            // Make sure the first don't exist anymore
            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(false, stack.Contains(commands[i]), "The stack retained a command it should have lost!");
            }
            // Make sure the newer ones still exist
            for (int i = 10; i < 20; i++)
            {
                Assert.AreEqual(true, stack.Contains(commands[i]), "The stack lost a command it should have retained!");
            }
            XTMFCommand command;

            for (int i = 19; i >= 10; i--)
            {
                if (stack.TryPop(out command))
                {
                    Assert.AreEqual(commands[i], command, "While popping we popped an unexpected command!");
                }
                else
                {
                    Assert.Fail("A pop failed that should have succeeded!");
                }
            }
        }
Example #10
0
        public bool RemoveAllCollectionMembers(ref string error)
        {
            if (!IsCollection)
            {
                throw new InvalidOperationException("You can not add collection members to a module that is not a collection!");
            }
            IList <ModelSystemStructureModel> oldChildren     = null;
            IList <IModelSystemStructure>     oldRealChildren = null;

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          (ref string e) =>
            {
                if (RealModelSystemStructure.Children == null || RealModelSystemStructure.Children.Count <= 0)
                {
                    e = "There were no modules to delete in the collection!";
                    return false;
                }
                oldRealChildren = RealModelSystemStructure.Children.ToList();
                RealModelSystemStructure.Children.Clear();
                oldChildren = Children.ToList();
                Children.Clear();
                return true;
            },
                                          (ref string e) =>
            {
                foreach (var child in oldChildren)
                {
                    Children.Add(child);
                }
                var realChildList = RealModelSystemStructure.Children;
                if (oldRealChildren != null)
                {
                    foreach (var child in oldRealChildren)
                    {
                        realChildList.Add(child);
                    }
                }
                return true;
            },
                                          (ref string e) =>
            {
                RealModelSystemStructure.Children.Clear();
                Children.Clear();
                return true;
            }),
                                      ref error));
        }
Example #11
0
        /// <summary>
        /// Removes a collection member at the given index
        /// </summary>
        /// <param name="index">The index to remove from.</param>
        /// <param name="error">If an error happens it will contain a text representation of the error.</param>
        /// <returns>If the index was able to be removed</returns>
        /// <exception cref="InvalidOperationException">This operation is only allowed on Collections.</exception>
        public bool RemoveCollectionMember(int index, ref string error)
        {
            if (index < 0)
            {
                throw new InvalidOperationException("Indexes must be greater than or equal to zero!");
            }

            if (!IsCollection)
            {
                throw new InvalidOperationException("You can not add collection members to a module that is not a collection!");
            }
            CollectionChangeData data = new CollectionChangeData();

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          (ref string e) =>
            {
                var children = RealModelSystemStructure.Children;
                if (children.Count <= index)
                {
                    e = "There is no collection member at index " + index + "!";
                    return false;
                }
                data.Index = index;
                data.StructureInQuestion = RealModelSystemStructure.Children[data.Index] as ModelSystemStructure;
                data.ModelInQuestion = Children[data.Index];
                RealModelSystemStructure.Children.RemoveAt(data.Index);
                Children.RemoveAt(data.Index);
                ModelHelper.PropertyChanged(PropertyChanged, this, "Children");
                return true;
            },
                                          (ref string e) =>
            {
                RealModelSystemStructure.Children.Insert(data.Index, data.StructureInQuestion);
                Children.Insert(data.Index, data.ModelInQuestion);
                ModelHelper.PropertyChanged(PropertyChanged, this, "Children");
                return true;
            },
                                          (ref string e) =>
            {
                RealModelSystemStructure.Children.RemoveAt(data.Index);
                Children.RemoveAt(data.Index);
                ModelHelper.PropertyChanged(PropertyChanged, this, "Children");
                return true;
            }),
                                      ref error));
        }
Example #12
0
        public bool MoveChild(int originalPosition, int newPosition, ref string error)
        {
            if (!IsCollection)
            {
                error = "You can only move the children of a collection!";
                return(false);
            }
            MoveChildData move = new MoveChildData();

            return(Session.RunCommand(
                       XTMFCommand.CreateCommand(
                           // do
                           (ref string e) =>
            {
                move.OriginalPosition = originalPosition;
                move.NewPosition = newPosition;
                if (originalPosition < 0 | originalPosition >= Children.Count)
                {
                    e = "The original position was invalid!";
                    return false;
                }
                if (newPosition < 0 | newPosition >= Children.Count)
                {
                    e = "The destination position was invalid!";
                    return false;
                }
                Move(originalPosition, newPosition);
                return true;
            },
                           // undo
                           (ref string e) =>
            {
                Move(newPosition, originalPosition);
                return true;
            },
                           // redo
                           (ref string e) =>
            {
                Move(originalPosition, newPosition);
                return true;
            }
                           ), ref error));
        }
Example #13
0
 /// <summary>
 /// Sets the name of the linked parameter
 /// </summary>
 /// <param name="newName">The desired new name</param>
 /// <param name="error">A message describing why the operation failed.</param>
 /// <returns>True if the name was changed, false otherwise.</returns>
 public bool SetName(string newName, ref string error)
 {
     lock (ParameterModelsLock)
     {
         string oldName = RealLinkedParameter.Name;
         return(Session.RunCommand(XTMFCommand.CreateCommand((ref string e) =>
         {
             RealLinkedParameter.Name = newName;
             return true;
         },
                                                             (ref string e) =>
         {
             RealLinkedParameter.Name = oldName;
             return true;
         },
                                                             (ref string e) =>
         {
             RealLinkedParameter.Name = newName;
             return true;
         }), ref error));
     }
 }
Example #14
0
        public bool SetName(string newName, ref string error)
        {
            var oldName = "";

            return(Session.RunCommand(XTMFCommand.CreateCommand((ref string e) =>
            {
                oldName = this.RealModelSystemStructure.Name;
                this.RealModelSystemStructure.Name = newName;
                ModelHelper.PropertyChanged(PropertyChanged, this, "Name");
                return true;
            }, (ref string e) =>
            {
                this.RealModelSystemStructure.Name = oldName;
                ModelHelper.PropertyChanged(PropertyChanged, this, "Name");
                return true;
            },
                                                                (ref string e) =>
            {
                this.RealModelSystemStructure.Name = newName;
                ModelHelper.PropertyChanged(PropertyChanged, this, "Name");
                return true;
            }), ref error));
        }
Example #15
0
 public bool RunCommand(XTMFCommand command, ref string error)
 {
     lock (SessionLock)
     {
         if (_IsRunning)
         {
             error = "You can not edit a model system while it is running.";
             return(false);
         }
         if (command.Do(ref error))
         {
             HasChanged = true;
             if (command.CanUndo())
             {
                 UndoStack.Add(command);
             }
             // if we do something new, redo no long is available
             RedoStack.Clear();
             return(true);
         }
         return(false);
     }
 }
Example #16
0
        /// <summary>
        /// This will set the value of the linked parameter and all contained parameter to the given value
        /// </summary>
        /// <param name="newValue">The value to set it to.</param>
        /// <param name="error">Contains a message in case of an error.</param>
        /// <returns>True if successful, false in case of failure.</returns>
        public bool SetValue(string newValue, ref string error)
        {
            string oldValue = RealLinkedParameter.Value;

            return(Session.RunCommand(
                       XTMFCommand.CreateCommand(
                           // do
                           (ref string e) =>
            {
                return SetWithoutCommand(newValue, ref e);
            },
                           // undo
                           (ref string e) =>
            {
                return SetWithoutCommand(oldValue, ref e);
            },
                           // redo
                           (ref string e) =>
            {
                return SetWithoutCommand(newValue, ref e);
            })
                       , ref error));
        }
Example #17
0
 public CommandDisplayModel(XTMFCommand command)
 {
     Command = command;
     Name    = command.Name;
 }
Example #18
0
        public bool Paste(string buffer, ref string error)
        {
            ModelSystemStructure       copiedStructure;
            List <TempLinkedParameter> linkedParameters;

            // Get the data
            using (MemoryStream backing = new MemoryStream())
            {
                StreamWriter writer = new StreamWriter(backing);
                writer.Write(buffer);
                writer.Flush();
                backing.Position = 0;

                try
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(backing);
                    copiedStructure  = GetModelSystemStructureFromXML(doc["CopiedModule"]["CopiedModules"]);
                    linkedParameters = GetLinkedParametersFromXML(doc["CopiedModule"]["LinkedParameters"]);
                }
                catch (Exception e)
                {
                    error = "Unable to decode the copy buffer.\r\n" + e.Message;
                    return(false);
                }
            }
            if (copiedStructure.IsCollection)
            {
                if (!IsCollection)
                {
                    error = "The copied model system is not pasteable at this location.";
                    return(false);
                }
                foreach (var child in copiedStructure.Children)
                {
                    if (!IsAssignable(Session.ModelSystemModel.Root.RealModelSystemStructure,
                                      IsCollection ? RealModelSystemStructure : Session.GetParent(this).RealModelSystemStructure, child as ModelSystemStructure))
                    {
                        error = "The copied model system is not pasteable at this location.";
                        return(false);
                    }
                }
            }
            else
            {
                // validate the modules contained
                if (!IsAssignable(Session.ModelSystemModel.Root.RealModelSystemStructure,
                                  IsCollection ? RealModelSystemStructure : Session.GetParent(this).RealModelSystemStructure, copiedStructure))
                {
                    error = "The copied model system is not pasteable at this location.";
                    return(false);
                }
            }
            List <LinkedParameterModel> newLinkedParameters = new List <LinkedParameterModel>();
            var additions = new List <Tuple <ParameterModel, LinkedParameterModel> >();
            var oldReal   = RealModelSystemStructure;

            return(Session.RunCommand(XTMFCommand.CreateCommand(
                                          (ref string e) =>
            {
                ModelSystemStructureModel beingAdded;
                int indexOffset = 0;
                if (IsCollection)
                {
                    if (copiedStructure.IsCollection)
                    {
                        indexOffset = RealModelSystemStructure.Children != null ? RealModelSystemStructure.Children.Count : 0;
                        foreach (var child in copiedStructure.Children)
                        {
                            RealModelSystemStructure.Add(child);
                        }
                        UpdateChildren();
                        beingAdded = this;
                    }
                    else
                    {
                        RealModelSystemStructure.Add(copiedStructure);
                        UpdateChildren();
                        beingAdded = Children[Children.Count - 1];
                    }
                }
                else
                {
                    var modelSystemRoot = Session.ModelSystemModel.Root.RealModelSystemStructure;
                    // if we are the root of the model system
                    if (modelSystemRoot == RealModelSystemStructure)
                    {
                        copiedStructure.Required = RealModelSystemStructure.Required;
                        copiedStructure.ParentFieldType = RealModelSystemStructure.ParentFieldType;
                        copiedStructure.ParentFieldName = RealModelSystemStructure.ParentFieldName;
                        Session.ModelSystemModel.Root.RealModelSystemStructure = copiedStructure;
                    }
                    else
                    {
                        var parent = ModelSystemStructure.GetParent(modelSystemRoot, RealModelSystemStructure);
                        var index = parent.Children.IndexOf(RealModelSystemStructure);
                        copiedStructure.Required = RealModelSystemStructure.Required;
                        copiedStructure.ParentFieldType = RealModelSystemStructure.ParentFieldType;
                        copiedStructure.ParentFieldName = RealModelSystemStructure.ParentFieldName;
                        RealModelSystemStructure = copiedStructure;
                        parent.Children[index] = copiedStructure;
                    }
                    UpdateAll();
                    beingAdded = this;
                }
                var linkedParameterModel = Session.ModelSystemModel.LinkedParameters;
                var realLinkedParameters = linkedParameterModel.GetLinkedParameters();
                var missing = from lp in linkedParameters
                              where !realLinkedParameters.Any(rlp => rlp.Name == lp.Name)
                              select lp;
                var matching = linkedParameters.Join(realLinkedParameters, (p) => p.Name, (p) => p.Name, (t, r) => new { Real = r, Temp = t });
                // add links for the ones we've matched
                foreach (var lp in matching)
                {
                    foreach (var containedParameters in GetParametersFromTemp(lp.Temp, beingAdded, indexOffset))
                    {
                        lp.Real.AddParameterWithoutCommand(containedParameters);
                        containedParameters.SignalIsLinkedChanged();
                        additions.Add(new Tuple <ParameterModel, LinkedParameterModel>(containedParameters, lp.Real));
                    }
                }
                // add links for the ones that didn't match
                foreach (var missingLp in missing)
                {
                    var newLP = linkedParameterModel.AddWithoutCommand(missingLp.Name, missingLp.Value);
                    newLinkedParameters.Add(newLP);
                    foreach (var containedParameters in GetParametersFromTemp(missingLp, beingAdded, indexOffset))
                    {
                        newLP.AddParameterWithoutCommand(containedParameters);
                        containedParameters.SignalIsLinkedChanged();
                    }
                }
                return true;
            },
                                          (ref string e) =>
            {
                if (IsCollection)
                {
                    if (copiedStructure.IsCollection)
                    {
                        foreach (var child in copiedStructure.Children)
                        {
                            RealModelSystemStructure.Children.Remove(child);
                        }
                    }
                    else
                    {
                        RealModelSystemStructure.Children.Remove(copiedStructure);
                    }
                    UpdateChildren();
                }
                else
                {
                    var modelSystemRoot = Session.ModelSystemModel.Root.RealModelSystemStructure;
                    // if we are the root of the model system
                    if (modelSystemRoot == RealModelSystemStructure)
                    {
                        RealModelSystemStructure = oldReal;
                        Session.ModelSystemModel.Root.RealModelSystemStructure = oldReal;
                    }
                    else
                    {
                        var parent = ModelSystemStructure.GetParent(Session.ModelSystemModel.Root.RealModelSystemStructure, RealModelSystemStructure);
                        var index = parent.Children.IndexOf(RealModelSystemStructure);
                        RealModelSystemStructure = oldReal;
                        parent.Children[index] = RealModelSystemStructure;
                    }
                    UpdateAll();
                }
                var linkedParameterModel = Session.ModelSystemModel.LinkedParameters;
                foreach (var newLP in newLinkedParameters)
                {
                    linkedParameterModel.RemoveWithoutCommand(newLP);
                }
                foreach (var addition in additions)
                {
                    addition.Item2.RemoveParameterWithoutCommand(addition.Item1);
                }
                return true;
            },
                                          (ref string e) =>
            {
                if (IsCollection)
                {
                    if (copiedStructure.IsCollection)
                    {
                        foreach (var child in copiedStructure.Children)
                        {
                            RealModelSystemStructure.Add(child);
                        }
                    }
                    else
                    {
                        RealModelSystemStructure.Add(copiedStructure);
                    }
                    UpdateChildren();
                }
                else
                {
                    var modelSystemRoot = Session.ModelSystemModel.Root.RealModelSystemStructure;
                    // if we are the root of the model system
                    if (modelSystemRoot == RealModelSystemStructure)
                    {
                        RealModelSystemStructure = copiedStructure;
                        Session.ModelSystemModel.Root.RealModelSystemStructure = RealModelSystemStructure;
                    }
                    else
                    {
                        var parent = ModelSystemStructure.GetParent(Session.ModelSystemModel.Root.RealModelSystemStructure, RealModelSystemStructure);
                        var index = parent.Children.IndexOf(RealModelSystemStructure);
                        RealModelSystemStructure = copiedStructure;
                        parent.Children[index] = RealModelSystemStructure;
                    }
                    UpdateAll();
                }
                var linkedParameterModel = Session.ModelSystemModel.LinkedParameters;
                foreach (var newLP in newLinkedParameters)
                {
                    linkedParameterModel.AddWithoutCommand(newLP);
                }
                foreach (var addition in additions)
                {
                    addition.Item2.AddParameterWithoutCommand(addition.Item1);
                }
                return true;
            }), ref error));
        }