implement a good part of pattern matching