public static void MassNeighborEqualize(Matter m1, Matter m2)
        {
            List<Matter> ms1 = new List<Matter>(), ms2 = new List<Matter>();

            //Create side by side list of applicable matter
            if (m1._myType.IsStackable)
                ms1.Add(m1);

            if (m2._myType.IsStackable)
                ms2.Add(m2);

            if (m1._myType.IsPermeable)
            {
                for (int i = 0; i < m1._myMixedContents.Count; i++)
                {
                    if (m1._myMixedContents[i]._myType.IsStackable)
                        ms1.Add(m1._myMixedContents[i]);
                }
            }

            if (m2._myType.IsPermeable)
            {
                for (int i = 0; i < m2._myMixedContents.Count; i++)
                {
                    if (m2._myMixedContents[i]._myType.IsStackable)
                        ms2.Add(m2._myMixedContents[i]);
                }
            }

            //Get Matches for simple equilibrium function and remove from old list
            List<Matter[]> matches = new List<Matter[]>();
            for (int i = 0; i < ms1.Count; i++)
            {
                var x = (from Matter tm2 in ms2
                         where ms1[i].TypeMatches(tm2)
                         select tm2).ToList<Matter>();

                if (x.Count == 0)
                    continue;

                if (x.Count > 1)
                    throw new Exception("Two matches?");

                if (ms1[i] == x[0])
                    throw new Exception("Unknown event by matching objects");

                if (Math.Abs(((1.0 * ms1[i].ElementUnits) / x[0].ElementUnits) - 1) > .001)
                    matches.Add(new Matter[] { ms1[i], x[0] });

                ms1.RemoveAt(i);
                i--;
                ms2.Remove(x[0]);
            }

            //FLow what is already matching
            for (int i = 0; i < matches.Count; i++)
            {
                int nmm1 = 0, nmm2 = 0;

                Chemistry.EquilibriumFunction(matches[i][0].ElementUnits, matches[i][1].ElementUnits, 1, 1, 1, out nmm1, out nmm2);

                matches[i][0].ElementUnits = nmm1;
                matches[i][1].ElementUnits = nmm2;
            }

            //Go through non matches
            if (m2._myType.IsPermeable)
            {
                for (int i = 0; i < ms1.Count; i++)
                {
                    int nmm1 = 0, nmm2 = 0;

                    Chemistry.EquilibriumFunction(ms1[i].ElementUnits, 0, 1, 1, 1, out nmm1, out nmm2);

                    if (nmm2 == 0)
                        continue;

                    //ms1[i]._elementMass = nmm1;
                    m2.AbsorbChunk(ms1[i].Split(nmm2));
                }
            }
            if (m1._myType.IsPermeable)
            {
                for (int i = 0; i < ms2.Count; i++)
                {
                    int nmm1 = 0, nmm2 = 0;

                    Chemistry.EquilibriumFunction(ms2[i].ElementUnits, 0, 1, 1, 1, out nmm1, out nmm2);

                    if (nmm2 == 0)
                        continue;

                    //ms2[i]._elementMass = nmm1;
                    m1.AbsorbChunk(ms2[i].Split(nmm2));
                }
            }
        }
            public virtual bool React(Matter m)
            {
                //Make sure matter is reactant, otherwise set reversed
                var reversed = false;
                if (this._reversible && m.TypeMatches(this._product))
                    reversed = true;

                //If not reversed and m does not equal reactant, throw exception
                if (!m.TypeMatches(this._reactant) && !reversed)
                    throw new Exception("Matter Object provided does not satisfy given conditions");

                //Get Probability of states
                var temp = 1.0 * m.ElementHeat / m.TotalMass;
                var parts = m.ElementUnits;
                if (temp == 0 || parts == 0)
                    return false;

                //Create Vars
                var muparts = 0;
                var muNparts = 0;
                Matter.ElementType toElement;

                //Handle Case If reversed for muEnergy
                if (reversed)
                {
                    muparts = this._product.Mu;
                    muNparts = this._reactant.Mu;
                    toElement = this._reactant;
                }
                else
                {
                    muparts = this._reactant.Mu;
                    muNparts = this._product.Mu;
                    toElement = this._product;
                }

                var reactKR = Math.Exp((muparts - (muNparts + this._activationEnergy)) / temp);

                if (parts == 0)
                {
                    int a = 7; int b = 3; int c = a / b;
                }

                parts--;
                var ReactionRate = temp * parts * reactKR;

                //If State is greater thanequalto one, then create x amount of new state
                if (ReactionRate > 1)// || StateMuNew >= 1)
                {
                    if (this._reactant.MyName == "DNA")
                    {
                        int a = 7; int b = 3; int c = a / b;
                    }

                    ///////////////////////
                    //Add DATA
                    if (m.Owner != null)
                        m.Owner.MySimulator.MyData.AddData("ReactionRate", ReactionRate);
                    else
                        m.MySimulator.MyData.AddData("ReactionRate", ReactionRate);
                    //////////////////////

                    var enDif = muparts - muNparts;
                    var amt = (int)ReactionRate;

                    if (enDif > 0 && enDif * amt > m.ElementHeat)
                        return false;

                    if (amt > parts)
                        amt = parts;
                    //var amt = (int)StateMuNew;
                    var newChunk = new Matter.MatterChunk(m, toElement, amt);

                    //Handle heat
                    if (enDif < 0)
                        m.ReleaseHeat(amt * Math.Abs(enDif));
                    else if (enDif > 0)
                        m.AbsorbHeat(amt * enDif);
                    else
                        throw new Exception("EnDif is zero or did not interact with environment");
                    var nm = m.AbsorbChunk(newChunk);

                    if (!m.NeedsRemoval && !m.IsRemoved)
                        Matter.HeatNeighborEqualize(nm, m);

                    if (m.IsElementEmpty())
                        m.DegenerateExistence();
                }

                return false;
            }