//TODO : this stuff seems too complex. Make it look simler.
        private void Functions_CollectionChanged(object sender, NotifyCollectionChangingEventArgs e)
        {
            var function = (IFunction)e.Item;

            switch (e.Action)
            {
            case NotifyCollectionChangeAction.Add:

                FunctionValues.Add(null);
                /* Get the components of a function. Not of variables */
                if (!(function is IVariable))
                {
                    foreach (IVariable component in function.Components)
                    {
                        if (Functions.Contains(component))
                        {
                            continue;
                        }
                        Functions.Add(component);
                    }
                }

                foreach (IVariable argument in function.Arguments)
                {
                    if (argument.Store != this)
                    {
                        if (Functions.Contains(argument))
                        {
                            continue;
                        }
                        Functions.Add(argument);
                    }
                }

                if (function is IVariable)
                {
                    var variable = (IVariable)function;

                    var variableValues = variable.FixedSize == 0 ? null : variable.Values;

                    // avoid unnecessary calls for better performance
                    var array = (variableValues == null || variableValues.Count == 0)
                            ? variable.CreateStorageArray()
                            : variable.CreateStorageArray(variable.Values);

                    FunctionValues[e.Index] = array;

                    variable.CachedValues = array;

                    SubscribeToArray(array);

                    // register all variables which for the newly added is an argument
                    IEnumerable <IFunction> dependendFunctions =
                        functions.Where(f => f.Arguments.Contains(variable) && f is IVariable);
                    foreach (IVariable dependentVariable in dependendFunctions)
                    {
                        //DependentVariables[variable].Add(dependentVariable);
                        UpdateVariableSize(dependentVariable);
                    }
                }

                function.Store = this;

                break;

            case NotifyCollectionChangeAction.Remove:

                IMultiDimensionalArray multiDimensionalArray = FunctionValues[e.Index];
                UnsubscribeFromArray(multiDimensionalArray);

                FunctionValues.RemoveAt(e.Index);

                //evict the function from the store. Reset arguments and components list to prevent synchronization.

                function.Arguments  = new EventedList <IVariable>();
                function.Components = new EventedList <IVariable>();
                function.Store      = null;

                //IFunctionStore newStore = new MemoryFunctionStore();
                //newStore.Functions.Add(function);
                break;

            case NotifyCollectionChangeAction.Replace:
                throw new NotSupportedException();
            }
            UpdateAutoSortOnArrays();
            UpdateDependentVariables();
        }