internal algorithm