public void TestFindAddressCandidatesCannotMatchAddress(string address)
        {
            BindRunTime();

            // Get the input from the IPropertySet
            object names = null;
            object values = null;

            IPropertySet addressObj = new PropertySetClass();
            names = new string[] { "Single Line Address" };
            // Get centre point of Envelope for geocode location
            // Workaround for currnet non Point geometry issue
            values = new object[] { address };

            addressObj.SetProperties(names, values);

            BNG_Locator bng = new BNG_Locator();
            IArray matches = bng.FindAddressCandidates(addressObj);
            Assert.IsTrue(matches.Count == 0);
        }
        /// <summary>
        /// Generate an address based on a point.
        /// </summary>
        /// <param name="location"></param>
        /// <param name="returnIntersection"></param>
        /// <returns></returns>
        public override IPropertySet ReverseGeocode(IPoint location, bool returnIntersection)
        {
            _log.Debug("IReverseGeocode ReverseGeocode");
            string matchText;
            IPropertySet reverseGeocodedResult = new PropertySetClass();
            Type factoryType = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
            System.Object obj = Activator.CreateInstance(factoryType);
            var srf = obj as ISpatialReferenceFactory3;
            var wgs84GCS = srf.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);

            // Sometimes LatLong is incorrectly identified as BNG so it must be checked
            if ((location.X > -9 && location.X < 2) && (location.Y > 49 && location.Y < 61))
            {
                location.SpatialReference = wgs84GCS;
            }

            // Only supports coords in WGS 84 or BNG
            if (location.SpatialReference.Name == "GCS_WGS_1984")
            {
                #region Project coordinates to BNG accurately

                // Create Transformation from WGS84 to OSGB86
                var geoTrans = srf.CreateGeoTransformation((int)esriSRGeoTransformationType.esriSRGeoTransformation_OSGB1936_To_WGS1984Petrol) as IGeoTransformation;

                ISpatialReference fromSpatialReference;
                ISpatialReference toSpatialReference;
                geoTrans.GetSpatialReferences(out fromSpatialReference, out toSpatialReference);

                // Use correct coord systems to ensure accuracy
                var bngPCS = srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_BritishNationalGrid);
                if ((wgs84GCS.FactoryCode != toSpatialReference.FactoryCode)
                    || (bngPCS.GeographicCoordinateSystem.FactoryCode != fromSpatialReference.FactoryCode))
                {
                    throw new Exception("invalid geotransformation");
                }

                IGeometry5 geometry;
                geometry = location as IGeometry5;
                geometry.SpatialReference = wgs84GCS;

                geometry.ProjectEx(bngPCS, esriTransformDirection.esriTransformReverse, geoTrans, false, 0.0, 0.0);
                location = geometry as IPoint;

                #endregion
            }
            else if (location.SpatialReference.Name != "British_National_Grid")
            {
                // Unaccepted spatial reference, do not process
                return reverseGeocodedResult;
            }

            TranslateGridReference translate = new TranslateGridReference();
            // Translate the BNG coords to a British Grid Reference
            matchText = translate.GetGridReference(location);
            object names = null;
            object values = null;

            // The values being returned must include a geometry, any extra info fields ("X", "Y", "Addr_type") and at least
            // one field with the same name as an input field, "BNG" in this case, to hold the result fields, mathcText in this case
            names = new string[] { "Shape", "X Field", "Y Field", "BNG" , "Addr_type", "Match_addr" };
            values = new object[] { location, location.X, location.Y, matchText.ToString(), "BNG", matchText.ToString() };

            reverseGeocodedResult.SetProperties(names, values);

            return reverseGeocodedResult;
        }
        /// <summary>
        /// Uses the FindAddressCandidates method to geocode a single address
        /// </summary>
        /// <param name="address">Input address</param>
        /// <returns>IPropertySet that contains the matched address</returns>
        public virtual IPropertySet MatchAddress(IPropertySet address)
        {
            _log.Debug("IAddressGeocoding MatchAddress");
              IPropertySet resultSet = new PropertySetClass();
              try
              {
              IArray addressCandidates = FindAddressCandidates(address);
              if (addressCandidates.Count < 1)
                  throw new Exception();

              resultSet = addressCandidates.get_Element(0) as IPropertySet;

              object names;
              object values;
              // Get the name and value of all the properties in the property set
              resultSet.GetAllProperties(out names, out values);
              String[] nameArray = names as String[];
              object[] valueArray = values as object[];

              _log.Debug("MatchAddress Input address columns:" + string.Concat(nameArray));
              // Add the Status Field to the Result
              List<string> matchNames = new List<string>(nameArray);
              List<object> matchValues = new List<object>(valueArray);
              matchNames.Insert(1, "Status");
              matchValues.Insert(1, "M");

              // Set the field names and values for the matched address
              names = matchNames.ToArray() as object;
              values = matchValues.ToArray() as object;
              resultSet.SetProperties(names, values);

              return resultSet;
              }
              catch (Exception ex)
              {
              _log.Error("An error ocurred during MatchAddress: " + ex.Message);

              // Return an empty address match to prevent errors
              IGeometry emptyPoint = new PointClass() as IGeometry;
              emptyPoint.SetEmpty();
              resultSet.SetProperties(new string[] { "Shape", "Status", "Score", "Match_addr" },
                                          new object[] { emptyPoint, "U", null, null });
              return resultSet;
              }
        }
        /// <summary>
        /// This method is called when a query is made to the locator. 
        /// This must be implemented in such a way that Single and Multi line searches can be preformaed
        /// </summary>
        /// <param name="address">Review code for the structure of this property set</param>
        /// <returns>A single-line array containing a property set. Review code for the structure of this property set</returns>
        public override IArray FindAddressCandidates(IPropertySet address)
        {
            _log.Debug("BNGLocator  IAddressCandidates FindAddressCandidates");
            IArray addressCandidates = new ArrayClass();

            // Get the input from the IPropertySet
            object names = null;
            object values = null;

            address.GetAllProperties(out names, out values);

            string[] nameArray = (string[])names;
            object[] valueArray = (object[])values;

            _log.Debug("Input address columns:" + string.Concat( nameArray));

            //make sure there is at least one value
            if (nameArray.Length > 0)
            {
                string addressValue;

                if(nameArray.Length == 1)
                    addressValue = valueArray[0].ToString();
                else
                    addressValue = valueArray[0].ToString() + "," + valueArray[1].ToString();

                _log.Debug("Lookup Value:" + addressValue);

                Envelope enve = DoMatchLookup(addressValue);
                // Get centre point of Envelope for geocode location
                // ONLY Point geometries can be returned successfully
                Point point = CentrePoint(enve);

                if (point != null)
                {
                    // Ensure spatial reference is set on this envelope returned by the search function
                    (point as IGeometry).SpatialReference = base.m_spatialReference;

                    // Build the required output array
                    IPropertySet match = new PropertySetClass();
                    names = new string[] { "Shape", "Status", "Score", "X", "Y", "XMin", "YMin", "XMax", "YMax", "Match_addr", "Addr_type" };
                    values = new object[] { point, "M", 100, point.X, point.Y, enve.XMin, enve.YMin, enve.XMax, enve.YMax, addressValue.ToUpper(), "BNG" };

                    match.SetProperties(names, values);
                    addressCandidates.Add(match);
                }
            }

            return addressCandidates;
        }