/// <summary>
        /// Copy Function
        /// </summary>
        /// <returns>new copy</returns>
        public IFunction ShallowCopy()
        {
            IFunction newAOF = new Function();
            foreach (Requirement aor in this.Requirements)
            {
                Requirement newAOR = new Requirement();
                newAOR.ChildOperator = aor.ChildOperator;
                newAOR.Operator = aor.Operator;
                newAOR.Statnumber = aor.Statnumber;
                newAOR.Target = aor.Target;
                newAOR.Value = aor.Value;
                newAOF.Requirements.Add(newAOR);
            }

            foreach (object ob in this.Arguments.Values)
            {
                if (ob.GetType() == typeof(string))
                {
                    string z = (string)ob;
                    newAOF.Arguments.Values.Add(z);
                }

                if (ob.GetType() == typeof(int))
                {
                    int i = (int)ob;
                    newAOF.Arguments.Values.Add(i);
                }

                if (ob.GetType() == typeof(Single))
                {
                    float s = (Single)ob;
                    newAOF.Arguments.Values.Add(s);
                }
            }

            newAOF.dolocalstats = this.dolocalstats;
            newAOF.FunctionType = this.FunctionType;
            newAOF.Target = this.Target;
            newAOF.TickCount = this.TickCount;
            newAOF.TickInterval = this.TickInterval;

            return newAOF;
        }
        /// <summary>
        /// The parse reqs.
        /// </summary>
        /// <param name="rreqs">
        /// The rreqs.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public List<Requirement> ParseReqs(List<rawreqs> rreqs)
        {
            int numreqs = rreqs.Count;

            List<Requirement> output = new List<Requirement>();
            Requirement aor = null;
            for (int i = 0; i < numreqs; i++)
            {
                rawreqs rr = rreqs[i];
                if (aor == null)
                {
                    aor = new Requirement();
                }

                aor.Target = ItemTarget.Self; // 0x13
                aor.Statnumber = rr.stat;
                aor.Operator = (Operator)Enum.ToObject(typeof(Operator), rr.ops);
                aor.Value = rr.val;
                aor.ChildOperator = Operator.Unknown;

                if ((i < numreqs - 1)
                    && (
                    (aor.Operator == Operator.OnTarget)
                    || (aor.Operator == Operator.OnSelf)
                    || (aor.Operator == Operator.OnUser)
                        || (aor.Operator == Operator.OnValidTarget)
                        || (aor.Operator == Operator.OnInvalidTarget)
                        || (aor.Operator == Operator.OnValidUser)
                        || (aor.Operator == Operator.OnInvalidUser)
                        || (aor.Operator == Operator.OnGeneralBeholder)
                        || (aor.Operator == Operator.OnCaster)
                        || (aor.Operator == Operator.Unknown2)))
                {
                    aor.Target = (ItemTarget)(int)aor.Operator;
                    i++;
                    rr = rreqs[i];
                    aor.Statnumber = rr.stat;
                    aor.Value = rr.val;
                    aor.Operator = (Operator)Enum.ToObject(typeof(Operator), rr.ops);
                }

                if (!((i >= numreqs - 1) || (numreqs == 2)))
                {
                    int anum = rreqs[i + 1].stat;
                    int aval = rreqs[i + 1].val;
                    int aop = rreqs[i + 1].ops;

                    if ((((aop == (int)Operator.Or) || (aop == (int)Operator.And)) || (aop == (int)Operator.Not)) || (anum == (int)Operator.EqualTo))
                    {
                        aor.ChildOperator = (Operator)Enum.ToObject(typeof(Operator), aop);
                        i++;
                    }
                }
                output.Add(aor);
                aor = null;
            }

            if (output.Count > 1)
            {
                output[0].ChildOperator = output[1].ChildOperator;
            }
            else
            {
                output[0].ChildOperator = Operator.Or;
            }
            /*output[0].ChildOperator = Operator.Or;
            for (int i = 0; i < output.Count - 2; i++)
            {
                output[i].ChildOperator = output[i + 1].ChildOperator;
            }*/

            return output;
        }
 /// <summary>
 /// </summary>
 /// <returns>
 /// </returns>
 public Requirement Copy()
 {
     Requirement copy = new Requirement();
     copy.Operator = this.Operator;
     copy.ChildOperator = this.ChildOperator;
     copy.Target = this.Target;
     copy.Statnumber = this.Statnumber;
     copy.Value = this.Value;
     return copy;
 }
        /// <summary>
        /// </summary>
        /// Methods to do:
        /// Read Item
        /// Write Item
        /// Return Dynel Item (placing on the ground)
        /// <returns>
        /// </returns>
        public NanoFormula ShallowCopy()
        {
            NanoFormula nanoFormula = new NanoFormula();
            nanoFormula.ID = this.ID;

            foreach (KeyValuePair<int, int> nanoFormulaAttribute in this.Attack)
            {
                nanoFormula.Attack.Add(nanoFormulaAttribute.Key, nanoFormulaAttribute.Value);
            }

            foreach (KeyValuePair<int, int> nanoFormulaAttribute in this.Defend)
            {
                nanoFormula.Defend.Add(nanoFormulaAttribute.Key, nanoFormulaAttribute.Value);
            }

            foreach (KeyValuePair<int, int> nanoFormulaAttribute in this.Stats)
            {
                nanoFormula.Stats.Add(nanoFormulaAttribute.Key, nanoFormulaAttribute.Value);
            }

            foreach (Event aoEvents in this.Events)
            {
                Event newEvent = new Event();
                foreach (Function aoFunctions in aoEvents.Functions)
                {
                    Function newAOFunctions = new Function();
                    foreach (Requirement aor in aoFunctions.Requirements)
                    {
                        Requirement newRequirement = new Requirement();
                        newRequirement.ChildOperator = aor.ChildOperator;
                        newRequirement.Operator = aor.Operator;
                        newRequirement.Statnumber = aor.Statnumber;
                        newRequirement.Target = aor.Target;
                        newRequirement.Value = aor.Value;
                        newAOFunctions.Requirements.Add(newRequirement);
                    }

                    foreach (object argument in aoFunctions.Arguments.Values)
                    {
                        if (argument.GetType() == typeof(string))
                        {
                            string z = (string)argument;
                            newAOFunctions.Arguments.Values.Add(z);
                        }

                        if (argument.GetType() == typeof(int))
                        {
                            int i = (int)argument;
                            newAOFunctions.Arguments.Values.Add(i);
                        }

                        if (argument.GetType() == typeof(Single))
                        {
                            float s = (Single)argument;
                            newAOFunctions.Arguments.Values.Add(s);
                        }
                    }

                    newAOFunctions.dolocalstats = aoFunctions.dolocalstats;
                    newAOFunctions.FunctionType = aoFunctions.FunctionType;
                    newAOFunctions.Target = aoFunctions.Target;
                    newAOFunctions.TickCount = aoFunctions.TickCount;
                    newAOFunctions.TickInterval = aoFunctions.TickInterval;
                    newEvent.Functions.Add(newAOFunctions);
                }

                newEvent.EventType = aoEvents.EventType;
                nanoFormula.Events.Add(newEvent);
            }

            nanoFormula.flags = this.flags;
            nanoFormula.Instance = this.Instance;
            nanoFormula.ItemType = this.ItemType;

            return nanoFormula;
        }
        /// <summary>
        /// </summary>
        /// <param name="rreqs">
        /// </param>
        /// <returns>
        /// </returns>
        public List<Requirement> ParseReqs(List<rawreqs> rreqs)
        {
            int numreqs = rreqs.Count;

            List<Requirement> output = new List<Requirement>();

            for (int i = 0; i < numreqs; i++)
            {
                rawreqs rr = rreqs[i];
                Requirement aor = new Requirement();

                aor.Target = ItemTarget.Self;
                aor.Statnumber = rr.stat;
                aor.Operator = (Operator)Enum.ToObject(typeof(Operator), rr.ops);
                aor.Value = rr.val;
                aor.ChildOperator = Operator.Unknown;

                if ((i < numreqs - 1)
                    && ((aor.Operator == Operator.OnTarget)
                    || (aor.Operator == Operator.OnSelf)
                    || (aor.Operator == Operator.OnUser)
                        || (aor.Operator == Operator.OnValidTarget)
                        || (aor.Operator == Operator.OnInvalidUser)
                        || (aor.Operator == Operator.OnValidUser)
                        || (aor.Operator == Operator.OnInvalidUser)
                        || (aor.Operator == Operator.OnGeneralBeholder)
                        || (aor.Operator == Operator.OnCaster)
                        || (aor.Operator == Operator.Unknown3)))
                {
                    aor.Target = (ItemTarget)Enum.ToObject(typeof(ItemTarget), aor.Operator);
                    i++;
                    rr = rreqs[i];
                    aor.Statnumber = rr.stat;
                    aor.Value = rr.val;
                    aor.Operator = (Operator)Enum.ToObject(typeof(Operator), rr.ops);
                }

                if (!((i >= numreqs - 1) || (numreqs == 2)))
                {
                    int anum = rreqs[i + 1].stat;
                    int aval = rreqs[i + 1].val;
                    int aop = rreqs[i + 1].ops;

                    if ((((aop == 3) || (aop == 4)) || (aop == 0x2a)) && (anum == 0))
                    {
                        aor.ChildOperator = (Operator)Enum.ToObject(typeof(Operator), aop);
                        i++;
                    }
                }

                output.Add(aor);
            }

            for (int i = 0; i < output.Count - 2; i++)
            {
                output[i].ChildOperator = output[i + 1].ChildOperator;
            }

            return output;
        }
 /// <summary>
 /// </summary>
 /// <param name="requirements">
 /// </param>
 /// <returns>
 /// </returns>
 internal static Func<IInstancedEntity, bool> Create(Requirement requirements)
 {
     return
         BuildExpression(
             (ItemTarget)requirements.Target,
             (Operator)requirements.Operator,
             requirements.Statnumber,
             requirements.Value).Compile();
 }