public void setTokenizerProperties(TokenizerProperties props) throws NullPointerException {
    if (props == null) {
      throw new NullPointerException();
    }

    // set properties
    if (_properties != null) {
      _properties.removeTokenizerPropertyListener(this);
    }
    _properties = props;
    _properties.addTokenizerPropertyListener(this);

    // who is going to handle the various token types ?
    if (_properties instanceof WhitespaceHandler) {
      setWhitespaceHandler((WhitespaceHandler)_properties);
    } else {
      setWhitespaceHandler(new StandardWhitespaceHandler(_properties));
    }
    if (_properties instanceof SeparatorHandler) {
      setSeparatorHandler((SeparatorHandler)_properties);
    } else {
      setSeparatorHandler(new StandardSeparatorHandler(_properties));
    }
    if (_properties instanceof SequenceHandler) {
      setSequenceHandler((SequenceHandler)_properties);
    } else {
      setSequenceHandler(new StandardSequenceHandler(_properties));
    }
    if (props instanceof KeywordHandler) {
      setKeywordHandler((KeywordHandler)props);
    } else {
      setKeywordHandler(new StandardKeywordHandler(_properties));
    }
    if (_properties instanceof PatternHandler) {
      setPatternHandler((PatternHandler)_properties);
    } else {
      setPatternHandler(null);
    }
      
    // flag handling
    int newFlags = _properties.getParseFlags();

    if (newFlags != _flags) {
      propertyChanged(new TokenizerPropertyEvent(
                            TokenizerPropertyEvent.PROPERTY_MODIFIED,
                            new TokenizerProperty(TokenizerProperty.PARSE_FLAG_MASK, 
                                                  new String[] { Integer.toBinaryString(newFlags) } ),
                            new TokenizerProperty(TokenizerProperty.PARSE_FLAG_MASK, 
                                                  new String[] { Integer.toBinaryString(_flags) } )));
    }
  }