/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Collections.Generic;
using System.Threading;

namespace Apache.Geode.Client.UnitTests
{
  using NUnit.Framework;
  using Apache.Geode.DUnitFramework;
  using Apache.Geode.Client.Tests;

  using Apache.Geode.Client;

  using QueryStatics = Apache.Geode.Client.Tests.QueryStatics;
  using QueryCategory = Apache.Geode.Client.Tests.QueryCategory;
  using QueryStrings = Apache.Geode.Client.Tests.QueryStrings;

  [Ignore("flaky")]
  [TestFixture]
  [Category("group1")]
  [Category("unicast_only")]
  [Category("generics")]
  public class ThinClientQueryTests : ThinClientRegionSteps
  {
    #region Private members

    private UnitProcess m_client1;
    private UnitProcess m_client2;
    private static string[] QueryRegionNames = { "Portfolios", "Positions", "Portfolios2",
      "Portfolios3" };
    private static string QERegionName = "Portfolios";
    #endregion

    protected override ClientBase[] GetClients()
    {
      m_client1 = new UnitProcess();
      m_client2 = new UnitProcess();
      return new ClientBase[] { m_client1, m_client2 };
    }

    [TestFixtureSetUp]
    public override void InitTests()
    {
      base.InitTests();
    }

    [TearDown]
    public override void EndTest()
    {
			m_client1.Call(Close);
			m_client2.Call(Close);
			CacheHelper.StopJavaServers();
      base.EndTest();
    }

    [SetUp]
    public override void InitTest()
    {
      m_client1.Call(InitClient);
      m_client2.Call(InitClient);
    }

    #region Functions invoked by the tests

    public void InitClient()
    {
      CacheHelper.Init();
      CacheHelper.DCache.TypeRegistry.RegisterType(Portfolio.CreateDeserializable, 8);
      CacheHelper.DCache.TypeRegistry.RegisterType(Position.CreateDeserializable, 7);
      CacheHelper.DCache.TypeRegistry.RegisterPdxType(PortfolioPdx.CreateDeserializable);
      CacheHelper.DCache.TypeRegistry.RegisterPdxType(PositionPdx.CreateDeserializable);
    }

    public void StepOneQE(string locators, bool isPdx)
    {
      m_isPdx = isPdx;
      try
      {
				var poolFail = CacheHelper.DCache.GetPoolManager().CreateFactory().Create("_TESTFAILPOOL_");
				var qsFail = poolFail.GetQueryService();
        var qryFail = qsFail.NewQuery<object>("select distinct * from /" + QERegionName);
        var resultsFail = qryFail.Execute();
        Assert.Fail("Since no endpoints defined, so exception expected");
      }
      catch (IllegalStateException ex)
      {
        Util.Log("Got expected exception: {0}", ex);
      }
			catch (Exception e) {
				Util.Log("Caught unexpected exception: {0}", e);
				throw e;
			}

      CacheHelper.CreateTCRegion_Pool<object, object>(QERegionName, true, true,
        null, locators, "__TESTPOOL1_", true);
      IRegion<object, object> region = CacheHelper.GetVerifyRegion<object, object>(QERegionName);
      if (!m_isPdx)
      {
        Portfolio p1 = new Portfolio(1, 100);
        Portfolio p2 = new Portfolio(2, 100);
        Portfolio p3 = new Portfolio(3, 100);
        Portfolio p4 = new Portfolio(4, 100);

        region["1"] = p1;
        region["2"] = p2;
        region["3"] = p3;
        region["4"] = p4;
      }
      else
      {
        PortfolioPdx p1 = new PortfolioPdx(1, 100);
        PortfolioPdx p2 = new PortfolioPdx(2, 100);
        PortfolioPdx p3 = new PortfolioPdx(3, 100);
        PortfolioPdx p4 = new PortfolioPdx(4, 100);

        region["1"] = p1;
        region["2"] = p2;
        region["3"] = p3;
        region["4"] = p4;
      }

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      Query<object> qry = qs.NewQuery<object>("select distinct * from /" + QERegionName);
      ISelectResults<object> results = qry.Execute();
      var count = results.Size;
      Assert.AreEqual(4, count, "Expected 4 as number of portfolio objects.");

      // Bring down the region
      region.GetLocalView().DestroyRegion();
    }

    public void StepTwoQE()
    {
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();
      Util.Log("Going to execute the query");
      Query<object> qry = qs.NewQuery<object>("select distinct * from /" + QERegionName);
      ISelectResults<object> results = qry.Execute();
      var count = results.Size;
      Assert.AreEqual(4, count, "Expected 4 as number of portfolio objects.");
    }

    public void StepOne(string locators, bool isPdx)
    {
      m_isPdx = isPdx;
      CacheHelper.CreateTCRegion_Pool<object, object>(QueryRegionNames[0], true, true,
      null, locators, "__TESTPOOL1_", true);
      CacheHelper.CreateTCRegion_Pool<object, object>(QueryRegionNames[1], true, true,
        null, locators, "__TESTPOOL1_", true);
      CacheHelper.CreateTCRegion_Pool<object, object>(QueryRegionNames[2], true, true,
        null, locators, "__TESTPOOL1_", true);
      CacheHelper.CreateTCRegion_Pool<object, object>(QueryRegionNames[3], true, true,
        null, locators, "__TESTPOOL1_", true);

      IRegion<object, object> region = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);
      Apache.Geode.Client.RegionAttributes<object, object> regattrs = region.Attributes;
      region.CreateSubRegion(QueryRegionNames[1], regattrs);
    }

    public void StepTwo(bool isPdx)
    {
      m_isPdx = isPdx;
      IRegion<object, object> region0 = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);
      IRegion<object, object> subRegion0 = (IRegion<object, object>)region0.GetSubRegion(QueryRegionNames[1]);
      IRegion<object, object> region1 = CacheHelper.GetRegion<object, object>(QueryRegionNames[1]);
      IRegion<object, object> region2 = CacheHelper.GetRegion<object, object>(QueryRegionNames[2]);
      IRegion<object, object> region3 = CacheHelper.GetRegion<object, object>(QueryRegionNames[3]);

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      Util.Log("SetSize {0}, NumSets {1}.", qh.PortfolioSetSize,
        qh.PortfolioNumSets);

      if (!m_isPdx)
      {
        qh.PopulatePortfolioData(region0, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePositionData(subRegion0, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePositionData(region1, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePortfolioData(region2, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePortfolioData(region3, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
      }
      else
      {
        qh.PopulatePortfolioPdxData(region0, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePositionPdxData(subRegion0, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePositionPdxData(region1, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePortfolioPdxData(region2, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
        qh.PopulatePortfolioPdxData(region3, qh.PortfolioSetSize,
          qh.PortfolioNumSets);
      }
    }

    public void StepTwoQT()
    {
      IRegion<object, object> region0 = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);
      IRegion<object, object> subRegion0 = region0.GetSubRegion(QueryRegionNames[1]);

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      if (!m_isPdx)
      {
        qh.PopulatePortfolioData(region0, 100, 20, 100);
        qh.PopulatePositionData(subRegion0, 100, 20);
      }
      else
      {
        qh.PopulatePortfolioPdxData(region0, 100, 20, 100);
        qh.PopulatePositionPdxData(subRegion0, 100, 20);
      }
    }

    public void StepThreeRS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.ResultSetQueries)
      {
        if (qrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        if (m_isPdx == true)
        {
          if (qryIdx == 2 || qryIdx == 3 || qryIdx == 4)
          {
            Util.Log("Skipping query index {0} for Pdx because it is function type.", qryIdx);
            qryIdx++;
            continue;
          }
        }

        Util.Log("Evaluating query index {0}. Query string {1}", qryIdx, qrystr.Query);

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        ISelectResults<object> results = query.Execute();

        int expectedRowCount = qh.IsExpectedRowsConstantRS(qryIdx) ?
          QueryStatics.ResultSetRowCounts[qryIdx] : QueryStatics.ResultSetRowCounts[qryIdx] * qh.PortfolioNumSets;

        if (!qh.VerifyRS(results, expectedRowCount))
        {
          ErrorOccurred = true;
          Util.Log("Query verify failed for query index {0}.", qryIdx);
          qryIdx++;
          continue;
        }

        ResultSet<object> rs = results as ResultSet<object>;

        foreach (object item in rs)
        {
          if (!m_isPdx)
          {
            Portfolio port = item as Portfolio;
            if (port == null)
            {
              Position pos = item as Position;
              if (pos == null)
              {
                string cs = item.ToString();
                if (cs == null)
                {
                  Util.Log("Query got other/unknown object.");
                }
                else
                {
                  Util.Log("Query got string : {0}.", cs);
                }
              }
              else
              {
                Util.Log("Query got Position object with secId {0}, shares {1}.", pos.SecId, pos.SharesOutstanding);
              }
            }
            else
            {
              Util.Log("Query got Portfolio object with ID {0}, pkid {1}.", port.ID, port.Pkid);
            }
          }
          else
          {
            PortfolioPdx port = item as PortfolioPdx;
            if (port == null)
            {
              PositionPdx pos = item as PositionPdx;
              if (pos == null)
              {
                string cs = item.ToString();
                if (cs == null)
                {
                  Util.Log("Query got other/unknown object.");
                }
                else
                {
                  Util.Log("Query got string : {0}.", cs);
                }
              }
              else
              {
                Util.Log("Query got Position object with secId {0}, shares {1}.", pos.secId, pos.getSharesOutstanding);
              }
            }
            else
            {
              Util.Log("Query got Portfolio object with ID {0}, pkid {1}.", port.ID, port.Pkid);
            }
          }
        }

        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");
    }

    public void StepThreePQRS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings paramqrystr in QueryStatics.ResultSetParamQueries)
      {
        if (paramqrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating query index {0}. {1}", qryIdx, paramqrystr.Query);

        Query<object> query = qs.NewQuery<object>(paramqrystr.Query);

        //Populate the parameter list (paramList) for the query.
        object[] paramList = new object[QueryStatics.NoOfQueryParam[qryIdx]];
        int numVal = 0;
        for (int ind = 0; ind < QueryStatics.NoOfQueryParam[qryIdx]; ind++)
        {
          //Util.Log("NIL::PQRS:: QueryStatics.QueryParamSet[{0},{1}] = {2}", qryIdx, ind, QueryStatics.QueryParamSet[qryIdx][ind]);

          try
          {
            numVal = Convert.ToInt32(QueryStatics.QueryParamSet[qryIdx][ind]);
            paramList[ind] = numVal;
            //Util.Log("NIL::PQRS::361 Interger Args:: paramList[0] = {1}", ind, paramList[ind]);
          }
          catch (FormatException)
          {
            //Console.WriteLine("Param string is not a sequence of digits.");
            paramList[ind] = (System.String)QueryStatics.QueryParamSet[qryIdx][ind];
            //Util.Log("NIL::PQRS:: Interger Args:: routingObj[0] = {1}", ind, routingObj[ind].ToString());
          }
        }

        ISelectResults<object> results = query.Execute(paramList);

        //Varify the result
        int expectedRowCount = qh.IsExpectedRowsConstantPQRS(qryIdx) ?
        QueryStatics.ResultSetPQRowCounts[qryIdx] : QueryStatics.ResultSetPQRowCounts[qryIdx] * qh.PortfolioNumSets;

        if (!qh.VerifyRS(results, expectedRowCount))
        {
          ErrorOccurred = true;
          Util.Log("Query verify failed for query index {0}.", qryIdx);
          qryIdx++;
          continue;
        }

        ResultSet<object> rs = results as ResultSet<object>;

        foreach (object item in rs)
        {
          if (!m_isPdx)
          {
            Portfolio port = item as Portfolio;
            if (port == null)
            {
              Position pos = item as Position;
              if (pos == null)
              {
                string cs = item as string;
                if (cs == null)
                {
                  Util.Log("Query got other/unknown object.");
                }
                else
                {
                  Util.Log("Query got string : {0}.", cs);
                }
              }
              else
              {
                Util.Log("Query got Position object with secId {0}, shares {1}.", pos.SecId, pos.SharesOutstanding);
              }
            }
            else
            {
              Util.Log("Query got Portfolio object with ID {0}, pkid {1}.", port.ID, port.Pkid);
            }
          }
          else
          {
            PortfolioPdx port = item as PortfolioPdx;
            if (port == null)
            {
              PositionPdx pos = item as PositionPdx;
              if (pos == null)
              {
                string cs = item as string;
                if (cs == null)
                {
                  Util.Log("Query got other/unknown object.");
                }
                else
                {
                  Util.Log("Query got string : {0}.", cs);
                }
              }
              else
              {
                Util.Log("Query got PositionPdx object with secId {0}, shares {1}.", pos.secId, pos.getSharesOutstanding);
              }
            }
            else
            {
              Util.Log("Query got PortfolioPdx object with ID {0}, pkid {1}.", port.ID, port.Pkid);
            }
          }
        }

        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");
    }

    public void StepFourRS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.ResultSetQueries)
      {
        if (qrystr.Category != QueryCategory.Unsupported)
        {
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating unsupported query index {0}.", qryIdx);

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        try
        {
          ISelectResults<object> results = query.Execute();

          Util.Log("Query exception did not occur for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
        catch (GeodeException)
        {
          // ok, exception expected, do nothing.
          qryIdx++;
        }
        catch (Exception)
        {
          Util.Log("Query unexpected exception occurred for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
      }

      Assert.IsFalse(ErrorOccurred, "Query expected exceptions did not occur.");
    }

    public void StepFourPQRS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.ResultSetParamQueries)
      {
        if (qrystr.Category != QueryCategory.Unsupported)
        {
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating unsupported query index {0}.", qryIdx);

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        object[] paramList = new object[QueryStatics.NoOfQueryParam[qryIdx]];

        Int32 numVal = 0;
        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParam[qryIdx]; ind++)
        {
          //Util.Log("NIL::PQRS:: QueryStatics.QueryParamSet[{0},{1}] = {2}", qryIdx, ind, QueryStatics.QueryParamSet[qryIdx, ind]);

          try
          {
            numVal = Convert.ToInt32(QueryStatics.QueryParamSet[qryIdx][ind]);
            paramList[ind] = numVal;
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind]);
          }
          catch (FormatException)
          {
            //Console.WriteLine("Param string is not a sequence of digits.");
            paramList[ind] = (System.String)QueryStatics.QueryParamSet[qryIdx][ind];
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind].ToString());
          }
        }

        try
        {
          ISelectResults<object> results = query.Execute(paramList);

          Util.Log("Query exception did not occur for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
        catch (GeodeException)
        {
          // ok, exception expected, do nothing.
          qryIdx++;
        }
        catch (Exception)
        {
          Util.Log("Query unexpected exception occurred for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
      }

      Assert.IsFalse(ErrorOccurred, "Query expected exceptions did not occur.");
    }

    public void StepThreeSS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.StructSetQueries)
      {
        if (qrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        if (m_isPdx == true)
        {
          if (qryIdx == 12 || qryIdx == 4 || qryIdx == 7 || qryIdx == 22 || qryIdx == 30 || qryIdx == 34)
          {
            Util.Log("Skipping query index {0} for pdx because it has function.", qryIdx);
            qryIdx++;
            continue;
          }
        }

        Util.Log("Evaluating query index {0}. {1}", qryIdx, qrystr.Query);

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        ISelectResults<object> results = query.Execute();

        int expectedRowCount = qh.IsExpectedRowsConstantSS(qryIdx) ?
          QueryStatics.StructSetRowCounts[qryIdx] : QueryStatics.StructSetRowCounts[qryIdx] * qh.PortfolioNumSets;

        if (!qh.VerifySS(results, expectedRowCount, QueryStatics.StructSetFieldCounts[qryIdx]))
        {
          ErrorOccurred = true;
          Util.Log("Query verify failed for query index {0}.", qryIdx);
          qryIdx++;
          continue;
        }

        StructSet<object> ss = results as StructSet<object>;
        if (ss == null)
        {
          Util.Log("Zero records found for query index {0}, continuing.", qryIdx);
          qryIdx++;
          continue;
        }

        uint rows = 0;
        Int32 fields = 0;
        foreach (Struct si in ss)
        {
          rows++;
          fields = (Int32)si.Count;
        }

        Util.Log("Query index {0} has {1} rows and {2} fields.", qryIdx, rows, fields);

        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");
    }

    public void StepThreePQSS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.StructSetParamQueries)
      {
        if (qrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating query index {0}. {1}", qryIdx, qrystr.Query);

        if (m_isPdx == true)
        {
          if (qryIdx == 16)
          {
            Util.Log("Skipping query index {0} for pdx because it has function.", qryIdx);
            qryIdx++;
            continue;
          }
        }

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        //Populate the param list, paramList for parameterized query 
        object[] paramList = new object[QueryStatics.NoOfQueryParamSS[qryIdx]];

        Int32 numVal = 0;
        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[qryIdx]; ind++)
        {
          //Util.Log("NIL::PQRS:: QueryStatics.QueryParamSetSS[{0},{1}] = {2}", qryIdx, ind, QueryStatics.QueryParamSetSS[qryIdx, ind]);

          try
          {
            numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[qryIdx][ind]);
            paramList[ind] = numVal;
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind]);
          }
          catch (FormatException)
          {
            //Console.WriteLine("Param string is not a sequence of digits.");
            paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[qryIdx][ind];
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind].ToString());
          }
        }

        ISelectResults<object> results = query.Execute(paramList);

        int expectedRowCount = qh.IsExpectedRowsConstantPQSS(qryIdx) ?
        QueryStatics.StructSetPQRowCounts[qryIdx] : QueryStatics.StructSetPQRowCounts[qryIdx] * qh.PortfolioNumSets;

        if (!qh.VerifySS(results, expectedRowCount, QueryStatics.StructSetPQFieldCounts[qryIdx]))
        {
          ErrorOccurred = true;
          Util.Log("Query verify failed for query index {0}.", qryIdx);
          qryIdx++;
          continue;
        }

        StructSet<object> ss = results as StructSet<object>;
        if (ss == null)
        {
          Util.Log("Zero records found for query index {0}, continuing.", qryIdx);
          qryIdx++;
          continue;
        }

        uint rows = 0;
        Int32 fields = 0;
        foreach (Struct si in ss)
        {
          rows++;
          fields = (Int32)si.Count;
        }

        Util.Log("Query index {0} has {1} rows and {2} fields.", qryIdx, rows, fields);

        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");
    }

    public void StepFourSS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.StructSetQueries)
      {
        if (qrystr.Category != QueryCategory.Unsupported)
        {
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating unsupported query index {0}.", qryIdx);

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        try
        {
          ISelectResults<object> results = query.Execute();

          Util.Log("Query exception did not occur for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
        catch (GeodeException)
        {
          // ok, exception expected, do nothing.
          qryIdx++;
        }
        catch (Exception)
        {
          Util.Log("Query unexpected exception occurred for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
      }

      Assert.IsFalse(ErrorOccurred, "Query expected exceptions did not occur.");
    }

    public void StepFourPQSS()
    {
      bool ErrorOccurred = false;

      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.StructSetParamQueries)
      {
        if (qrystr.Category != QueryCategory.Unsupported)
        {
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating unsupported query index {0}.", qryIdx);

        Query<object> query = qs.NewQuery<object>(qrystr.Query);

        //Populate the param list
        object[] paramList = new object[QueryStatics.NoOfQueryParamSS[qryIdx]];

        Int32 numVal = 0;
        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[qryIdx]; ind++)
        {
          //Util.Log("NIL::PQRS:: QueryStatics.QueryParamSetSS[{0},{1}] = {2}", qryIdx, ind, QueryStatics.QueryParamSetSS[qryIdx, ind]);

          try
          {
            numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[qryIdx][ind]);
            paramList[ind] = numVal;
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind]);
          }
          catch (FormatException)
          {
            //Console.WriteLine("Param string is not a sequence of digits.");
            paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[qryIdx][ind];
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind].ToString());
          }
        }

        try
        {
          ISelectResults<object> results = query.Execute(paramList);

          Util.Log("Query exception did not occur for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
        catch (GeodeException)
        {
          // ok, exception expected, do nothing.
          qryIdx++;
        }
        catch (Exception)
        {
          Util.Log("Query unexpected exception occurred for index {0}.", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
      }

      Assert.IsFalse(ErrorOccurred, "Query expected exceptions did not occur.");
    }

    public void KillServer()
    {
      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");
    }

    public delegate void KillServerDelegate();

    public void StepOneFailover(bool isPdx)
    {
      m_isPdx = isPdx;
      // This is here so that Client1 registers information of the cacheserver
      // that has been already started
      CacheHelper.SetupJavaServers(true,
        "cacheserver_remoteoqlN.xml",
        "cacheserver_remoteoql2N.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      CacheHelper.CreateTCRegion_Pool<object, object>(QueryRegionNames[0], true, true, null,
        CacheHelper.Locators, "__TESTPOOL1_", true);

      IRegion<object, object> region = CacheHelper.GetVerifyRegion<object, object>(QueryRegionNames[0]);
      if (!m_isPdx)
      {
        Portfolio p1 = new Portfolio(1, 100);
        Portfolio p2 = new Portfolio(2, 200);
        Portfolio p3 = new Portfolio(3, 300);
        Portfolio p4 = new Portfolio(4, 400);

        region["1"] = p1;
        region["2"] = p2;
        region["3"] = p3;
        region["4"] = p4;
      }
      else
      {
        PortfolioPdx p1 = new PortfolioPdx(1, 100);
        PortfolioPdx p2 = new PortfolioPdx(2, 200);
        PortfolioPdx p3 = new PortfolioPdx(3, 300);
        PortfolioPdx p4 = new PortfolioPdx(4, 400);

        region["1"] = p1;
        region["2"] = p2;
        region["3"] = p3;
        region["4"] = p4;
      }
    }

    public void StepTwoFailover()
    {
      CacheHelper.StartJavaServerWithLocators(2, "GFECS2", 1);
      Util.Log("Cacheserver 2 started.");

      IAsyncResult killRes = null;
      KillServerDelegate ksd = new KillServerDelegate(KillServer);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      for (int i = 0; i < 10000; i++)
      {
        Query<object> qry = qs.NewQuery<object>("select distinct * from /" + QueryRegionNames[0]);

        ISelectResults<object> results = qry.Execute();

        if (i == 10)
        {
          killRes = ksd.BeginInvoke(null, null);
        }

        var resultSize = results.Size;

        if (i % 100 == 0)
        {
          Util.Log("Iteration upto {0} done, result size is {1}", i, resultSize);
        }

        Assert.AreEqual(4, resultSize, "Result size is not 4!");
      }

      killRes.AsyncWaitHandle.WaitOne();
      ksd.EndInvoke(killRes);
    }

    public void StepTwoPQFailover()
    {
      CacheHelper.StartJavaServerWithLocators(2, "GFECS2", 1);
      Util.Log("Cacheserver 2 started.");

      IAsyncResult killRes = null;
      KillServerDelegate ksd = new KillServerDelegate(KillServer);

      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      for (int i = 0; i < 10000; i++)
      {
        Query<object> qry = qs.NewQuery<object>("select distinct * from /" + QueryRegionNames[0] + " where ID > $1");

        //Populate the param list
        object[] paramList = new object[1];
        paramList[0] = 1;

        ISelectResults<object> results = qry.Execute(paramList);

        if (i == 10)
        {
          killRes = ksd.BeginInvoke(null, null);
        }

        var resultSize = results.Size;

        if (i % 100 == 0)
        {
          Util.Log("Iteration upto {0} done, result size is {1}", i, resultSize);
        }

        Assert.AreEqual(3, resultSize, "Result size is not 3!");
      }

      killRes.AsyncWaitHandle.WaitOne();
      ksd.EndInvoke(killRes);
    }

    public void StepThreeQT()
    {
      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();
      Util.Log("query " + QueryStatics.ResultSetQueries[34].Query);
      Query<object> query = qs.NewQuery<object>(QueryStatics.ResultSetQueries[34].Query);

      try
      {
        Util.Log("EXECUTE 1 START for query: ", query.QueryString);
        ISelectResults<object> results = query.Execute(TimeSpan.FromSeconds(3));
        Util.Log("EXECUTE 1 STOP");
        Util.Log("Result size is {0}", results.Size);
        Assert.Fail("Didnt get expected timeout exception for first execute");
      }
      catch (GeodeException excp)
      {
        Util.Log("First execute expected exception: {0}", excp.Message);
      }
    }

    public void StepFourQT()
    {
      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      Query<object> query = qs.NewQuery<object>(QueryStatics.ResultSetQueries[35].Query);

      try
      {
        Util.Log("EXECUTE 2 START for query: ", query.QueryString);
        ISelectResults<object> results = query.Execute(TimeSpan.FromSeconds(850));
        Util.Log("EXECUTE 2 STOP");
        Util.Log("Result size is {0}", results.Size);
      }
      catch (GeodeException excp)
      {
        Assert.Fail("Second execute unwanted exception: {0}", excp.Message);
      }
    }

    public void StepFiveQT()
    {
      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      Query<object> query = qs.NewQuery<object>(QueryStatics.StructSetQueries[17].Query);

      try
      {
        Util.Log("EXECUTE 3 START for query: ", query.QueryString);
        ISelectResults<object> results = query.Execute(TimeSpan.FromSeconds(2));
        Util.Log("EXECUTE 3 STOP");
        Util.Log("Result size is {0}", results.Size);
        Assert.Fail("Didnt get expected timeout exception for third execute");
      }
      catch (GeodeException excp)
      {
        Util.Log("Third execute expected exception: {0}", excp.Message);
      }
    }

    public void StepSixQT()
    {
      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();
      Query<object> query = qs.NewQuery<object>(QueryStatics.StructSetQueries[17].Query);

      try
      {
        Util.Log("EXECUTE 4 START for query: ", query.QueryString);
        ISelectResults<object> results = query.Execute(TimeSpan.FromSeconds(850));
        Util.Log("EXECUTE 4 STOP");
        Util.Log("Result size is {0}", results.Size);
      }
      catch (GeodeException excp)
      {
        Assert.Fail("Fourth execute unwanted exception: {0}", excp.Message);
      }
    }

    public void StepThreePQT()
    {
      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      Query<object> query = qs.NewQuery<object>(QueryStatics.StructSetParamQueries[5].Query);


      try
      {
        Util.Log("EXECUTE 5 START for query: ", query.QueryString);
        //Populate the param list, paramList for parameterized query 
        object[] paramList = new object[QueryStatics.NoOfQueryParamSS[5]];

        Int32 numVal = 0;
        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[5]; ind++)
        {
          try
          {
            numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[5][ind]);
            paramList[ind] = numVal;
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind]);
          }
          catch (FormatException)
          {
            //Console.WriteLine("Param string is not a sequence of digits.");
            paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[5][ind];
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind].ToString());
          }
        }

        ISelectResults<object> results = query.Execute(paramList, TimeSpan.FromSeconds(1));
        Util.Log("EXECUTE 5 STOP");
        Util.Log("Result size is {0}", results.Size);
        Assert.Fail("Didnt get expected timeout exception for Fifth execute");
      }
      catch (GeodeException excp)
      {
        Util.Log("Fifth execute expected exception: {0}", excp.Message);
      }
    }

    public void StepFourPQT()
    {
      QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
      var qs = CacheHelper.DCache.GetPoolManager().Find("__TESTPOOL1_").GetQueryService();

      Query<object> query = qs.NewQuery<object>(QueryStatics.StructSetParamQueries[5].Query);

      try
      {
        Util.Log("EXECUTE 6 START for query: ", query.QueryString);
        //Populate the param list, paramList for parameterized query 
        object[] paramList = new object[QueryStatics.NoOfQueryParamSS[5]];

        Int32 numVal = 0;
        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[5]; ind++)
        {
          try
          {
            numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[5][ind]);
            paramList[ind] = numVal;
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind]);
          }
          catch (FormatException)
          {
            //Console.WriteLine("Param string is not a sequence of digits.");
            paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[5][ind];
            //Util.Log("NIL::PQRS:: Interger Args:: paramList[0] = {1}", ind, paramList[ind].ToString());
          }
        }

        ISelectResults<object> results = query.Execute(paramList, TimeSpan.FromSeconds(850));
        Util.Log("EXECUTE 6 STOP");
        Util.Log("Result size is {0}", results.Size);
      }
      catch (GeodeException excp)
      {
        Assert.Fail("Sixth execute unwanted exception: {0}", excp.Message);
      }
    }

    public void StepThreeRQ()
    {
      bool ErrorOccurred = false;

      IRegion<object, object> region = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.RegionQueries)
      {
        if (qrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating query index {0}. {1}", qryIdx, qrystr.Query);

        if (m_isPdx)
        {
          if (qryIdx == 18)
          {
            Util.Log("Skipping query index {0} because it is unsupported for pdx type.", qryIdx);
            qryIdx++;
            continue;
          }
        }

        ISelectResults<object> results = region.Query<object>(qrystr.Query);

        if (results.Size != (ulong) QueryStatics.RegionQueryRowCounts[qryIdx])
        {
          ErrorOccurred = true;
          Util.Log("FAIL: Query # {0} expected result size is {1}, actual is {2}", qryIdx,
            QueryStatics.RegionQueryRowCounts[qryIdx], results.Size);
          qryIdx++;
          continue;
        }
        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");

      try
      {
        ISelectResults<object> results = region.Query<object>("");
        Assert.Fail("Expected IllegalArgumentException exception for empty predicate");
      }
      catch (IllegalArgumentException ex)
      {
        Util.Log("got expected IllegalArgumentException exception for empty predicate:");
        Util.Log(ex.Message);
      }


      try
      {
        ISelectResults<object> results = region.Query<object>(QueryStatics.RegionQueries[0].Query, TimeSpan.FromSeconds(2200000));
        Assert.Fail("Expected IllegalArgumentException exception for invalid timeout");
      }
      catch (IllegalArgumentException ex)
      {
        Util.Log("got expected IllegalArgumentException exception for invalid timeout:");
        Util.Log(ex.Message);
      }


      try
      {
        ISelectResults<object> results = region.Query<object>("bad predicate");
        Assert.Fail("Expected QueryException exception for wrong predicate");
      }
      catch (QueryException ex)
      {
        Util.Log("got expected QueryException exception for wrong predicate:");
        Util.Log(ex.Message);
      }
    }

    public void StepFourRQ()
    {
      bool ErrorOccurred = false;

      IRegion<object, object> region = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.RegionQueries)
      {
        if (qrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating query index {0}.{1}", qryIdx, qrystr.Query);

        bool existsValue = region.ExistsValue(qrystr.Query);
        bool expectedResult = QueryStatics.RegionQueryRowCounts[qryIdx] > 0 ? true : false;

        if (existsValue != expectedResult)
        {
          ErrorOccurred = true;
          Util.Log("FAIL: Query # {0} existsValue expected is {1}, actual is {2}", qryIdx,
            expectedResult ? "true" : "false", existsValue ? "true" : "false");
          qryIdx++;
          continue;
        }

        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");
      try
      {
        bool existsValue = region.ExistsValue("");
        Assert.Fail("Expected IllegalArgumentException exception for empty predicate");
      }
      catch (IllegalArgumentException ex)
      {
        Util.Log("got expected IllegalArgumentException exception for empty predicate:");
        Util.Log(ex.Message);
      }


      try
      {
        bool existsValue = region.ExistsValue(QueryStatics.RegionQueries[0].Query, TimeSpan.FromSeconds(2200000));
        Assert.Fail("Expected IllegalArgumentException exception for invalid timeout");
      }
      catch (IllegalArgumentException ex)
      {
        Util.Log("got expected IllegalArgumentException exception for invalid timeout:");
        Util.Log(ex.Message);
      }


      try
      {
        bool existsValue = region.ExistsValue("bad predicate");
        Assert.Fail("Expected QueryException exception for wrong predicate");
      }
      catch (QueryException ex)
      {
        Util.Log("got expected QueryException exception for wrong predicate:");
        Util.Log(ex.Message);
      }
    }

    public void StepFiveRQ()
    {
      bool ErrorOccurred = false;

      IRegion<object, object> region = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.RegionQueries)
      {
        if (qrystr.Category == QueryCategory.Unsupported)
        {
          Util.Log("Skipping query index {0} because it is unsupported.", qryIdx);
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating query index {0}.", qryIdx);

        try
        {
          Object result = region.SelectValue(qrystr.Query);

          if (!(QueryStatics.RegionQueryRowCounts[qryIdx] == 0 ||
            QueryStatics.RegionQueryRowCounts[qryIdx] == 1))
          {
            ErrorOccurred = true;
            Util.Log("FAIL: Query # {0} expected query exception did not occur", qryIdx);
            qryIdx++;
            continue;
          }
        }
        catch (QueryException)
        {
          if (QueryStatics.RegionQueryRowCounts[qryIdx] == 0 ||
            QueryStatics.RegionQueryRowCounts[qryIdx] == 1)
          {
            ErrorOccurred = true;
            Util.Log("FAIL: Query # {0} unexpected query exception occured", qryIdx);
            qryIdx++;
            continue;
          }
        }
        catch (Exception)
        {
          ErrorOccurred = true;
          Util.Log("FAIL: Query # {0} unexpected exception occured", qryIdx);
          qryIdx++;
          continue;
        }

        qryIdx++;
      }

      Assert.IsFalse(ErrorOccurred, "One or more query validation errors occurred.");

      try
      {
        Object result = region.SelectValue("");
        Assert.Fail("Expected IllegalArgumentException exception for empty predicate");
      }
      catch (IllegalArgumentException ex)
      {
        Util.Log("got expected IllegalArgumentException exception for empty predicate:");
        Util.Log(ex.Message);
      }


      try
      {
        Object result = region.SelectValue(QueryStatics.RegionQueries[0].Query, TimeSpan.FromSeconds(2200000));
        Assert.Fail("Expected IllegalArgumentException exception for invalid timeout");
      }
      catch (IllegalArgumentException ex)
      {
        Util.Log("got expected IllegalArgumentException exception for invalid timeout:");
        Util.Log(ex.Message);
      }

      try
      {
        Object result = region.SelectValue("bad predicate");
        Assert.Fail("Expected QueryException exception for wrong predicate");
      }
      catch (QueryException ex)
      {
        Util.Log("got expected QueryException exception for wrong predicate:");
        Util.Log(ex.Message);
      }
    }

    public void StepSixRQ()
    {
      bool ErrorOccurred = false;

      IRegion<object, object> region = CacheHelper.GetRegion<object, object>(QueryRegionNames[0]);

      int qryIdx = 0;

      foreach (QueryStrings qrystr in QueryStatics.RegionQueries)
      {
        if ((qrystr.Category != QueryCategory.Unsupported) || (qryIdx == 3))
        {
          qryIdx++;
          continue;
        }

        Util.Log("Evaluating unsupported query index {0}.", qryIdx);

        try
        {
          ISelectResults<object> results = region.Query<object>(qrystr.Query);

          Util.Log("Query # {0} expected exception did not occur", qryIdx);
          ErrorOccurred = true;
          qryIdx++;
        }
        catch (QueryException)
        {
          // ok, exception expected, do nothing.
          qryIdx++;
        }
        catch (Exception)
        {
          ErrorOccurred = true;
          Util.Log("FAIL: Query # {0} unexpected exception occured", qryIdx);
          qryIdx++;
        }
      }

      Assert.IsFalse(ErrorOccurred, "Query expected exceptions did not occur.");
    }

    //private void CreateRegions(object p, object USE_ACK, object endPoint1, bool p_4)
    //{
    //  throw new Exception("The method or operation is not implemented.");
    //}


    //public void CompareMap(CacheableHashMap map1, CacheableHashMap map2)
    //{
    //  if (map1.Count != map2.Count)
    //    Assert.Fail("Number of Keys dont match");
    //  if (map1.Count == 0) return;
    //  foreach (KeyValuePair<ICacheableKey, ISerializable> entry in map1)
    //  {
    //    ISerializable value;
    //    if (!(map2.TryGetValue(entry.Key,out value)))
    //    {
    //      Assert.Fail("Key was not found");
    //      return;
    //    }
    //    if(entry.Value.Equals(value))
    //    {
    //      Assert.Fail("Value was not found");
    //      return;
    //    }
    //  }
    //}

    //public void GetAllRegionQuery()
    //{
    //  IRegion<object, object> region0 = CacheHelper.GetVerifyRegion(QueryRegionNames[0]);
    //  IRegion<object, object> region1 = region0.GetSubRegion(QueryRegionNames[1] );
    //  IRegion<object, object> region2 = CacheHelper.GetVerifyRegion(QueryRegionNames[1]);
    //  IRegion<object, object> region3 = CacheHelper.GetVerifyRegion(QueryRegionNames[2]);
    //  IRegion<object, object> region4 = CacheHelper.GetVerifyRegion(QueryRegionNames[3]);
    //  string[] SecIds = Portfolio.SecIds;
    //  int NumSecIds = SecIds.Length;
    //  List<ICacheableKey> PosKeys = new List<ICacheableKey>();
    //  List<ICacheableKey> PortKeys = new List<ICacheableKey>();
    //  CacheableHashMap ExpectedPosMap = new CacheableHashMap();
    //  CacheableHashMap ExpectedPortMap = new CacheableHashMap();
    //  QueryHelper<object, object> qh = QueryHelper<object, object>.GetHelper(CacheHelper.DCache);
    //  int SetSize = qh.PositionSetSize;
    //  int NumSets = qh.PositionNumSets;
    //  for (int set = 1; set <= NumSets; set++)
    //  {
    //    for (int current = 1; current <= SetSize; current++)
    //    {
    //      CacheableKey PosKey  = "pos" + set + "-" + current;
    //      Position pos = new Position(SecIds[current % NumSecIds], current * 100 );
    //      PosKeys.Add(PosKey);
    //      ExpectedPosMap.Add(PosKey, pos);
    //    }
    //  }
    //  SetSize = qh.PortfolioSetSize;
    //  NumSets = qh.PortfolioNumSets;
    //  for (int set = 1; set <= NumSets; set++)
    //  {
    //    for (int current = 1; current <= SetSize; current++)
    //    {
    //      CacheableKey PortKey = "port" + set + "-" + current;
    //      Portfolio Port = new Portfolio(current,1);
    //      PortKeys.Add(PortKey);
    //      ExpectedPortMap.Add(PortKey, Port);
    //    }
    //  }
    //  CacheableHashMap ResMap = new CacheableHashMap();
    //  Dictionary<ICacheableKey, Exception> ExMap = new Dictionary<ICacheableKey, Exception>();
    //  region0.GetAll(PortKeys.ToArray(), ResMap, ExMap);
    //  CompareMap(ResMap, ExpectedPortMap);
    //  if (ExMap.Count != 0)
    //  {
    //    Assert.Fail("Expected No Exception");
    //  }
    //  ResMap.Clear();

    //  region1.GetAll(PosKeys.ToArray(), ResMap, ExMap);
    //  CompareMap(ResMap, ExpectedPosMap);
    //  if (ExMap.Count != 0)
    //  {
    //    Assert.Fail("Expected No Exception");
    //  }
    //  ResMap.Clear();
    //  region2.GetAll(PosKeys.ToArray(), ResMap, ExMap);
    //  CompareMap(ResMap, ExpectedPosMap);
    //  if (ExMap.Count != 0)
    //  {
    //    Assert.Fail("Expected No Exception");
    //  }
    //  ResMap.Clear();

    //  region3.GetAll(PortKeys.ToArray(), ResMap, ExMap);
    //  CompareMap(ResMap, ExpectedPortMap);
    //  if (ExMap.Count != 0)
    //  {
    //    Assert.Fail("Expected No Exception");
    //  }
    //  ResMap.Clear();

    //  region4.GetAll(PortKeys.ToArray(), ResMap, ExMap);
    //  CompareMap(ResMap, ExpectedPortMap);
    //  if (ExMap.Count != 0)
    //  {
    //    Assert.Fail("Expected No Exception");
    //  }
    //  ResMap.Clear();
    //}
    #endregion

    void runRemoteQueryRS()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client1.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client1.Call(StepTwo, m_isPdx);
      Util.Log("StepTwo complete.");

      m_client1.Call(StepThreeRS);
      Util.Log("StepThree complete.");

      m_client1.Call(StepFourRS);
      Util.Log("StepFour complete.");

      m_client1.Call(Close);

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runRemoteParamQueryRS()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client1.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client1.Call(StepTwo, m_isPdx);
      Util.Log("StepTwo complete.");

      m_client1.Call(StepThreePQRS);
      Util.Log("StepThree complete.");

      m_client1.Call(StepFourPQRS);
      Util.Log("StepFour complete.");

      m_client1.Call(Close);

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runRemoteQuerySS()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client2.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client2.Call(StepTwo, m_isPdx);
      Util.Log("StepTwo complete.");

      m_client2.Call(StepThreeSS);
      Util.Log("StepThree complete.");

      m_client2.Call(StepFourSS);
      Util.Log("StepFour complete.");

      //m_client2.Call(GetAllRegionQuery);

      m_client2.Call(Close);

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runRemoteParamQuerySS()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client2.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client2.Call(StepTwo, m_isPdx);
      Util.Log("StepTwo complete.");

      m_client2.Call(StepThreePQSS);
      Util.Log("StepThree complete.");

      m_client2.Call(StepFourPQSS);
      Util.Log("StepFour complete.");

      //m_client2.Call(GetAllRegionQuery);

      m_client2.Call(Close);

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runRemoteQueryFailover()
    {
      try
      {
        m_client1.Call(StepOneFailover, m_isPdx);
        Util.Log("StepOneFailover complete.");

        m_client1.Call(StepTwoFailover);
        Util.Log("StepTwoFailover complete.");

        m_client1.Call(Close);
        Util.Log("Client closed");
      }
      finally
      {
        m_client1.Call(CacheHelper.StopJavaServers);
        m_client1.Call(CacheHelper.StopJavaLocator, 1);
      }
    }

    void runRemoteParamQueryFailover()
    {
      try
      {
        m_client1.Call(StepOneFailover, m_isPdx);
        Util.Log("StepOneFailover complete.");

        m_client1.Call(StepTwoPQFailover);
        Util.Log("StepTwoPQFailover complete.");

        m_client1.Call(Close);
        Util.Log("Client closed");
      }
      finally
      {
        m_client1.Call(CacheHelper.StopJavaServers);
        m_client1.Call(CacheHelper.StopJavaLocator, 1);
      }
    }

    void runQueryExclusiveness()
    {
      CacheHelper.SetupJavaServers(true, "cacheserver_remoteoqlN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client1.Call(StepOneQE, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client1.Call(StepTwoQE);
      Util.Log("StepTwo complete.");

      m_client1.Call(Close);
      Util.Log("Client closed");

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runQueryTimeout()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client1.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client1.Call(StepTwoQT);
      Util.Log("StepTwo complete.");

      m_client1.Call(StepThreeQT);
      Util.Log("StepThree complete.");

      Thread.Sleep(150000); // sleep 2.5min to allow server query to complete

      m_client1.Call(StepFourQT);
      Util.Log("StepFour complete.");

      m_client1.Call(StepFiveQT);
      Util.Log("StepFive complete.");

      Thread.Sleep(60000); // sleep 1min to allow server query to complete

      m_client1.Call(StepSixQT);
      Util.Log("StepSix complete.");

      m_client1.Call(Close);
      Util.Log("Client closed");

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runParamQueryTimeout()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started. WITH PDX = " + m_isPdx);

      m_client1.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client1.Call(StepTwoQT);
      Util.Log("StepTwo complete.");

      m_client1.Call(StepThreePQT);
      Util.Log("StepThreePQT complete.");

      Thread.Sleep(60000); // sleep 1min to allow server query to complete

      m_client1.Call(StepFourPQT);
      Util.Log("StepFourPQT complete.");

      m_client1.Call(Close);
      Util.Log("Client closed");

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    void runRegionQuery()
    {
      CacheHelper.SetupJavaServers(true, "remotequeryN.xml");
      CacheHelper.StartJavaLocator(1, "GFELOC");
      Util.Log("Locator started");
      CacheHelper.StartJavaServerWithLocators(1, "GFECS1", 1);
      Util.Log("Cacheserver 1 started.");

      m_client2.Call(StepOne, CacheHelper.Locators, m_isPdx);
      Util.Log("StepOne complete.");

      m_client2.Call(StepTwo, m_isPdx);
      Util.Log("StepTwo complete.");

      //Extra Step
      //m_client1.Call(StepExtra);

      m_client2.Call(StepThreeRQ);
      Util.Log("StepThree complete.");

      m_client2.Call(StepFourRQ);
      Util.Log("StepFour complete.");

      m_client2.Call(StepFiveRQ);
      Util.Log("StepFive complete.");

      m_client2.Call(StepSixRQ);
      Util.Log("StepSix complete.");

      m_client2.Call(Close);
      Util.Log("Client closed");

      CacheHelper.StopJavaServer(1);
      Util.Log("Cacheserver 1 stopped.");

      CacheHelper.StopJavaLocator(1);
      Util.Log("Locator stopped");
    }

    static bool m_isPdx = false;

    [Test]
    public void RemoteQueryRSWithPdx()
    {
      m_isPdx = true;
      runRemoteQueryRS();
    }


		[Test]
		public void RemoteQueryRSWithoutPdx()
		{
			m_isPdx = false;
			runRemoteQueryRS();
		}

		[Test]
		public void RemoteParamQueryRSWithPdx()
    {
			m_isPdx = true;
			runRemoteParamQueryRS();

    }

		[Test]
		public void RemoteParamQueryRSWithoutPdx()
		{
			m_isPdx = false;
			runRemoteParamQueryRS();

		}

		[Test]
		public void RemoteQuerySSWithPdx()
    {
				m_isPdx = true;
				runRemoteQuerySS();

    }

		[Test]
		public void RemoteQuerySSWithoutPdx()
		{
			m_isPdx = false;
			runRemoteQuerySS();

		}

		[Test]
		public void RemoteParamQuerySSWithoutPdx()
    {

      m_isPdx = false;
      runRemoteParamQuerySS();

    }

		[Test]
		public void RemoteParamQuerySSWithPdx()
		{

			m_isPdx = true;
			runRemoteParamQuerySS();

		}

		[Test]
    public void RemoteQueryFailoverWithPdx()
    {
      m_isPdx = true;
      runRemoteQueryFailover();
    }

		[Test]
		public void RemoteQueryFailoverWithoutPdx()
		{
			m_isPdx = false;
			runRemoteQueryFailover();
		}

		[Test]
    [Ignore]
    public void RemoteParamQueryFailover()
    {
      for (int i = 0; i < 2; i++)
      {
        runRemoteParamQueryFailover();
        m_isPdx = true;
      }
      m_isPdx = false;
    }

    [Test]
    public void QueryExclusivenessWithoutPdx()
    {
			m_isPdx = false;
      runQueryExclusiveness();

    }


		[Test]
		public void QueryExclusivenessWithPdx()
		{
			m_isPdx = true;
			runQueryExclusiveness();
		}

		[Test]
		[Ignore]
    public void QueryTimeout()
    {
      for (int i = 0; i < 2; i++)
      {
        runQueryTimeout();
        m_isPdx = true;
      }
      m_isPdx = false;
    }

    [Test]
    [Ignore]
    public void ParamQueryTimeout()
    {
      for (int i = 0; i < 2; i++)
      {
        runParamQueryTimeout();
        m_isPdx = true;
      }
      m_isPdx = false;
    }

		[Test]
		public void RegionQueryWithPdx()
		{
			m_isPdx = true;
			runRegionQuery();
		}

		[Test]
    public void RegionQueryWithoutPdx()
    {
			m_isPdx = false;
      runRegionQuery();
    }

  }
}
