import java.util.*; // for List and ArrayList

// stubs: Color and Dictionary don't work; we just want the rest to type-check
class Color {
    public Color(String s) {}
}
class Dictionary { 
    public static Dictionary findDictionary(String language) { return null; /*...*/ }
    public boolean contains(String s) { return true; /*...*/ }
    /*...*/
}

/* As a final but separate style issue, it was wrong from the start 
   to mix specific appearance choices in with spell-checking (poor cohesion).
   
   So while this still is not ideal, we abstract out the notion of
   color choices, which creates a separate concept that is broadly
   useful since a color for errors applies to more than spell-checking
   (wrong quiz answers, wrong phone-number format, ...)
*/
interface ColorChoices {
    public Color defaultColor();
    public Color errorColor();
    /* ... */
}
class StandardColors implements ColorChoices {
    public Color defaultColor() {
        return new Color("black");
    }
    public Color errorColor() {
        return new Color("red");
    }
    /* ... */
}

interface WordChangeListener {
    public void onWordChange(StyledWord w);
}

class StyledWord {
    private StringBuffer text  = new StringBuffer();
    private Color        color = new Color("black");

    private List<WordChangeListener> listeners = new ArrayList<WordChangeListener>();
 
    public StyledWord() { }
    public void addListener(WordChangeListener l) {
        listeners.add(l);
    }
    public void removeListener(WordChangeListener l) {
        listeners.remove(l);
    }

    private void afterWordChange() {
        for(WordChangeListener listener : listeners) {
            listener.onWordChange(this);
        }
    }
    public void addLetter(char c, int position) { 
        text.insert(position,c); 
        afterWordChange();
    }
    public void deleteLetter(int position) { 
        text.delete(position,position+1); 
        afterWordChange();
    }
    public String getText() {
        return new String(text);
    }
    public Color getColor() {
        return color;
    }
    public void setColor(Color c) {
        color = c;
    }
    /*...*/
}

class Spellchecker implements WordChangeListener {
    private Dictionary dictionary;
    private ColorChoices colors;
    public Spellchecker(String language, ColorChoices cs) {
        dictionary = Dictionary.findDictionary(language);
        colors = cs;
    }
    public boolean performSpellcheck(StyledWord word) {
        return dictionary.contains(word.getText());
    }
    public void onWordChange(StyledWord word) {
        if(performSpellcheck(word)) {
            word.setColor(colors.defaultColor());
        } else {
            word.setColor(colors.errorColor());
        }
    }
}

class QRemover implements WordChangeListener {
    public QRemover() { }
    public void removeQs(StyledWord word) {
        // subtle that we can delete only one Q but we'll get 
        // called-back again after changing the text
        int i = word.getText().indexOf('Q');
        if(i != -1) {
            word.deleteLetter(i);
        }
    }
    public void onWordChange(StyledWord word) {
        removeQs(word);
    }
}

class ChangeCounter implements WordChangeListener { 
    private int count = 0;
    public ChangeCounter() { }
    public void onWordChange(StyledWord word) {
        count++;
    }
    public int getCount() {
        return count;
    }
}

class Main {
    public static void main(String[] args) {
        StyledWord w = new StyledWord();
        w.addListener(new Spellchecker("English", new StandardColors()));
        // ... use w in various methods in the application
    }
}