refactor observer internals