put core logic into new function