private WitnessList FindBestMatchInPartialList(ref WitnessList newWitnessList)
        {
            var total = newWitnessList.FullMergeWintess.Count;
            var parList = newWitnessList.PartialMergeWitness;
            WitnessList revList = new WitnessList();//ref wintessList);
            if (total == 1)
                newWitnessList.addToPartialMerge(newWitnessList.FullMergeWintess[0]);

            for (int i = 0; i < parList.Count; i++)
            {
                for (int j = i + 1; j < parList.Count; j++)
                {
                    var revTempWitnesList = ConstraintMatching(parList[i], parList[j], true);

                    if (revTempWitnesList.FullMergeWintess.Count > 0)
                    {
                        var W1RecordLen = parList[i].GetWitnessRecordItems().Count;
                        var W2RecordLen = parList[j].GetWitnessRecordItems().Count;
                        var revRecordLen = revTempWitnesList.FullMergeWintess[0].GetWitnessRecordItems().Count;

                        if (!((revRecordLen > W1RecordLen) && (revRecordLen > W2RecordLen)))
                        {
                            revList.addToPartialMerge(parList[i]);
                            revList.addToPartialMerge(parList[j]);
                        }
                        else
                            revList.addToFullMerge(revTempWitnesList.FullMergeWintess[0]);

                    }
                    else
                    {
                        if (revTempWitnesList.PartialMergeWitness.Count > 0)
                        {
                            foreach (var record in revTempWitnesList.PartialMergeWitness)
                            {
                                revList.addToPartialMerge(record);
                            }
                        }
                    }

                }
            }
            if (revList.FullMergeWintess.Count > 1)
            {
                foreach(var record in revList.FullMergeWintess)
                {
                    revList.addToPartialMerge(record);
                }
                revList.FullMergeWintess.Clear();

            }

            return revList;
        }
        protected WitnessList ConstraintMatching(WitnessRecord WitnessOne, WitnessRecord WitnessTwo, bool bIgnoreIfSplit)
        {
            WitnessList newWitnessList = new WitnessList(ref wintessList);

            List<string> newRecordItems = new List<string>();
            List<string> subWitnessitems = null;
            bool bSplit = false;
            int iLastVistedPos = 0;
            string lastMatchdString = string.Empty;
            try
            {
                foreach (var WOneRecordItem in WitnessOne.GetWitnessRecordItems())
                {

                    string witnessItem_W1 = WOneRecordItem.getWitness();
                    bool bFirstItem_W1 = WOneRecordItem.IsFirstItem;
                    bool bLastItem_W1 = WOneRecordItem.isLastItem;
                    bool bNextItem_W1 = false;
                    int ItemIndex;

                    if (!bFirstItem_W1 && !bLastItem_W1)
                        bNextItem_W1 = true;

                    bool bItemMatched = isItemMatched(witnessItem_W1, WitnessTwo, out ItemIndex);

                    var WitnessTwoItemsList = WitnessTwo.GetWitnessRecordItems();
                    if (bItemMatched)
                    {
                        int stPos = WitnessTwo.LastVistedItem + 1;

                        var WitnessTwoItems = WitnessTwoItemsList[ItemIndex];
                        string witnessItem_W2 = WitnessTwoItems.getWitness();
                        bool bFirstItem_W2 = WitnessTwoItems.IsFirstItem;
                        bool bLastItem_W2 = WitnessTwoItems.isLastItem;

                        bool bNextItem_W2 = false;
                        string witnessGroup = WitnessTwoItems.WitnessGroup;
                        lastMatchdString = witnessItem_W2;
                        if (!bFirstItem_W2 && !bLastItem_W2)
                        {
                            bNextItem_W2 = true;
                        }

                        if ((bFirstItem_W1 && bFirstItem_W2) ||
                                            (bNextItem_W1 && bFirstItem_W2) ||
                                             (bLastItem_W1 && bFirstItem_W2))
                        {
                            newRecordItems.Add(witnessItem_W2);
                            WitnessTwo.LastVistedItem = ItemIndex;
                        }

                        else if ((bFirstItem_W1 && bNextItem_W2) ||
                                                 (bFirstItem_W1 && bLastItem_W2))
                        {
                            for (int j = stPos; j <= ItemIndex; j++)
                            {
                                newRecordItems.Add(WitnessTwoItemsList[j].getWitness());
                            }
                            WitnessTwo.LastVistedItem = ItemIndex;

                        }

                        else if ((bNextItem_W1 && bNextItem_W2) ||
                                                                  (bNextItem_W1 && bLastItem_W2))
                        {
                            WitnessTwo.LastVistedItem = ItemIndex;
                            if (WitnessOne.GetPrevItemMatched(witnessGroup))
                            {
                                for (int j = stPos; j <= ItemIndex; j++)
                                {
                                    newRecordItems.Add(WitnessTwoItemsList[j].getWitness());
                                }
                            }
                            else
                            {
                                if (!bIgnoreIfSplit)
                                {

                                    //split
                                    bSplit = true;
                                    subWitnessitems = new List<string>();
                                    int stIndex = stPos > 0 ? (stPos - 1) : -1;
                                    if (stIndex >= 0)
                                        CopyTillLastMatch(ref newRecordItems, WitnessTwoItemsList[stIndex].getWitness(), ref subWitnessitems);

                                    for (int j = stPos; j <= ItemIndex; j++)
                                    {
                                        subWitnessitems.Add(WitnessTwoItemsList[j].getWitness());
                                    }

                                    newRecordItems.Add(witnessItem_W2);
                                }
                            }
                        }

                        else if ((bLastItem_W1 && bNextItem_W2) ||
                                             (bLastItem_W1 && bLastItem_W2))
                        {
                            WitnessTwo.LastVistedItem = WitnessTwoItemsList.Count;
                            if (WitnessOne.GetPrevItemMatched(witnessGroup))
                            {
                                for (int j = stPos; j < WitnessTwoItemsList.Count; j++)
                                {
                                    newRecordItems.Add(WitnessTwoItemsList[j].getWitness());
                                }
                            }
                            else
                            {
                                if (!bIgnoreIfSplit)
                                {
                                    //split
                                    bSplit = true;
                                    subWitnessitems = new List<string>();
                                    int stIndex = stPos > 0 ? (stPos - 1) : -1;
                                    if (stIndex >= 0)
                                        CopyTillLastMatch(ref newRecordItems, WitnessTwoItemsList[stIndex].getWitness(), ref subWitnessitems);
                                    int matchedItemPos = stPos;
                                    bool bVisit = false;
                                    for (int j = stPos; j < WitnessTwoItemsList.Count; j++)
                                    {
                                        if (witnessItem_W2.Equals(WitnessTwoItemsList[j].getWitness()))
                                        {
                                            if (!bVisit)
                                            {
                                                matchedItemPos = j;
                                                bVisit = true;
                                            }
                                        }

                                        subWitnessitems.Add(WitnessTwoItemsList[j].getWitness());
                                    }

                                    for (int j = matchedItemPos; j < WitnessTwoItemsList.Count; j++)
                                    {
                                        newRecordItems.Add(WitnessTwoItemsList[j].getWitness());
                                    }
                                }
                            }
                        }

                        iLastVistedPos = WitnessTwo.LastVistedItem;
                        WitnessOne.SetPrevItemMatched(true, witnessGroup);
                    }
                    else
                    {
                        iLastVistedPos++;
                        var groupName = WitnessTwoItemsList[0].WitnessGroup;
                        if (!bIgnoreIfSplit)
                        {

                            if (iLastVistedPos + 1 == WitnessTwoItemsList.Count) // last item in second list
                            {
                                bSplit = true;

                                subWitnessitems = new List<string>();
                                CopyTillLastMatch(ref newRecordItems, lastMatchdString, ref subWitnessitems);

                                for (int j = WitnessTwo.LastVistedItem + 1; j < WitnessTwoItemsList.Count; j++)
                                {
                                    subWitnessitems.Add(WitnessTwoItemsList[j].getWitness());
                                }

                            }

                            if (bLastItem_W1 && WitnessOne.GetPrevItemMatched(groupName))
                            {
                                if ((iLastVistedPos + 1) > WitnessTwoItemsList.Count) // No more elements in W2
                                {
                                    if (subWitnessitems == null)
                                        subWitnessitems = new List<string>();
                                    subWitnessitems.Add(witnessItem_W1);
                                }
                            }
                        }
                        newRecordItems.Add(witnessItem_W1);
                        WitnessOne.SetPrevItemMatched(false, groupName);
                    }

                }

                if (!bSplit)
                {
                    newWitnessList.addToFullMerge(CreateWitnessRecord(newRecordItems));
                }
                else
                {

                    if (!bIgnoreIfSplit)
                    {
                        if (subWitnessitems != null)
                        {
                            newWitnessList.addToPartialMerge(CreateWitnessRecord(subWitnessitems));
                        }

                        newWitnessList.addToPartialMerge(CreateWitnessRecord(newRecordItems));
                    }
                    else
                        newWitnessList.addToPartialMerge(WitnessTwo);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Contraint matching error" + e.Message);
            }
            finally
            {
                WitnessTwo.LastVistedItem = -1;
            }

            return newWitnessList;
        }