diff --git a/geoentitylinker-addon/pom.xml b/geoentitylinker-addon/pom.xml
new file mode 100644
index 0000000..6fd5059
--- /dev/null
+++ b/geoentitylinker-addon/pom.xml
@@ -0,0 +1,66 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.opennlp</groupId>
+    <artifactId>opennlp</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath>../opennlp/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>geoentitylinker-addon</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+  <name>geoentitylinker-addon</name>
+
+  <url>http://maven.apache.org</url>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-core</artifactId>
+      <version>4.5.0</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-analyzers-common</artifactId>
+      <version>4.5.0</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-queryparser</artifactId>
+      <version>4.5.0</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.opennlp</groupId>
+      <artifactId>opennlp-tools</artifactId>
+      <version>1.6.0-SNAPSHOT</version>
+      <optional>true</optional>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContext.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContext.java
new file mode 100644
index 0000000..bc6d787
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContext.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+
+/**
+ * Finds instances of country mentions in a String, typically a document text.
+ * Used to boost or degrade scoring of linked geo entities
+ *
+ */
+public class CountryContext {
+
+ 
+  private List<CountryContextEntry> countrydata;
+  private Map<String, Set<String>> nameCodesMap = new HashMap<String, Set<String>>();
+  private Map<String, Set<Integer>> countryMentions = new HashMap<String, Set<Integer>>();
+  private Set<CountryContextEntry> countryHits = new HashSet<>();
+
+  public CountryContext() {
+  }
+
+  public Map<String, Set<Integer>> getCountryMentions() {
+    return countryMentions;
+  }
+
+  public Set<CountryContextEntry> getCountryHits() {
+    return countryHits;
+  }
+
+  public Map<String, Set<String>> getNameCodesMap() {
+    return nameCodesMap;
+  }
+
+  public void setNameCodesMap(Map<String, Set<String>> nameCodesMap) {
+    this.nameCodesMap = nameCodesMap;
+  }
+
+  /**
+   * Finds mentions of countries based on a list from MySQL stored procedure
+   * called getCountryList. This method finds country mentions in documents,
+   * which is an essential element of the scoring that is done for geo
+   * linkedspans. Lazily loads the list from the database.
+   *
+   * @param docText    the full text of the document
+   * @param properties EntityLinkerProperties for getting database connection
+   * @return
+   */
+  public Map<String, Set<Integer>> regexfind(String docText, EntityLinkerProperties properties) {
+    countryMentions = new HashMap<>();
+    nameCodesMap.clear();
+    try {
+
+      if (countrydata == null) {
+        countrydata = getCountryContextFromFile(properties);
+        //   countrydata = getCountryData(properties);
+      }
+      for (CountryContextEntry entry : countrydata) {
+        Pattern regex = Pattern.compile(entry.getFull_name_nd_ro().trim(), Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+        Matcher rs = regex.matcher(docText);
+        String code = entry.getCc1().toLowerCase();
+
+        boolean found = false;
+        while (rs.find()) {
+          found = true;
+          Integer start = rs.start();
+          String hit = rs.group().toLowerCase();
+          if (countryMentions.containsKey(code)) {
+            countryMentions.get(code).add(start);
+          } else {
+            Set<Integer> newset = new HashSet<Integer>();
+            newset.add(start);
+            countryMentions.put(code, newset);
+          }
+          if (!hit.equals("")) {
+            if (this.nameCodesMap.containsKey(hit)) {
+              nameCodesMap.get(hit).add(code);
+            } else {
+              HashSet<String> newset = new HashSet<String>();
+              newset.add(code);
+              nameCodesMap.put(hit, newset);
+            }
+          }
+        }
+        if (found) {
+          countryHits.add(entry);
+        }
+
+      }
+
+    } catch (Exception ex) {
+      Logger.getLogger(CountryContext.class.getName()).log(Level.SEVERE, null, ex);
+    }
+
+
+    return countryMentions;
+  }
+
+  private List<CountryContextEntry> getCountryContextFromFile(EntityLinkerProperties properties) {
+    List<CountryContextEntry> entries = new ArrayList<>();
+    String path = "";// properties.getProperty("geoentitylinker.countrycontext.filepath", "");
+    BufferedReader reader;
+
+    try {
+      path = properties.getProperty("opennlp.geoentitylinker.countrycontext.filepath", "");
+
+      reader = new BufferedReader(new FileReader(path));
+
+      while (reader.read() != -1) {
+        String line = reader.readLine();
+        String[] values = line.split("\t");
+        if (values.length != 4) {
+          throw new IOException("improperly formatted country context file");
+        }
+        CountryContextEntry entry = new CountryContextEntry();
+        // rc,cc1, full_name_nd_ro,dsg
+        entry.setRc(values[0].toLowerCase());
+        entry.setCc1(values[1].toLowerCase());
+        entry.setFull_name_nd_ro(values[2].toLowerCase());
+        entry.setDsg(values[3].toLowerCase());
+        entries.add(entry);
+      }
+      reader.close();
+    } catch (IOException e) {
+      System.err.println(e);
+    }
+    return entries;
+
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContextEntry.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContextEntry.java
new file mode 100644
index 0000000..61cfcbb
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContextEntry.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.Objects;
+
+/**
+ *Stores a tuple from mysql that is used to find country mentions in document text.
+ *
+ */
+public class CountryContextEntry {
+  /*
+   * rc,cc1, full_name_nd_ro,dsg
+   */
+
+  private String rc;
+  private String cc1;
+  private String full_name_nd_ro;
+  private String dsg;
+  private String provCode;
+  public CountryContextEntry() {
+  }
+
+  public CountryContextEntry(String rc, String cc1, String full_name_nd_ro, String dsg) {
+    this.rc = rc;
+    this.cc1 = cc1;
+    this.full_name_nd_ro = full_name_nd_ro;
+    this.dsg = dsg;
+  }
+
+  public String getProvCode() {
+    return provCode;
+  }
+
+  public void setProvCode(String provCode) {
+    this.provCode = provCode;
+  }
+
+  public String getRc() {
+    return rc;
+  }
+
+  public void setRc(String rc) {
+    this.rc = rc;
+  }
+
+  public String getCc1() {
+    return cc1;
+  }
+
+  public void setCc1(String cc1) {
+    this.cc1 = cc1;
+  }
+
+  public String getFull_name_nd_ro() {
+    return full_name_nd_ro;
+  }
+
+  public void setFull_name_nd_ro(String full_name_nd_ro) {
+    this.full_name_nd_ro = full_name_nd_ro;
+  }
+
+  public String getDsg() {
+    return dsg;
+  }
+
+  public void setDsg(String dsg) {
+    this.dsg = dsg;
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = 7;
+    hash = 17 * hash + Objects.hashCode(this.rc);
+    hash = 17 * hash + Objects.hashCode(this.cc1);
+    hash = 17 * hash + Objects.hashCode(this.full_name_nd_ro);
+    hash = 17 * hash + Objects.hashCode(this.dsg);
+    return hash;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final CountryContextEntry other = (CountryContextEntry) obj;
+    if (!Objects.equals(this.rc, other.rc)) {
+      return false;
+    }
+    if (!Objects.equals(this.cc1, other.cc1)) {
+      return false;
+    }
+    if (!Objects.equals(this.full_name_nd_ro, other.full_name_nd_ro)) {
+      return false;
+    }
+    if (!Objects.equals(this.dsg, other.dsg)) {
+      return false;
+    }
+    return true;
+  }
+  
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContextHit.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContextHit.java
new file mode 100644
index 0000000..3df2392
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryContextHit.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+/**
+ *Stores a "hit" on a country and the start and end of the hit
+
+ */
+public class CountryContextHit {
+
+  private String countryCode;
+  private int start;
+  private int end;
+
+  public CountryContextHit() {
+  }
+
+  public CountryContextHit(String countryCode, int start, int end) {
+    this.countryCode = countryCode;
+    this.start = start;
+    this.end = end;
+  }
+
+  public String getCountryCode() {
+    return countryCode;
+  }
+
+  public void setCountryCode(String countryCode) {
+    this.countryCode = countryCode;
+  }
+
+  public int getStart() {
+    return start;
+  }
+
+  public void setStart(int start) {
+    this.start = start;
+  }
+
+  public int getEnd() {
+    return end;
+  }
+
+  public void setEnd(int end) {
+    this.end = end;
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryProximityScorer.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryProximityScorer.java
new file mode 100644
index 0000000..48ebccf
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/CountryProximityScorer.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.entitylinker.domain.BaseLink;
+import opennlp.tools.entitylinker.domain.LinkedSpan;
+import opennlp.tools.util.Span;
+
+/**
+ * Scores toponyms based on country context as well as fuzzy string matching
+ */
+public class CountryProximityScorer implements LinkedEntityScorer<CountryContext> {
+
+  private Map<String, Set<String>> nameCodesMap;
+  String dominantCode = "";
+
+  @Override
+  public void score(List<LinkedSpan> linkedSpans, String docText, Span[] sentenceSpans, EntityLinkerProperties properties, CountryContext additionalContext) {
+
+    score(linkedSpans, additionalContext.getCountryMentions(), additionalContext.getNameCodesMap(), docText, sentenceSpans, 1000);
+
+  }
+
+  /**
+   * Assigns a score to each BaseLink in each linkedSpan's set of N best
+   * matches. Currently the scoring indicates the probability that the toponym
+   * is correct based on the country context in the document and fuzzy string
+   * matching
+   *
+   * @param linkedData     the linked spans, holds the Namefinder results, and
+   *                       the list of BaseLink for each
+   * @param countryHits    all the country mentions in the document
+   * @param nameCodesMap   maps a country indicator name to a country code. Used
+   *                       to determine if the namefinder found the same exact
+   *                       toponym the country context did. If so the score is
+   *                       boosted due to the high probability that the
+   *                       NameFinder actually "rediscovered" a country
+   * @param docText        the full text of the document...not used in this
+   *                       default implementation
+   * @param sentences      the sentences that correspond to the doc text.
+   * @param maxAllowedDist a constant that is used to determine which country
+   *                       mentions, based on proximity within the text, should
+   *                       be used to score the Named Entity.
+   * @return
+   */
+  public List<LinkedSpan> score(List<LinkedSpan> linkedData, Map<String, Set<Integer>> countryHits, Map<String, Set<String>> nameCodesMap, String docText, Span[] sentences, Integer maxAllowedDist) {
+    this.nameCodesMap = nameCodesMap;
+    setDominantCode(countryHits);
+    for (LinkedSpan<BaseLink> linkedspan : linkedData) {
+
+      linkedspan = simpleProximityAnalysis(sentences, countryHits, linkedspan, maxAllowedDist);
+    }
+    return linkedData;
+  }
+
+  /**
+   * sets class level variable to a code based on the number of mentions
+   *
+   * @param countryHits
+   */
+  private void setDominantCode(Map<String, Set<Integer>> countryHits) {
+    int hits = -1;
+    for (String code : countryHits.keySet()) {
+      if (countryHits.get(code).size() > hits) {
+        hits = countryHits.get(code).size();
+        dominantCode = code;
+      }
+    }
+  }
+
+  /**
+   * Generates distances from each country mention to the span's location in the
+   * doc text. Ultimately an attempt to ensure that ambiguously named toponyms
+   * are resolved to the correct country and coordinate.
+   *
+   * @param sentences
+   * @param countryHits
+   * @param span
+   * @return
+   */
+  private LinkedSpan<BaseLink> simpleProximityAnalysis(Span[] sentences, Map<String, Set<Integer>> countryHits, LinkedSpan<BaseLink> span, Integer maxAllowedDistance) {
+    Double score = 0.0;
+    //get the index of the actual span, begining of sentence
+    //should generate tokens from sentence and create a char offset...
+    //could have large sentences due to poor sentence detection or wonky doc text
+    int sentenceIdx = span.getSentenceid();
+    int sentIndexInDoc = sentences[sentenceIdx].getStart();
+    /**
+     * create a map of all the span's proximal country mentions in the document
+     * Map< countrycode, set of <distances from this NamedEntity>>
+     */
+    Map<String, Set<Integer>> distancesFromCodeMap = new HashMap<String, Set<Integer>>();
+    //map = Map<countrycode, Set <of distances this span is from all the mentions of the code>>
+    for (String cCode : countryHits.keySet()) {
+//iterate over all the regex start values and calculate an offset
+      for (Integer cHit : countryHits.get(cCode)) {
+        Integer absDist = Math.abs(sentIndexInDoc - cHit);
+        //only include near mentions based on a heuristic
+        //TODO make this a property
+        //  if (absDist < maxAllowedDistance) {
+        if (distancesFromCodeMap.containsKey(cCode)) {
+          distancesFromCodeMap.get(cCode).add(absDist);
+        } else {
+          HashSet<Integer> newset = new HashSet<Integer>();
+          newset.add(absDist);
+          distancesFromCodeMap.put(cCode, newset);
+        }
+      }
+
+      //}
+    }
+    //we now know how far this named entity is from every country mention in the document
+
+    /**
+     * the gaz matches that have a country code that have mentions in the doc
+     * that are closest to the Named Entity should return the best score.
+     * Analyzemap generates a likelihood score that the toponym from the gaz is
+     * referring to one of the countries, i.e, Map<countrycode, prob that this
+     * span is referring to the toponym form this code key>
+     */
+    Map<String, Double> scoreMap = analyzeMap(distancesFromCodeMap, sentences, span);
+    for (BaseLink link : span.getLinkedEntries()) {
+      //getItemParentId is the country code
+      String spanCountryCode = link.getItemParentID();
+      if (scoreMap.containsKey(spanCountryCode)) {
+
+        score = scoreMap.get(spanCountryCode);
+        ///does the name extracted match a country name?
+        if (nameCodesMap.containsKey(link.getItemName().toLowerCase())) {
+          //if so, is it the correct country code for that name?
+          if (nameCodesMap.get(link.getItemName().toLowerCase()).contains(link.getItemParentID())) {
+            //boost the score becuase it is likely that this is the location in the text, so add 50% to the score or set to 1
+            //TODO: make this multiplier configurable
+            score = (score + .75) > 1.0 ? 1d : (score + .75);
+
+            if (link.getItemParentID().equals(dominantCode)) {
+              score = (score + .25) > 1.0 ? 1d : (score + .25);
+            }
+          }
+        }
+      }
+      link.getScoreMap().put("countrycontext", score);
+    }
+    return span;
+  }
+
+  /**
+   * takes a map of distances from the NE to each country mention and generates
+   * a map of scores for each country code. The map is then correlated to teh
+   * correlated to the code of the BaseLink parentid for retrieval. Then the
+   * score is added to the overall.
+   *
+   * @param distanceMap
+   * @param sentences
+   * @param span
+   * @return
+   */
+  private Map<String, Double> analyzeMap(Map<String, Set<Integer>> distanceMap, Span[] sentences, LinkedSpan<BaseLink> span) {
+
+    Map<String, Double> scoreMap = new HashMap<String, Double>();
+    if (distanceMap.isEmpty()) {
+      return scoreMap;
+    }
+    TreeSet<Integer> all = new TreeSet<Integer>();
+    for (String key : distanceMap.keySet()) {
+      all.addAll(distanceMap.get(key));
+    }
+    //get min max for normalization, this could be more efficient
+
+    Integer min = all.first();
+    Integer max = all.last();
+    if (min == max) {
+      min = 0;
+    }
+    for (String key : distanceMap.keySet()) {
+
+      TreeSet<Double> normalizedDistances = new TreeSet<Double>();
+      for (Integer i : distanceMap.get(key)) {
+        Double norm = normalize(i, min, max);
+        //reverse the normed distance so low numbers (closer) are better
+        //this could be improved with a "decaying " function using an imcreaseing negative exponent
+        Double reverse = Math.abs(norm - 1);
+        normalizedDistances.add(reverse);
+      }
+
+
+      List<Double> doubles = new ArrayList<Double>(normalizedDistances);
+      scoreMap.put(key, slidingDistanceAverage(doubles));
+    }
+    return scoreMap;
+  }
+
+  /**
+   * this method is an attempt to make closer clusters of mentions group
+   * together to smooth out the average, so one distant outlier does not kill
+   * the score for an obviously good hit. More elegant solution is possible
+   * using Math.pow, and making the score decay with distance by using an
+   * increasing negative exponent
+   *
+   * @param normDis the normalized and sorted set of distances as a list
+   * @return
+   */
+  private Double slidingDistanceAverage(List<Double> normDis) {
+    List<Double> windowOfAverages = new ArrayList<Double>();
+
+    if (normDis.size() < 3) {
+      windowOfAverages.addAll(normDis);
+    } else {
+
+      for (int i = 0; i < normDis.size() - 1; i++) {
+        double a = normDis.get(i);
+        double b = normDis.get(i + 1);
+        windowOfAverages.add((a + b) / 2);
+
+      }
+    }
+    double sum = 0d;
+    for (double d : windowOfAverages) {
+      sum += d;
+    }
+    double result = sum / windowOfAverages.size();
+    //TODO: ++ prob when large amounts of mentions for a code
+    //System.out.println("avg of window:" + result);
+    return result;
+  }
+
+  /**
+   * transposes a value within one range to a relative value in a different
+   * range. Used to normalize distances in this class.
+   *
+   * @param valueToNormalize the value to place within the new range
+   * @param minimum          the min of the set to be transposed
+   * @param maximum          the max of the set to be transposed
+   * @return
+   */
+  private Double normalize(int valueToNormalize, int minimum, int maximum) {
+    Double d = (double) ((1 - 0) * (valueToNormalize - minimum)) / (maximum - minimum) + 0;
+    d = d == null ? 0d : d;
+    return d;
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/FuzzyStringMatchScorer.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/FuzzyStringMatchScorer.java
new file mode 100644
index 0000000..29cf58b
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/FuzzyStringMatchScorer.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.entitylinker.domain.BaseLink;
+import opennlp.tools.entitylinker.domain.LinkedSpan;
+import opennlp.tools.ngram.NGramGenerator;
+import opennlp.tools.util.Span;
+
+/**
+ *
+ * Generates scores for string comparisons.
+ */
+public class FuzzyStringMatchScorer implements LinkedEntityScorer<CountryContext> {
+
+  @Override
+  public void score(List<LinkedSpan> linkedSpans, String docText, Span[] sentenceSpans, EntityLinkerProperties properties, CountryContext additionalContext) {
+    for (LinkedSpan<BaseLink> linkedSpan : linkedSpans) {
+      for (BaseLink link : linkedSpan.getLinkedEntries()) {
+        Double dice = getDiceCoefficient(linkedSpan.getSearchTerm().toLowerCase().replace(" ", ""), link.getItemName().toLowerCase().replace(" ", ""), 2);
+        link.getScoreMap().put("dice", dice);
+        Double ld = (double) getLevenshteinDistance(linkedSpan.getSearchTerm().toLowerCase().replace(" ", ""), link.getItemName().toLowerCase().replace(" ", ""));
+        link.getScoreMap().put("levenshtein", ld);
+      }
+    }
+
+
+  }
+
+  /**
+   * Generates a score based on an overlap of nGrams between two strings using
+   * the DiceCoefficient technique.
+   *
+   * @param s1     first string
+   * @param s2     second string
+   * @param nGrams number of chars in each gram
+   * @return
+   */
+  public double getDiceCoefficient(String s1, String s2, int nGrams) {
+    if (s1.equals("") || s1.equals("")) {
+      return 0d;
+    }
+    List<String> s1Grams = NGramGenerator.generate(s1.toCharArray(), nGrams, "");
+    List<String> s2Grams = NGramGenerator.generate(s2.toCharArray(), nGrams, "");
+
+    Set<String> overlap = new HashSet<String>(s1Grams);
+    overlap.retainAll(s2Grams);
+    double totcombigrams = overlap.size();
+
+    return (2 * totcombigrams) / (s1Grams.size() + s2Grams.size());
+  }
+
+  private int minimum(int a, int b, int c) {
+    return Math.min(Math.min(a, b), c);
+  }
+
+  public int getLevenshteinDistance(CharSequence str1,
+          CharSequence str2) {
+    int[][] distance = new int[str1.length() + 1][str2.length() + 1];
+
+    for (int i = 0; i <= str1.length(); i++) {
+      distance[i][0] = i;
+    }
+    for (int j = 1; j <= str2.length(); j++) {
+      distance[0][j] = j;
+    }
+
+    for (int i = 1; i <= str1.length(); i++) {
+      for (int j = 1; j <= str2.length(); j++) {
+        distance[i][j] = minimum(
+                distance[i - 1][j] + 1,
+                distance[i][j - 1] + 1,
+                distance[i - 1][j - 1] + ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1));
+      }
+    }
+
+    return distance[str1.length()][str2.length()];
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerEntry.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerEntry.java
new file mode 100644
index 0000000..f375dcf
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerEntry.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.HashMap;
+import java.util.Map;
+import opennlp.tools.entitylinker.domain.BaseLink;
+
+/**
+ *
+ * Stores a record from a geographic placenames gazateer
+ */
+public class GazateerEntry extends BaseLink {
+
+  private Double latitude;
+  private Double longitude;
+  private String source;
+  private String indexID;
+  private Map<String, String> indexData=new HashMap<>();
+
+  public String getIndexID() {
+    return indexID;
+  }
+
+  public void setIndexID(String indexID) {
+    this.indexID = indexID;
+  }
+
+  public Double getLatitude() {
+    return latitude;
+  }
+
+  public void setLatitude(Double latitude) {
+    this.latitude = latitude;
+  }
+
+  public Double getLongitude() {
+    return longitude;
+  }
+
+  public void setLongitude(Double longitude) {
+    this.longitude = longitude;
+  }
+
+  public String getSource() {
+    return source;
+  }
+
+  public void setSource(String source) {
+    this.source = source;
+  }
+
+  public Map<String, String> getIndexData() {
+    return indexData;
+  }
+
+  public void setIndexData(Map<String, String> indexData) {
+    this.indexData = indexData;
+  }
+  
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerIndexer.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerIndexer.java
new file mode 100644
index 0000000..5e72a9f
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerIndexer.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.ar.ArabicAnalyzer;
+import org.apache.lucene.analysis.fa.PersianAnalyzer;
+import org.apache.lucene.analysis.ru.RussianAnalyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.analysis.th.ThaiAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.MMapDirectory;
+import org.apache.lucene.util.Version;
+
+/**
+ *
+ * Creates two lucene indexes, geonames and usgs for use in GeoEntityLinker
+ */
+public class GazateerIndexer {
+
+  public GazateerIndexer() {
+    loadAnalyzerMap();
+  }
+  Map<String, Analyzer> languageAnalyzerMap = new HashMap<>();
+
+  public static interface Separable {
+
+    String getSeparator();
+  }
+
+  public enum GazType implements Separable {
+
+    GEONAMES {
+      @Override
+      public String toString() {
+        return "/opennlp_geoentitylinker_geonames_idx";
+      }
+
+      @Override
+      public String getSeparator() {
+        return "\t";
+      }
+    },
+    USGS {
+      @Override
+      public String toString() {
+        return "/opennlp_geoentitylinker_usgsgaz_idx";
+      }
+
+      @Override
+      public String getSeparator() {
+        return "\\|";
+      }
+    }
+  }
+
+  public void index(File outputIndexDir, File gazateerInputData, GazType type) throws Exception {
+    if (!outputIndexDir.isDirectory()) {
+      throw new IllegalArgumentException("outputIndexDir must be a directory.");
+    }
+
+    String indexloc = outputIndexDir + type.toString();
+    Directory index = new MMapDirectory(new File(indexloc));
+
+    Analyzer a = new StandardAnalyzer(Version.LUCENE_45);
+    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_45, a);
+
+    IndexWriter w = new IndexWriter(index, config);
+
+    readFile(gazateerInputData, w, type);
+    w.commit();
+    w.close();
+
+  }
+
+  public void readFile(File gazateerInputData, IndexWriter w, GazType type) throws Exception {
+    BufferedReader reader = new BufferedReader(new FileReader(gazateerInputData));
+    List<String> fields = new ArrayList<String>();
+    int counter = 0;
+    int langCodeIndex = 0;
+    System.out.println("reading gazateer data from file...........");
+    while (reader.read() != -1) {
+      String line = reader.readLine();
+      String[] values = line.split(type.getSeparator());
+      if (counter == 0) {
+        // build fields
+        for (int i = 0; i < values.length; i++) {
+          String columnName = values[i];
+          fields.add(columnName.replace("»¿", "").trim());
+          if (columnName.toLowerCase().equals("lc")) {
+            langCodeIndex = i;
+          }
+        }
+
+
+      } else {
+        Document doc = new Document();
+        for (int i = 0; i < fields.size() - 1; i++) {
+          doc.add(new TextField(fields.get(i), values[i], Field.Store.YES));
+        }
+        if (type == GazType.GEONAMES) {
+          /**
+           * see if the map contains a language specific analyzer
+           */
+          if (languageAnalyzerMap.containsKey(values[langCodeIndex])) {
+            /*
+             * if so retrieve it from the map
+             */
+            Analyzer analyzer = languageAnalyzerMap.get(values[langCodeIndex]);
+            /**
+             * index the doc using the specified analyzer
+             */
+            w.addDocument(doc, analyzer);
+          } else {
+            w.addDocument(doc);
+          }
+        } else {
+          w.addDocument(doc);
+        }
+      }
+      counter++;
+      if (counter % 10000 == 0) {
+        w.commit();
+        System.out.println(counter + " .........committed to index..............");
+      }
+
+    }
+    w.commit();
+    System.out.println("Completed indexing gaz! index name is: " + type.toString());
+  }
+/**
+ * TODO: make these analyzers configurable
+ */
+  private void loadAnalyzerMap() {
+    languageAnalyzerMap.put("ara", new ArabicAnalyzer(Version.LUCENE_45));
+    languageAnalyzerMap.put("tha", new ThaiAnalyzer(Version.LUCENE_45));
+    languageAnalyzerMap.put("rus", new RussianAnalyzer(Version.LUCENE_45));
+    languageAnalyzerMap.put("fas", new PersianAnalyzer(Version.LUCENE_45));
+ 
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerSearchCache.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerSearchCache.java
new file mode 100644
index 0000000..437227e
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerSearchCache.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * Caches gazateer query results statically
+ */
+public class GazateerSearchCache {
+
+  private static Map<String, ArrayList<GazateerEntry>> gazCache = new HashMap<>();
+
+
+  public static synchronized ArrayList<GazateerEntry> get(String searchString) {
+    return gazCache.get(searchString);
+  }
+
+  public static synchronized void put(String searchString, ArrayList<GazateerEntry> hits) {
+    if (gazCache.size() > 10000) {
+      gazCache.clear();
+    }
+    if (!gazCache.containsKey(searchString)) {
+      gazCache.put(searchString, hits);
+    }
+  }
+
+
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerSearcher.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerSearcher.java
new file mode 100644
index 0000000..ed220e8
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GazateerSearcher.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.queryparser.classic.ParseException;
+
+import org.apache.lucene.queryparser.classic.QueryParser;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.MMapDirectory;
+import org.apache.lucene.util.Version;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+
+/**
+ *
+ * Searches Gazateers stored in a MMapDirectory lucene index
+ */
+public class GazateerSearcher {
+
+  private double scoreCutoff = .75;
+  private Directory geonamesIndex;//= new MMapDirectory(new File(indexloc));
+  private IndexReader geonamesReader;// = DirectoryReader.open(geonamesIndex);
+  private IndexSearcher geonamesSearcher;// = new IndexSearcher(geonamesReader);
+  private Analyzer geonamesAnalyzer;
+  //usgs US gazateer
+  private Directory usgsIndex;//= new MMapDirectory(new File(indexloc));
+  private IndexReader usgsReader;// = DirectoryReader.open(geonamesIndex);
+  private IndexSearcher usgsSearcher;// = new IndexSearcher(geonamesReader);
+  private Analyzer usgsAnalyzer;
+
+  public GazateerSearcher() {
+  }
+
+  /**
+   *
+   * @param searchString the nameed entity to look up in the lucene index
+   * @param rowsReturned how many rows to allow lucene to return
+   * @param code         the country code
+   * @param properties   properties file that states where the lucene indexes
+   *                     are
+   * @return
+   */
+  public ArrayList<GazateerEntry> geonamesFind(String searchString, int rowsReturned, String code, EntityLinkerProperties properties) {
+    ArrayList<GazateerEntry> linkedData = new ArrayList<>();
+    try {
+      /**
+       * build the search string
+       */
+      String luceneQueryString = !code.equals("")
+              ? "FULL_NAME_ND_RO:" + searchString.toLowerCase().trim() + " AND CC1:" + code.toLowerCase() + "^1000"
+              : "FULL_NAME_ND_RO:" + searchString.toLowerCase().trim();
+      /**
+       * check the cache and go no further if the records already exist
+       */
+      ArrayList<GazateerEntry> get = GazateerSearchCache.get(searchString);
+      if (get != null) {
+        return get;
+      }
+      if (geonamesIndex == null) {
+        String indexloc = properties.getProperty("opennlp.geoentitylinker.gaz.geonames", "");
+        String cutoff = properties.getProperty("opennlp.geoentitylinker.gaz.lucenescore.min", ".60");
+        scoreCutoff = Double.valueOf(cutoff);
+        geonamesIndex = new MMapDirectory(new File(indexloc));
+        geonamesReader = DirectoryReader.open(geonamesIndex);
+        geonamesSearcher = new IndexSearcher(geonamesReader);
+        geonamesAnalyzer = new StandardAnalyzer(Version.LUCENE_45);
+
+      }
+
+
+
+      QueryParser parser = new QueryParser(Version.LUCENE_45, luceneQueryString, geonamesAnalyzer);
+      Query q = parser.parse(luceneQueryString);
+
+
+      TopDocs search = geonamesSearcher.search(q, rowsReturned);
+      double maxScore = (double) search.getMaxScore();
+
+      for (int i = 0; i < search.scoreDocs.length; ++i) {
+        GazateerEntry entry = new GazateerEntry();
+        int docId = search.scoreDocs[i].doc;
+        double sc = search.scoreDocs[i].score;
+
+        entry.getScoreMap().put("lucene", sc);
+
+        entry.getScoreMap().put("rawlucene", sc);
+        entry.setIndexID(docId + "");
+        entry.setSource("geonames");
+
+        Document d = geonamesSearcher.doc(docId);
+        List<IndexableField> fields = d.getFields();
+        for (int idx = 0; idx < fields.size(); idx++) {
+          String value = d.get(fields.get(idx).name());
+          value = value.toLowerCase();
+          switch (idx) {
+            case 1:
+              entry.setItemID(value);
+              break;
+            case 3:
+              entry.setLatitude(Double.valueOf(value));
+              break;
+            case 4:
+              entry.setLongitude(Double.valueOf(value));
+              break;
+            case 10:
+              entry.setItemType(value);
+              break;
+            case 12:
+              entry.setItemParentID(value);
+              break;
+            case 23:
+              entry.setItemName(value);
+              break;
+          }
+          entry.getIndexData().put(fields.get(idx).name(), value);
+        }
+        //only keep it if the country code is a match
+        if (entry.getItemParentID().toLowerCase().equals(code.toLowerCase())) {
+          linkedData.add(entry);
+        }
+      }
+
+      normalize(linkedData, 0d, maxScore);
+      prune(linkedData);
+    } catch (IOException | ParseException ex) {
+      System.err.println(ex);
+    }
+    /**
+     * add the records to the cache for this query
+     */
+    GazateerSearchCache.put(searchString, linkedData);
+    return linkedData;
+  }
+
+  /**
+   * Looks up the name in the USGS gazateer, after checking the cache
+   *
+   * @param searchString the nameed entity to look up in the lucene index
+   * @param rowsReturned how many rows to allow lucene to return
+   *
+   * @param properties   properties file that states where the lucene indexes
+   * @return
+   */
+  public ArrayList<GazateerEntry> usgsFind(String searchString, int rowsReturned, EntityLinkerProperties properties) {
+    ArrayList<GazateerEntry> linkedData = new ArrayList<>();
+    try {
+
+      String luceneQueryString = "FEATURE_NAME:" + searchString.toLowerCase().trim() + " OR MAP_NAME: " + searchString.toLowerCase().trim();
+      /**
+       * hit the cache
+       */
+      ArrayList<GazateerEntry> get = GazateerSearchCache.get(searchString);
+      if (get != null) {
+        //if the name is already there, return the list of cavhed results
+        return get;
+      }
+      if (usgsIndex == null) {
+        String indexloc = properties.getProperty("opennlp.geoentitylinker.gaz.usgs", "");
+        String cutoff = properties.getProperty("opennlp.geoentitylinker.gaz.lucenescore.min", ".75");
+        scoreCutoff = Double.valueOf(cutoff);
+        usgsIndex = new MMapDirectory(new File(indexloc));
+        usgsReader = DirectoryReader.open(usgsIndex);
+        usgsSearcher = new IndexSearcher(usgsReader);
+        usgsAnalyzer = new StandardAnalyzer(Version.LUCENE_45);
+      }
+
+
+      QueryParser parser = new QueryParser(Version.LUCENE_45, luceneQueryString, usgsAnalyzer);
+      Query q = parser.parse(luceneQueryString);
+
+
+      TopDocs search = usgsSearcher.search(q, rowsReturned);
+      double maxScore = (double) search.getMaxScore();
+
+
+      for (int i = 0; i < search.scoreDocs.length; ++i) {
+        GazateerEntry entry = new GazateerEntry();
+        int docId = search.scoreDocs[i].doc;
+        double sc = search.scoreDocs[i].score;
+        //keep track of the min score for normalization
+
+        entry.getScoreMap().put("lucene", sc);
+        entry.getScoreMap().put("rawlucene", sc);
+        entry.setIndexID(docId + "");
+        entry.setSource("usgs");
+        entry.setItemParentID("us");
+
+
+        Document d = usgsSearcher.doc(docId);
+        List<IndexableField> fields = d.getFields();
+        for (int idx = 0; idx < fields.size(); idx++) {
+          String value = d.get(fields.get(idx).name());
+          value = value.toLowerCase();
+          switch (idx) {
+            case 0:
+              entry.setItemID(value);
+              break;
+            case 1:
+              entry.setItemName(value);
+              break;
+            case 2:
+              entry.setItemType(value);
+              break;
+            case 9:
+              entry.setLatitude(Double.valueOf(value));
+              break;
+            case 10:
+              entry.setLongitude(Double.valueOf(value));
+              break;
+          }
+          entry.getIndexData().put(fields.get(idx).name(), value);
+        }
+        linkedData.add(entry);
+
+
+      }
+
+      normalize(linkedData, 0d, maxScore);
+      prune(linkedData);
+    } catch (IOException | ParseException ex) {
+      System.err.println(ex);
+    }
+    /**
+     * add the records to the cache for this query
+     */
+    GazateerSearchCache.put(searchString, linkedData);
+    return linkedData;
+  }
+
+  private void normalize(ArrayList<GazateerEntry> linkedData, Double minScore, Double maxScore) {
+    for (GazateerEntry gazateerEntry : linkedData) {
+
+      double luceneScore = gazateerEntry.getScoreMap().get("lucene");
+      luceneScore = normalize(luceneScore, minScore, maxScore);
+      luceneScore = luceneScore > 1.0 ? 1.0 : luceneScore;
+      luceneScore = (luceneScore == Double.NaN) ? 0.001 : luceneScore;
+      gazateerEntry.getScoreMap().put("lucene", luceneScore);
+    }
+  }
+
+  private void prune(ArrayList<GazateerEntry> linkedData) {
+    for (Iterator<GazateerEntry> itr = linkedData.iterator(); itr.hasNext();) {
+      GazateerEntry ge = itr.next();
+      if (ge.getScoreMap().get("lucene") < scoreCutoff) {
+        itr.remove();
+      }
+    }
+  }
+
+  private Double normalize(Double valueToNormalize, Double minimum, Double maximum) {
+    Double d = (double) ((1 - 0) * (valueToNormalize - minimum)) / (maximum - minimum) + 0;
+    d = d == null ? 0d : d;
+    return d;
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoEntityLinker.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoEntityLinker.java
new file mode 100644
index 0000000..3dc8c81
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoEntityLinker.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import opennlp.tools.entitylinker.domain.BaseLink;
+import opennlp.tools.entitylinker.domain.LinkedSpan;
+import opennlp.tools.util.Span;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.entitylinker.EntityLinker;
+
+/**
+ * Links location entities to gazatteers. Currently supports gazateers in a
+ * MySql database (NGA and USGS)
+ *
+ *
+ */
+public class GeoEntityLinker implements EntityLinker<LinkedSpan> {
+
+  private CountryContext countryContext;
+  private Map<String, Set<Integer>> countryMentions;
+  private EntityLinkerProperties linkerProperties;
+  private GazateerSearcher gazateerSearcher = new GazateerSearcher();
+  private List<LinkedEntityScorer> scorers = new ArrayList<>();
+  /**
+   * Flag for deciding whether to search gaz only for toponyms within countries
+   * that are mentioned in the document
+   */
+  private Boolean filterCountryContext = true;
+
+  public GeoEntityLinker() {
+    countryContext = new CountryContext();
+  }
+
+  @Override
+  public List<LinkedSpan> find(String doctext, Span[] sentences, String[][] tokensBySentence, Span[][] namesBySentence) {
+    ArrayList<LinkedSpan> spans = new ArrayList<LinkedSpan>();
+
+    if (linkerProperties == null) {
+      throw new IllegalArgumentException("EntityLinkerProperties cannot be null");
+    }
+    countryMentions = countryContext.regexfind(doctext, linkerProperties);
+
+    for (int s = 0; s < sentences.length; s++) {
+      Span[] names = namesBySentence[s];
+      String[] tokens = tokensBySentence[s];
+      String[] matches = Span.spansToStrings(names, tokens);
+
+      for (int i = 0; i < matches.length; i++) {
+
+//nga gazateer is for other than US placenames, don't use it unless US is a mention in the document
+        ArrayList<BaseLink> geoNamesEntries = new ArrayList<BaseLink>();
+        if (!(countryMentions.keySet().contains("us") && countryMentions.keySet().size() == 1) || countryMentions.keySet().size() > 1 || countryMentions.keySet().isEmpty()) {
+          // geoNamesEntries = geoNamesGaz.find(matches[i], names[i], countryMentions, linkerProperties);
+          if (!countryMentions.keySet().isEmpty()) {
+            for (String code : countryMentions.keySet()) {
+              if (!code.equals("us")) {
+                geoNamesEntries.addAll(gazateerSearcher.geonamesFind(matches[i], 10, code, linkerProperties));
+              }
+            }
+          } else {
+            geoNamesEntries.addAll(gazateerSearcher.geonamesFind(matches[i], 10, "", linkerProperties));
+
+          }
+
+        }
+        ArrayList<BaseLink> usgsEntries = new ArrayList<BaseLink>();
+        if (countryMentions.keySet().contains("us") || countryMentions.keySet().isEmpty()) {
+          //usgsEntries = usgsGaz.find(matches[i], names[i], linkerProperties);
+          usgsEntries.addAll(gazateerSearcher.usgsFind(matches[i], 3, linkerProperties));
+        }
+        LinkedSpan<BaseLink> geoSpan = new LinkedSpan<BaseLink>(geoNamesEntries, names[i].getStart(), names[i].getEnd());
+
+        if (!usgsEntries.isEmpty()) {
+          geoSpan.getLinkedEntries().addAll(usgsEntries);
+          geoSpan.setSearchTerm(matches[i]);
+        }
+
+        if (!geoSpan.getLinkedEntries().isEmpty()) {
+          geoSpan.setSearchTerm(matches[i]);
+          geoSpan.setSentenceid(s);
+          spans.add(geoSpan);
+        }
+      }
+    }
+
+    if (scorers.isEmpty()) {
+      scorers.add(new FuzzyStringMatchScorer());
+      scorers.add(new GeoHashBinningScorer());
+      scorers.add(new CountryProximityScorer());
+      scorers.add(new ModelBasedScorer());
+    }
+    for (LinkedEntityScorer scorer : scorers) {
+      scorer.score(spans, doctext, sentences, linkerProperties, countryContext);
+    }
+    return spans;
+  }
+
+  @Override
+  public void setEntityLinkerProperties(EntityLinkerProperties properties) {
+    this.linkerProperties = properties;
+  }
+
+  @Override
+  public List<LinkedSpan> find(String text, Span[] sentences, Span[] tokens, Span[] nameSpans) {
+    throw new UnsupportedOperationException("The GeoEntityLinker requires the entire document for proper scoring. This method is unsupported"); //To change body of generated methods, choose Tools | Templates.
+  }
+
+  @Override
+  public List<LinkedSpan> find(String text, Span[] sentences, Span[] tokens, Span[] nameSpans, int sentenceIndex) {
+    throw new UnsupportedOperationException("The GeoEntityLinker requires the entire document for proper scoring. This method is unsupported"); //To change body of generated methods, choose Tools | Templates.
+  }
+
+  @Override
+  public List<LinkedSpan> find(String text, Span[] sentences, String[] tokens, Span[] nameSpans) {
+    throw new UnsupportedOperationException("The GeoEntityLinker requires the entire document for proper scoring. This method is unsupported"); //To change body of generated methods, choose Tools | Templates.
+  }
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoEntityLinkerSetupUtils.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoEntityLinkerSetupUtils.java
new file mode 100644
index 0000000..00c3f9e
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoEntityLinkerSetupUtils.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import opennlp.tools.doccat.DoccatModel;
+import opennlp.tools.doccat.DocumentCategorizerME;
+import opennlp.tools.doccat.DocumentSample;
+import opennlp.tools.doccat.DocumentSampleStream;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.util.ObjectStream;
+import opennlp.tools.util.PlainTextByLineStream;
+import static opennlp.addons.geoentitylinker.ModelBasedScorer.RADIUS;
+
+
+/**
+ *
+ * Tools for setting up GeoEntityLinker gazateers and doccat scoring model
+ */
+public class GeoEntityLinkerSetupUtils {
+  public static ModelBasedScorer scorer;
+
+  static {
+    scorer = new ModelBasedScorer();
+  }
+    public static void createLuceneIndex(File outputIndexDir, File gazateerInputData, GazateerIndexer.GazType type){
+      GazateerIndexer indexer = new GazateerIndexer();
+      try {
+        indexer.index(outputIndexDir, gazateerInputData, type);
+      } catch (Exception ex) {
+       ex.printStackTrace();
+      }
+    }
+    /**
+   *
+   * @param documents         A list of document texts, for best results try to
+   *                          ensure each country you care about will be
+   *                          represented in the collection
+   * @param annotationOutFile the location where the annotated doccat text file
+   *                          will be stored
+   * @param modelOutFile      the location where the doccat model will be stored
+   * @param properties        the properties where the country context object
+   *                          will find it's country data from this property:
+   *                          opennlp.geoentitylinker.countrycontext.filepath
+   * @throws IOException
+   */
+  public static void buildCountryContextModel(Collection<String> documents, File annotationOutFile, File modelOutFile, EntityLinkerProperties properties) throws IOException {
+    CountryContext context = new CountryContext();
+    FileWriter writer = new FileWriter(annotationOutFile, true);
+    System.out.println("processing " + documents.size() + " documents");
+    for (String docText : documents) {
+      System.out.append(".");
+      Map<String, Set<Integer>> regexfind = context.regexfind(docText, properties);
+      Map<String, ArrayList<String>> modelCountryContext = modelCountryContext(docText, context, RADIUS);
+      for (String key : modelCountryContext.keySet()) {
+        for (String wordbag : modelCountryContext.get(key)) {
+          writer.write(key + " " + wordbag + "\n");
+        }
+      }
+    }
+    System.out.println("Document processing complete. Writing training data to "+ annotationOutFile.getAbsolutePath());
+    writer.close();
+    System.out.println("Building Doccat model...");
+    DoccatModel model = null;
+
+    InputStream dataIn = new FileInputStream(annotationOutFile);
+    try {
+
+      ObjectStream<String> lineStream =
+              new PlainTextByLineStream(dataIn, "UTF-8");
+      ObjectStream<DocumentSample> sampleStream = new DocumentSampleStream(lineStream);
+
+      model = DocumentCategorizerME.train("en", sampleStream);
+      OutputStream modelOut = new BufferedOutputStream(new FileOutputStream(modelOutFile));
+      model.serialize(modelOut);
+       System.out.println("Model complete!");
+    } catch (IOException e) {
+      // Failed to read or parse training data, training failed
+      e.printStackTrace();
+    }
+
+  }
+
+  /**
+   * generates proximal wordbags within the radius of a country mention within
+   * the doctext based on the country context object
+   *
+   *
+   * @param docText
+   * @param additionalContext
+   * @param radius
+   * @return
+   */
+  private static Map<String, ArrayList<String>> modelCountryContext(String docText, CountryContext additionalContext, int radius) {
+    Map<String, ArrayList< String>> featureBags = new HashMap<>();
+    Map<String, Set<Integer>> countryMentions = additionalContext.getCountryMentions();
+    /**
+     * iterator over the map that contains a mapping of every country code to
+     * all of its mentions in the document
+     */
+    for (String code : countryMentions.keySet()) {
+      /**
+       * for each mention, collect features from around each mention, then
+       * consolidate the features into another map
+       */
+      for (int mentionIdx : countryMentions.get(code)) {
+        String chunk = scorer.getTextChunk(mentionIdx, docText, radius);
+        //   Collection<String> extractFeatures = super.extractFeatures(chunk.split(" "));
+        if (featureBags.containsKey(code)) {
+          featureBags.get(code).add(chunk);
+        } else {
+          ArrayList<String> newlist = new ArrayList<>();
+          newlist.add(chunk);
+          featureBags.put(code, newlist);
+        }
+      }
+    }
+    return featureBags;
+  }
+
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoHashBinningScorer.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoHashBinningScorer.java
new file mode 100644
index 0000000..4d7467f
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/GeoHashBinningScorer.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.entitylinker.domain.BaseLink;
+import opennlp.tools.entitylinker.domain.LinkedSpan;
+import opennlp.tools.util.Span;
+
+/**
+ *Scores toponymns based on geographic point binning (clustering). This classes output is highly dependant on the quality
+ * of points returned from the gazateer. False positive hits from the index will pollute this result. Ensure the score cutoff for the
+ * Lucene search is set to an appropriate level so this class if not fed poor data.
+ */
+public class GeoHashBinningScorer implements LinkedEntityScorer<CountryContext> {
+
+  @Override
+  public void score(List<LinkedSpan> linkedSpans, String docText, Span[] sentenceSpans,EntityLinkerProperties properties, CountryContext additionalContext) {
+     score( linkedSpans);
+  }
+
+  private  void score(List<LinkedSpan> geospans) {
+    Map<Double, Double> latLongs = new HashMap<Double, Double>();
+
+    /**
+     * collect all the lat longs
+     */
+    for (LinkedSpan<BaseLink> ls : geospans) {
+      for (BaseLink bl : ls.getLinkedEntries()) {
+        if (bl instanceof GazateerEntry) {
+          GazateerEntry entry = (GazateerEntry) bl;
+          latLongs.put(entry.getLatitude(), entry.getLongitude());
+        
+        }
+      }
+    }
+
+    /**
+     * convert to geohash and add to sortedset
+     */
+    TreeSet<Long> geoHashes = new TreeSet<Long>();
+    for (Map.Entry<Double, Double> entry : latLongs.entrySet()) {
+      geoHashes.add(geoHash(entry.getKey(), entry.getValue()));
+    }
+    /**
+     * bin the points and generate a scoremap
+     */
+    Map<Long, Set<Long>> bins = bin(geoHashes);
+    Map<Long, Double> scores = getScore((TreeMap<Long, Set<Long>>) bins);
+    /**
+     * iterate over the data again and assign the score based on the bins
+     */
+    for (LinkedSpan<BaseLink> ls : geospans) {
+      for (BaseLink bl : ls.getLinkedEntries()) {
+        Long geohash = -1L;
+        Double score = 0d;
+        if (bl instanceof GazateerEntry) {
+          GazateerEntry entry = (GazateerEntry) bl;
+          geohash = geoHash(entry.getLatitude(), entry.getLongitude());
+        
+        }
+        if (scores.containsKey(geohash)) {
+          score = scores.get(geohash);
+
+        } else {
+          for (Long bin : bins.keySet()) {
+            if (bin == geohash || bins.get(bin).contains(geohash)) {
+              score = scores.get(bin);
+              break;
+            }
+          }
+        }
+        bl.getScoreMap().put("geohashbin", score);
+      }
+    }
+
+
+  }
+
+  private Long normalize(Double coordpart, Boolean isLat) {
+    Integer add = isLat ? 90 : 180;
+    coordpart = Math.abs(coordpart + add);
+    coordpart = coordpart * 1000000;
+
+    Long l = Math.round(coordpart);
+    String coord = String.valueOf(l);
+    if (coord.length() < 8) {
+      while (coord.length() < 8) {
+        coord += "0";
+      }
+    }
+    coord = coord.substring(0, 8);
+    l = Long.valueOf(coord);
+    return l;
+  }
+
+  /**
+   * interleaves a lat and a long to place the coordinate in linear sortable
+   * space for binning simplicity
+   *
+   * @param lat
+   * @param lon
+   * @return
+   */
+  private Long geoHash(double lat, double lon) {
+    Long normLat = normalize(lat, Boolean.TRUE);
+    Long normLon = normalize(lon, Boolean.FALSE);
+    String sLat = String.valueOf(normLat);
+    String sLon = String.valueOf(normLon);
+    char[] latInts = sLat.toCharArray();
+    char[] lonInts = sLon.toCharArray();
+    String geoHash = "";
+    int len = latInts.length > lonInts.length ? lonInts.length : latInts.length;
+    for (int i = 0; i < len - 1; i++) {
+      String a = String.valueOf(latInts[i]);
+      String b = String.valueOf(lonInts[i]);
+      geoHash += a + b;
+    }
+
+    return Long.valueOf(geoHash);
+  }
+
+  private Map<Long, Set<Long>> bin(TreeSet<Long> sets) {
+    ArrayList<Long> list = new ArrayList<Long>(sets);
+    ArrayList<Long> diffs = new ArrayList<Long>();
+    /**
+     * create a set of differences between the points
+     */
+    for (int i = 0; i < list.size() - 1; i++) {
+      Long n = list.get(i + 1);
+      Long v = list.get(i);
+      diffs.add(Math.abs(n - v));
+    }
+    /**
+     * generate an average "distance" between the normed points
+     */
+    Long sum = 0L;
+    for (Long l : diffs) {
+      sum += l;
+    }
+    Long avg=sum;
+    if(!diffs.isEmpty()){
+     avg = sum / diffs.size();
+    }
+
+
+    /**
+     * generate break values where the disparity is greater than the average
+     */
+    TreeSet<Long> breaks = new TreeSet<Long>();
+    for (int i = 0; i < list.size() - 1; i++) {
+      Long n = list.get(i + 1);
+      Long v = list.get(i);
+      //Long percent = 100 - (v / n * 100);
+      Long diff = n - v;
+      if (diff > avg) {
+        breaks.add(v);
+      }
+    }
+    /**
+     * based on the break values, place subsets of close points into bins
+     */
+    TreeMap<Long, Set<Long>> binToAmount = new TreeMap<Long, Set<Long>>();
+    Long lastBreak = -1L;
+    for (Long br : breaks) {
+      if (lastBreak == -1L) {
+        binToAmount.put(br, sets.subSet(0L, true, br, true));
+      } else {
+        binToAmount.put(br, sets.subSet(lastBreak, false, br, true));
+      }
+      lastBreak = br;
+    }
+    lastBreak = sets.higher(lastBreak);
+    if (lastBreak != null) {
+      binToAmount.put(lastBreak, sets.subSet(lastBreak, true, sets.last(), true));
+      if (binToAmount.get(lastBreak).isEmpty()) {
+        binToAmount.get(lastBreak).add(lastBreak);
+      }
+    }
+    /**
+     * "binToAmount" is a map of the break value to all the points behind it
+     * (it's sorted), so the key is the max value of its set of values
+     */
+    return binToAmount;
+  }
+
+  /**
+   * returns a map of geohashes and their score
+   *
+   * @param binToAmount
+   * @return Map< Geohash, score>
+   */
+  private Map<Long, Double> getScore(TreeMap<Long, Set<Long>> binToAmount) {
+    TreeMap<Long, Double> ranks = new TreeMap<Long, Double>();
+    TreeMap<Long, Double> normRanks = new TreeMap<Long, Double>();
+    /**
+     * if there is only one bin return 1 as the rank for each item in the value
+     */
+    if (binToAmount.keySet().size() == 1 || binToAmount.keySet().isEmpty()) {
+      for (Long bin : binToAmount.keySet()) {
+        for (Long hash : binToAmount.get(bin)) {
+          ranks.put(bin, 1d);
+        }
+      }
+      return ranks;
+    }
+    int total = 0;
+    /**
+     * generate a total number of points
+     */
+    for (Set<Long> geohashes : binToAmount.values()) {
+      total += geohashes.size();
+    }
+    /**
+     * divide total by bin size, largest bin size gets best score, everything in
+     * that bin gets that score because it is part of that primary cluster
+     * TODO... do an extra iteration of clustering within the predominant
+     * cluster to refine the scoring or make the basis of the binning more
+     * granular than > avg
+     */
+    TreeSet<Double> rankSet = new TreeSet<Double>();
+    for (Long key : binToAmount.keySet()) {
+      int size = binToAmount.get(key).size();
+      Double rank = (double) total / size;
+      rankSet.add(rank);
+      ranks.put(key, rank);
+    }
+    /**
+     * load the final score map with normalized values
+     */
+    for (Map.Entry<Long, Double> rank : ranks.entrySet()) {
+      double norm = normalize(rank.getValue(), rankSet.first() + .1, rankSet.last() + .1);
+      double reverse = Math.abs(norm - 1);
+      double score = reverse > 1d ? 1.0 : reverse;
+      normRanks.put(rank.getKey(), score);
+    }
+
+    return normRanks;
+  }
+
+  /**
+   * transposes a number in a range to a double between 0 and 1
+   *
+   * @param valueToNormalize the value to be normalized (placed within a new
+   *                         range of 0-1)
+   * @param minimum          the min of the current range
+   * @param maximum          the max of the current range
+   * @return
+   */
+  private Double normalize(Double valueToNormalize, Double minimum, Double maximum) {
+    Double d = (double) ((1 - 0) * (valueToNormalize - minimum)) / (maximum - minimum) + 0;
+    d = d == null ? 0d : d;
+    return d;
+  }
+}
+
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/LinkedEntityScorer.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/LinkedEntityScorer.java
new file mode 100644
index 0000000..1acca46
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/LinkedEntityScorer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.util.List;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.entitylinker.domain.LinkedSpan;
+import opennlp.tools.util.Span;
+
+/**
+ * Structure for scoring linked entities. The Map logically represents a pair :
+ * "Score type" to the "actual Score."
+ */
+public interface LinkedEntityScorer<T> {
+
+/**
+ * Scores a collection of linked entities. Implementations should populate the scoreMap in the list of BaseLink for each linkedSpan
+ * @param linkedSpans the spans that have been linked to some external source and have all the data they need to be scored
+ * @param docText the full text of the document.
+ * @param sentenceSpans the sentence spans the correspond to the document text
+ * @param additionalContext any additional data required to perform the scoring operation
+ * @return void
+ */
+  void score(List<LinkedSpan> linkedSpans, String docText, Span[] sentenceSpans, EntityLinkerProperties properties, T additionalContext);
+}
diff --git a/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/ModelBasedScorer.java b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/ModelBasedScorer.java
new file mode 100644
index 0000000..d370ec8
--- /dev/null
+++ b/geoentitylinker-addon/src/main/java/opennlp/addons/geoentitylinker/ModelBasedScorer.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+package opennlp.addons.geoentitylinker;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import opennlp.tools.doccat.DoccatModel;
+import opennlp.tools.doccat.DocumentCategorizerME;
+import opennlp.tools.entitylinker.EntityLinkerProperties;
+import opennlp.tools.entitylinker.domain.BaseLink;
+import opennlp.tools.entitylinker.domain.LinkedSpan;
+import opennlp.tools.util.Span;
+
+/**
+ *
+ * Utilizes a doccat model to score toponyms based on surrounding context
+ */
+public class ModelBasedScorer implements LinkedEntityScorer<CountryContext> {
+
+
+  DocumentCategorizerME documentCategorizerME;
+  DoccatModel doccatModel;
+  public static final int RADIUS = 100;
+
+  @Override
+  public void score(List<LinkedSpan> linkedSpans, String docText, Span[] sentenceSpans, EntityLinkerProperties properties, CountryContext additionalContext) {
+    try {
+      if (doccatModel == null) {
+        String path = properties.getProperty("opennlp.geoentitylinker.modelbasedscorer.modelpath", "");
+        if (path.equals("")) {
+          return;
+        }
+        doccatModel = new DoccatModel(new File(path));
+        documentCategorizerME = new DocumentCategorizerME(doccatModel);
+      }
+      Map<Integer, String> proximalFeatures = generateProximalFeatures(linkedSpans, sentenceSpans, docText, RADIUS);
+      for (Map.Entry<Integer, String> entry : proximalFeatures.entrySet()) {
+        Map<String, Double> scores = this.getScore(entry.getValue());
+        for (BaseLink link : (List<BaseLink>) linkedSpans.get(entry.getKey()).getLinkedEntries()) {
+          double score = 0d;
+          if (scores.containsKey(link.getItemParentID())) {
+            score = scores.get(link.getItemParentID());
+          }
+          link.getScoreMap().put("countrymodel", score);
+        }
+      }
+
+    } catch (FileNotFoundException ex) {
+      System.err.println("could not find modelpath using EntityLinkerProperties. Property should be \"opennlp.geoentitylinker.modelbasedscorer.modelpath\"");
+    } catch (IOException ex) {
+      System.err.println(ex);
+    } catch (Exception ex) {
+      System.err.println(ex);
+    }
+  }
+
+  /**
+   * generates features using a BagOfWordsfeatureGenerator that are within the
+   * radius of a mention within the doctext
+   *
+   * @param linkedSpans
+   * @param docText
+   * @param additionalContext
+   * @param radius
+   * @return a map of the index of the linked span to the string of surrounding
+   *         text: Map<indexofspan,surrounding text>
+   */
+  public Map<Integer, String> generateProximalFeatures(List<LinkedSpan> linkedSpans, Span[] sentenceSpans, String docText, int radius) {
+    Map<Integer, String> featureBags = new HashMap<>();
+    Map<Integer, Integer> nameMentionMap = new HashMap<>();
+    /**
+     * iterator over the map that contains a mapping of every country code to
+     * all of its mentions in the document
+     */
+    for (int i = 0; i < linkedSpans.size(); i++) {
+      LinkedSpan span = linkedSpans.get(i);
+      if (span.getLinkedEntries().isEmpty()) {
+        //don't care about spans that did not get linked to anything at all; nothing to work with
+        continue;
+      }
+      /**
+       * get the sentence the name span was found in, the beginning of the
+       * sentence will suffice as a centroid for feature generation around the
+       * named entity
+       */
+      Integer mentionIdx = sentenceSpans[span.getSentenceid()].getStart();
+      nameMentionMap.put(i, mentionIdx);
+    }
+    /**
+     * now associate each span to a string that will be used for categorization
+     * against the model.
+     */
+    for (Map.Entry<Integer, Integer> entry : nameMentionMap.entrySet()) {
+      featureBags.put(entry.getKey(), getTextChunk(entry.getValue(), docText, radius));
+    }
+
+
+    return featureBags;
+  }
+
+  public String getTextChunk(int mentionIdx, String docText, int radius) {
+    int docSize = docText.length();
+    int left = 0, right = 0;
+    left = (mentionIdx - radius < 0) ? 0 : mentionIdx - radius;
+    right = (mentionIdx + radius > docSize) ? docSize : mentionIdx + radius;
+    String chunk = "";
+    if (right <= left) {
+      chunk = "";
+    } else {
+      /**
+       * don't want to chop any words in half, so take fron the first space to
+       * the last space in the chunk string
+       */
+      chunk = docText.substring(left, right);
+      if (left != 0) {
+        left = chunk.indexOf(" ");
+      }
+      right = chunk.lastIndexOf(" ");
+      /**
+       * now get the substring again with only whole words
+       */
+      if (left < right) {
+        chunk = chunk.substring(left, right);
+      }
+    }
+
+    return chunk;
+  }
+
+  private Map<String, Double> getScore(String text) throws Exception {
+    Map<String, Double> scoreMap = new HashMap<>();
+    double[] categorize = documentCategorizerME.categorize(text);
+    int catSize = documentCategorizerME.getNumberOfCategories();
+    for (int i = 0; i < catSize; i++) {
+      String category = documentCategorizerME.getCategory(i);
+      scoreMap.put(category, categorize[documentCategorizerME.getIndex(category)]);
+    }
+    return scoreMap;
+  }
+
+  
+}
diff --git a/geoentitylinker-addon/src/test/java/apache/opennlp/addons/AppTest.java b/geoentitylinker-addon/src/test/java/apache/opennlp/addons/AppTest.java
new file mode 100644
index 0000000..60ea0f2
--- /dev/null
+++ b/geoentitylinker-addon/src/test/java/apache/opennlp/addons/AppTest.java
@@ -0,0 +1,38 @@
+package apache.opennlp.addons;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}
