public void ProcessData(IMatrixData mdata, Parameters param, ref IMatrixData[] supplTables,
                                ref IDocumentData[] documents, ProcessInfo processInfo)
        {
            ParameterWithSubParams <int> p = param.GetParamWithSubParams <int>("Row");
            int colInd = p.Value;

            if (colInd < 0)
            {
                processInfo.ErrString = "No categorical rows available.";
                return;
            }
            Parameter <int[]> mcp = p.GetSubParameters().GetParam <int[]>("Values");

            int[] inds = mcp.Value;
            if (inds.Length == 0)
            {
                processInfo.ErrString = "Please select at least one term for filtering.";
                return;
            }
            string[] values = new string[inds.Length];
            string[] v      = mdata.GetCategoryRowValuesAt(colInd);
            for (int i = 0; i < values.Length; i++)
            {
                values[i] = v[inds[i]];
            }
            HashSet <string> value  = new HashSet <string>(values);
            bool             remove = param.GetParam <int>("Mode").Value == 0;

            string[][] cats   = mdata.GetCategoryRowAt(colInd);
            List <int> valids = new List <int>();

            for (int i = 0; i < cats.Length; i++)
            {
                bool valid = true;
                foreach (string w in cats[i])
                {
                    if (value.Contains(w))
                    {
                        valid = false;
                        break;
                    }
                }
                if (valid && remove || !valid && !remove)
                {
                    valids.Add(i);
                }
            }
            PerseusPluginUtils.FilterColumns(mdata, param, valids.ToArray());
        }