public void summarizeRelatedTable(ITable pTable, ITable rTable, string plinkField, string rlinkField, string[] summaryFlds, string[] groupFlds, rasterUtil.focalType[] stats,string pWhere="", string rWhere="")
        {
            bool needCatDic = false;
            if(stats.Contains(rasterUtil.focalType.ASM)||stats.Contains(rasterUtil.focalType.ENTROPY)||stats.Contains(rasterUtil.focalType.MEDIAN)||stats.Contains(rasterUtil.focalType.MODE)||stats.Contains(rasterUtil.focalType.UNIQUE))needCatDic=true;
            HashSet<string> uGroups;
            //Console.WriteLine("Summarizing values");
            Dictionary<string,Dictionary<string, object[][]>> sumDic = getRelatedSummary(pTable, rTable, plinkField, rlinkField, summaryFlds, groupFlds, needCatDic, pWhere, rWhere, out uGroups);//<link,<group,[6][number of fields to summarize]>
            foreach (string s in sumDic.Keys)
            {
                //Console.WriteLine("ID key:" + s);
            }
            foreach (string s in uGroups)
            {
                //Console.WriteLine("Group:" + s);
            }
            //Console.WriteLine("Updating parent");
            int[] newFldNameIndex = new int[summaryFlds.Length * uGroups.Count * (stats.Length+1)];
            string[] newFldNameString = new string[summaryFlds.Length * uGroups.Count * (stats.Length+1)];
            int IndexCnt = 0;
            //int nIndex = pTable.FindField(geoUtil.createField(pTable,"n",esriFieldType.esriFieldTypeDouble,false));
            int linkIndex = pTable.FindField(plinkField);
            for (int i = 0; i < summaryFlds.Length; i++)
            {
                string fldNm = summaryFlds[i];
                foreach(string k in uGroups)
                {
                    string fldNm2 = fldNm + "_" + k;
                    string newFldName = geoUtil.createField(pTable, fldNm2 + "_N", esriFieldType.esriFieldTypeInteger, false);
                    newFldNameString[IndexCnt] = newFldName;
                    newFldNameIndex[IndexCnt] = pTable.FindField(newFldName);
                    IndexCnt += 1;
                    for (int j = 0; j < stats.Length; j++)
                    {
                        string fldNm3 = fldNm2 + "_" + stats[j];
                        newFldName = geoUtil.createField(pTable, fldNm3, esriFieldType.esriFieldTypeDouble, false);
                        newFldNameString[IndexCnt]=newFldName;
                        newFldNameIndex[IndexCnt] = pTable.FindField(newFldName);
                        IndexCnt += 1;
                    }
                }
            }
            IQueryFilter pQf = new QueryFilterClass();
            if (!String.IsNullOrEmpty(pWhere)) pQf.WhereClause = pWhere;
            ICursor cur = pTable.Update(pQf, true);
            IRow rw = cur.NextRow();
            while (rw != null)
            {
                string lnk = rw.get_Value(linkIndex).ToString();
                Dictionary<string,object[][]> d;
                if (sumDic.TryGetValue(lnk, out d))
                {
                    //Console.WriteLine("Found dictionary value " + lnk);
                    object n = 0;
                    for (int i = 0; i < newFldNameString.Length; i++)
                    {
                        string fldNameC = newFldNameString[i];
                        string[] fldnameArr = fldNameC.Split(new char[] { '_' });
                        string fld = fldnameArr[0];
                        string grp = fldnameArr[1];
                        for (int k = 1; k < groupFlds.Length; k++)
                        {
                            grp = grp + "_" + fldnameArr[1 + k];
                        }
                        string st = fldnameArr[fldnameArr.Length-1];
                        object[][] vlFldArr;
                        if (d.TryGetValue(grp, out vlFldArr))
                        {
                            //Console.WriteLine("Found Group value " + grp);
                            object uVl = 0;
                            int clIndex = System.Array.IndexOf(summaryFlds, fld);
                            object[] vlArr = vlFldArr[clIndex];
                            n = vlArr[0];
                            if (st != "N")
                            {
                                rasterUtil.focalType sType = (rasterUtil.focalType)Enum.Parse(typeof(rasterUtil.focalType), st);
                                //Console.WriteLine(sType.ToString());
                                switch (sType)
                                {
                                    case rasterUtil.focalType.SUM:
                                        uVl = vlArr[1];
                                        break;
                                    case rasterUtil.focalType.MIN:
                                        uVl = vlArr[3];
                                        break;
                                    case rasterUtil.focalType.MAX:
                                        uVl = vlArr[4];
                                        break;
                                    case rasterUtil.focalType.MEAN:
                                        uVl = System.Convert.ToDouble(vlArr[1]) / System.Convert.ToDouble(n);
                                        break;
                                    case rasterUtil.focalType.STD:
                                        uVl = Math.Sqrt((System.Convert.ToDouble(vlArr[2]) - (System.Convert.ToDouble(vlArr[1]) / System.Convert.ToDouble(n))) / (System.Convert.ToDouble(n) - 1));
                                        break;
                                    case rasterUtil.focalType.MODE:
                                        uVl = getMode((Dictionary<string, int>)vlArr[5]);
                                        break;
                                    case rasterUtil.focalType.MEDIAN:
                                        uVl = getMedian((Dictionary<string, int>)vlArr[5]);
                                        break;
                                    case rasterUtil.focalType.VARIANCE:
                                        uVl = (System.Convert.ToDouble(vlArr[2]) - (System.Convert.ToDouble(vlArr[1]) / System.Convert.ToDouble(n))) / (System.Convert.ToDouble(n) - 1);
                                        break;
                                    case rasterUtil.focalType.UNIQUE:
                                        uVl = ((Dictionary<string, int>)vlArr[5]).Keys.Count;
                                        break;
                                    case rasterUtil.focalType.ENTROPY:
                                        uVl = getEntropy((Dictionary<string, int>)vlArr[5]);
                                        break;
                                    case rasterUtil.focalType.ASM:
                                        uVl = getASM((Dictionary<string, int>)vlArr[5]);
                                        break;
                                    default:
                                        break;
                                }

                            }
                            else
                            {
                                uVl = n;
                            }
                            rw.set_Value(newFldNameIndex[i], uVl);
                        }
                        else
                        {
                            //Console.WriteLine("Could not find Group " + grp);
                            rw.set_Value(newFldNameIndex[i], 0);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < newFldNameString.Length; i++)
                    {
                        rw.set_Value(newFldNameIndex[i], 0);
                    }
                }
                cur.UpdateRow(rw);
                rw = cur.NextRow();
            }
            System.Runtime.InteropServices.Marshal.ReleaseComObject(cur);
        }