protected override IList <ITest> CreateTestInstances(object[] args)
        {
            var featureClass      = (IFeatureClass)args[0];
            var referenceClass    = (IFeatureClass)args[1];
            var referenceSubtypes = (int[])args[2];
            var featureClassRules = (string[])args[3];

            ConstrParams pars =
                ConstrParams.Create(featureClass, referenceSubtypes, featureClassRules);
            var notNearTest = new QaTopoNotNear(featureClass, referenceClass, pars.MaxNear,
                                                pars.FeatureClassNear,
                                                "0", 0, 0, is3D: false);

            if (pars.RightSideNears != null)
            {
                notNearTest.RightSideNears = pars.RightSideNears;
            }

            notNearTest.IgnoreNeighborCondition = pars.IgnoreNeighborCondition;
            notNearTest.UnconnectedLineCapStyle = LineCapStyle.Butt;

            var intersectTest =
                new QaIntersectsOther(featureClass, referenceClass, pars.IgnoreNeighborCondition);

            return(new List <ITest> {
                notNearTest, intersectTest
            });
        }
            public static ConstrParams Create(IFeatureClass featureClass,
                                              IList <int> referenceSubtypes,
                                              IList <string> featureClassRules)
            {
                string featureClassField   = ((ISubtypes)featureClass).SubtypeFieldName;
                string referenceClassField = ((ISubtypes)featureClass).SubtypeFieldName;

                double maxNear = 0;

                StringBuilder sbNear               = new StringBuilder();
                StringBuilder sbNearEnd            = new StringBuilder();
                StringBuilder sbRightSideNear      = new StringBuilder();
                StringBuilder sbRightSideNearEnd   = new StringBuilder();
                StringBuilder sbIgnore             = new StringBuilder();
                List <int>    featureClassSubtypes = new List <int>();
                bool          anyRightSide         = false;

                foreach (string featureClassRule in featureClassRules)
                {
                    string[] ruleParts = featureClassRule.Split(';');
                    if (!int.TryParse(ruleParts[0], out int subtype))
                    {
                        throw new InvalidOperationException(
                                  $"invalid subtype '{ruleParts[0]}' in featureClassRule '{featureClassRule}' ");
                    }

                    featureClassSubtypes.Add(subtype);

                    // handle default near
                    if (!double.TryParse(ruleParts[1], out double near))
                    {
                        throw new InvalidOperationException(
                                  $"invalid near distance '{ruleParts[1]}' in featureClassRule '{featureClassRule}' ");
                    }

                    maxNear = Math.Max(maxNear, near);
                    sbNear.Append($"IIF({featureClassField}={subtype},{near},");
                    sbNearEnd.Append(")");

                    // handle right side near
                    double rightSideNear;
                    if (!string.IsNullOrWhiteSpace(ruleParts[2]))
                    {
                        if (!double.TryParse(ruleParts[2], out rightSideNear))
                        {
                            throw new InvalidOperationException(
                                      $"invalid right side near distance '{ruleParts[2]}' in featureClassRule '{featureClassRule}' ");
                        }

                        anyRightSide = true;
                        maxNear      = Math.Max(maxNear, rightSideNear);
                    }
                    else
                    {
                        rightSideNear = near;
                    }

                    sbRightSideNear.Append($"IIF({featureClassField}={subtype},{rightSideNear},");
                    sbRightSideNearEnd.Append(")");

                    StringBuilder sbRefIgnore = new StringBuilder();
                    foreach (int overlapIndex in
                             LineNotNearPolyOverlapConfigurator.EnumOverlapIndices(
                                 ruleParts, featureClassRule, referenceSubtypes))
                    {
                        if (!int.TryParse(ruleParts[overlapIndex], out int overlapKey))
                        {
                            throw new InvalidOperationException(
                                      $"invalid rule '{ruleParts[overlapIndex]} in featureClassRule '{featureClassRule}'");
                        }

                        if (overlapKey == 0)
                        {
                            if (sbRefIgnore.Length > 0)
                            {
                                sbRefIgnore.Append(",");
                            }

                            sbRefIgnore.Append(
                                $"{referenceSubtypes[overlapIndex - ReferenceSubtypesStart]}");
                        }
                    }

                    if (sbRefIgnore.Length > 0)
                    {
                        if (sbIgnore.Length > 0)
                        {
                            sbIgnore.Append(" OR ");
                        }

                        sbIgnore.Append(
                            $"(G1.{featureClassField} = {subtype} AND G2.{referenceClassField} IN ({sbRefIgnore}))");
                    }
                }

                // prepare and create test parameters
                if (sbIgnore.Length > 0)
                {
                    sbIgnore.Append(" OR ");
                }

                string fcSubtypesList =
                    string.Concat(featureClassSubtypes.Select(x => $"{x},")).Trim(',');
                string refSubtypesList =
                    string.Concat(referenceSubtypes.Select(x => $"{x},")).Trim(',');

                sbIgnore.Append($"(G1.{featureClassField} NOT IN ({fcSubtypesList})");
                sbIgnore.Append($" OR G2.{referenceClassField} NOT IN ({refSubtypesList}))");

                ConstrParams pars = new ConstrParams
                {
                    MaxNear          = maxNear,
                    FeatureClassNear = $"{sbNear} 0 {sbNearEnd}",
                    RightSideNears   = anyRightSide
                                                                                     ? new List <string>
                    {
                        $"{sbRightSideNear} null {sbRightSideNearEnd}",
                        "0"
                    }
                                                                                     : null,
                    IgnoreNeighborCondition = $"{sbIgnore}"
                };

                return(pars);
            }