@Override
    public TreeValue next() {
        // check left branch
        if (place.hasLeftSon()) {
            place = place.getLeftSon();
            way.push(place.getValue(), place.getId(), place.getLeftSon(), place.getRightSon());
            return this.next();
        }
        // check right branch
        if (place.hasRightSon()) {
            place = place.getRightSon();
            way.push(place.getValue(), place.getId(), place.getLeftSon(), place.getRightSon());
            return this.next();
        }
        // check leaf
        if (!place.hasLeftSon() && !place.hasRightSon()) {
            // medium result
            TreeElement<TreeValue> help = new TreeElement<>(way.top().getValue(), 0);
            this.remove();
            // check viewed links
            if (this.hasNext()) {
                if (place.getLeftSon() != null && place.getLeftSon().getValue() == help.getValue()) {
                    place.setLeftSon(null);
                } else {
                    if (place.getRightSon() != null) {
                        place.setRightSon(null);
                    }
                }
            }
            return help.getValue();
        }
        
        return place.getValue();
    }