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; /*...*/ }
    /*...*/
}

/* We now allow dynamic addition and removal of listeners at any time, taking
   this functionality out of the constructors (though we could leave it
   there too if we wanted).

   Notice main has to change as a result.
 */
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;
    public Spellchecker(String language) {
        dictionary = Dictionary.findDictionary(language);
    }
    public void performSpellcheck(StyledWord word) {
        if(dictionary.contains(word.getText())) {
            word.setColor(new Color("black"));
        } else {
            word.setColor(new Color("red"));
        }
    }
    public void onWordChange(StyledWord word) {
        performSpellcheck(word);
    }
}

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"));
        // ... use w in various methods in the application
        // ... some time later ...
        w.removeListener(new Spellchecker("English"));
        w.addListener(new Spellchecker("Spanish"));
    }
}