initial copy from bjc, some refactoring (not complete or tested)