moved detection logic into user implementation