coveralls: 
[![Coverage Status](https://coveralls.io/builds/20502492/badge)](https://coveralls.io/builds/20502492)

Coverage decreased (-1.7%) to 98.315% when pulling **7773372af7921ea5d2e7a70f92afdedb7df069da on ensure-lowercase** into **689aa310a75c894a041e50cca9e8ce4e4cb37b39 on master**.

diff --git a/spellchecker/spellchecker.py b/spellchecker/spellchecker.py
index 5f9f644..64a25f0 100644
--- a/spellchecker/spellchecker.py
+++ b/spellchecker/spellchecker.py
@@ -136,10 +136,19 @@ class SpellChecker(object):
                 word (str): The word for which to calculate candidate spellings
             Returns:
                 set: The set of words that are possible candidates '''
-
-        return (self.known([word]) or self.known(self.edit_distance_1(word)) or
-                (self._distance == 2 and
-                 self.known(self.edit_distance_2(word))) or {word})
+        if self.known([word]):  # short-cut if word is correct already
+            return {word}
+        # get edit distance 1...
+        res = [x for x in self.edit_distance_1(word)]
+        tmp = self.known(res)
+        if tmp:
+            return tmp
+        # if still not found, use the edit distance 1 to calc edit distance 2
+        if self._distance == 2:
+            tmp = self.known([x for x in self.__edit_distance_alt(res)])
+            if tmp:
+                return tmp
+        return {word}
 
     def known(self, words):
         ''' The subset of `words` that appear in the dictionary of words
@@ -150,7 +159,8 @@ class SpellChecker(object):
             Returns:
                 set: The set of those words from the input that are in the \
                 corpus '''
-        return set(w for w in words if w in self._word_frequency.dictionary or
+        tmp = [w.lower() for w in words]
+        return set(w for w in tmp if w in self._word_frequency.dictionary or
                    not self._check_if_should_check(w))
 
     def unknown(self, words):
@@ -162,7 +172,7 @@ class SpellChecker(object):
             Returns:
                 set: The set of those words from the input that are not in \
                 the corpus '''
-        tmp = [w for w in words if self._check_if_should_check(w)]
+        tmp = [w.lower() for w in words if self._check_if_should_check(w)]
         return set(w for w in tmp if w not in self._word_frequency.dictionary)
 
     def edit_distance_1(self, word):
@@ -174,6 +184,7 @@ class SpellChecker(object):
             Returns:
                 set: The set of strings that are edit distance one from the \
                 provided word '''
+        word = word.lower()
         if self._check_if_should_check(word) is False:
             return {word}
         letters = self._word_frequency.letters
@@ -193,8 +204,21 @@ class SpellChecker(object):
             Returns:
                 set: The set of strings that are edit distance two from the \
                 provided word '''
-        return (e2 for e1 in self.edit_distance_1(word)
-                for e2 in self.edit_distance_1(e1))
+        word = word.lower()
+        return [e2 for e1 in self.edit_distance_1(word)
+                for e2 in self.edit_distance_1(e1)]
+
+    def __edit_distance_alt(self, words):
+        ''' Compute all strings that are 1 edits away from all the words using
+            only the letters in the corpus
+
+            Args:
+                words (list): The words for which to calculate the edit distance
+            Returns:
+                set: The set of strings that are edit distance two from the \
+                provided words '''
+        words = [x.lower() for x in words]
+        return [e2 for e1 in words for e2 in self.edit_distance_1(e1)]
 
     @staticmethod
     def _check_if_should_check(word):
@@ -214,6 +238,7 @@ class WordFrequency(object):
         different methods to load the data and update over time '''
 
     __slots__ = ['_dictionary', '_total_words', '_unique_words', '_letters']
+
     def __init__(self):
         self._dictionary = Counter()
         self._total_words = 0
@@ -222,11 +247,20 @@ class WordFrequency(object):
 
     def __contains__(self, key):
         ''' turn on contains '''
-        return key in self._dictionary
+        return key.lower() in self._dictionary
 
     def __getitem__(self, key):
         ''' turn on getitem '''
-        return self._dictionary[key]
+        return self._dictionary[key.lower()]
+
+    def pop(self, key, default=None):
+        ''' Remove the key and return the associated value or default if not
+            found
+
+            Args:
+                key (str): The key to remove
+                default (obj): The value to return if key is not present '''
+        return self._dictionary.pop(key.lower(), default)
 
     @property
     def dictionary(self):
@@ -328,7 +362,7 @@ class WordFrequency(object):
 
             Args:
                 word (str): The word to add '''
-        self.load_words([word.lower()])
+        self.load_words([word])
 
     def remove_words(self, words):
         ''' Remove a list of words from the word frequency list
@@ -353,7 +387,7 @@ class WordFrequency(object):
             Args:
                 threshold (int): The threshold at which a word is to be \
                 removed '''
-        keys = [x.lower() for x in self._dictionary.keys()]
+        keys = [x for x in self._dictionary.keys()]
         for key in keys:
             if self._dictionary[key] <= threshold:
                 self._dictionary.pop(key)

How to add new words to the dictionary?
From the docs, as far as I understood you can add new words as follows:
```
from spellchecker import SpellChecker
spell = SpellChecker(distance=1)
spell.word_frequency.load_words(['words', 'to', 'be','added', 'to', 'the', 'system', 'Addis Abeba'])
```
However, I am trying to correct the word "Addis Abeba", as follows and it doesn't work:


In:

```
misspelled = spell.unknown(['something', 'is', 'hapenning', 'here', 'Adis abebba'])
for word in misspelled:
    print(spell.correction(word))
    print(spell.candidates(word))
```

Out:

```
Adis abebba
{'Adis abebba'}
hapenning
{'hapenning'}

```

Thus, how can I add do my dictionary the word: "Adis abebba" in order to spell and correct words like "Addis abeba" or "Adiis abebbba"?
diff --git a/tests/spellchecker_test.py b/tests/spellchecker_test.py
index 823626a..dcf4332 100644
--- a/tests/spellchecker_test.py
+++ b/tests/spellchecker_test.py
@@ -235,3 +235,36 @@ class TestSpellChecker(unittest.TestCase):
         self.assertFalse('bananna' in sp)
 
         os.remove(new_filepath)
+
+    def test_capitalization(self):
+        ''' test that capitalization doesn't affect in comparisons '''
+        spell = SpellChecker(language=None)
+        spell.word_frequency.add('Bob')
+        spell.word_frequency.add('Bob')
+        spell.word_frequency.add('Bab')
+        self.assertEqual('Bob' in spell, True)
+        self.assertEqual('BOb' in spell, True)
+        self.assertEqual('BOB' in spell, True)
+        self.assertEqual('bob' in spell, True)
+
+        words = ['Bb', 'bb', 'BB']
+        self.assertEqual(spell.unknown(words), {'bb'})
+
+        known_words = ['BOB', 'bOb']
+        self.assertEqual(spell.known(known_words), {'bob'})
+
+        self.assertEqual(spell.candidates('BB'), {'bob', 'bab'})
+        self.assertEqual(spell.correction('BB'), 'bob')
+
+    def test_pop(self):
+        ''' test the popping of a word '''
+        spell = SpellChecker()
+        self.assertEqual('apple' in spell, True)
+        self.assertGreater(spell.word_frequency.pop('apple'), 1)
+        self.assertEqual('apple' in spell, False)
+
+    def test_pop_default(self):
+        ''' test the default value being set for popping a word '''
+        spell = SpellChecker()
+        self.assertEqual('appleies' in spell, False)
+        self.assertEqual(spell.word_frequency.pop('appleies', False), False)

pip install -e .[dev]
parse_log_pytest
pytest
pytest
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
certifi==2021.5.30
importlib-metadata @ file:///tmp/build/80754af9/importlib-metadata_1631916693255/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
-e git+https://github.com/barrust/pyspellchecker.git@689aa310a75c894a041e50cca9e8ce4e4cb37b39#egg=pyspellchecker
pytest==6.2.4
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: pyspellchecker
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib-metadata=4.8.1=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
prefix: /opt/conda/envs/pyspellchecker

tests/spellchecker_test.py::TestSpellChecker::test_capitalization tests/spellchecker_test.py::TestSpellChecker::test_pop tests/spellchecker_test.py::TestSpellChecker::test_pop_default
tests/spellchecker_test.py::TestSpellChecker::test_add_word tests/spellchecker_test.py::TestSpellChecker::test_candidates tests/spellchecker_test.py::TestSpellChecker::test_checking_odd_word tests/spellchecker_test.py::TestSpellChecker::test_correction tests/spellchecker_test.py::TestSpellChecker::test_edit_distance_invalud tests/spellchecker_test.py::TestSpellChecker::test_edit_distance_one tests/spellchecker_test.py::TestSpellChecker::test_edit_distance_one_property tests/spellchecker_test.py::TestSpellChecker::test_edit_distance_two tests/spellchecker_test.py::TestSpellChecker::test_import_export_gzip tests/spellchecker_test.py::TestSpellChecker::test_import_export_json tests/spellchecker_test.py::TestSpellChecker::test_load_external_dictionary tests/spellchecker_test.py::TestSpellChecker::test_load_text_file tests/spellchecker_test.py::TestSpellChecker::test_missing_dictionary tests/spellchecker_test.py::TestSpellChecker::test_remove_by_threshold tests/spellchecker_test.py::TestSpellChecker::test_remove_word tests/spellchecker_test.py::TestSpellChecker::test_remove_words tests/spellchecker_test.py::TestSpellChecker::test_spanish_dict tests/spellchecker_test.py::TestSpellChecker::test_unique_words tests/spellchecker_test.py::TestSpellChecker::test_unknown_words tests/spellchecker_test.py::TestSpellChecker::test_word_contains tests/spellchecker_test.py::TestSpellChecker::test_word_frequency tests/spellchecker_test.py::TestSpellChecker::test_word_in tests/spellchecker_test.py::TestSpellChecker::test_word_known tests/spellchecker_test.py::TestSpellChecker::test_word_probability tests/spellchecker_test.py::TestSpellChecker::test_words
spellchecker/spellchecker.py
spellchecker/spellchecker.py