private static int gather(LinkedList<Fragment> dest, LinkedList<Fragment> src, int cut, int poffset) {

        /*
         * move hunks in source that are less than cut to dest, but compensate
         * for changes in offset. The last hunk may be split if necessary
         * (oberlaps cut).
         */
        int offset = poffset;
        Fragment s = null;

        for (Iterator<Fragment> iter = src.iterator(); iter.hasNext();) {
            s = iter.next();
            if (cut <= s.start + offset) {
                break; /* we've gone far enough */
            }

            int postend = offset + s.start + s.len();
            if (postend <= cut) {
                /* save this hunk as it is */
                offset += s.start + s.len() - s.end;
                dest.add(s);
                iter.remove();

            } else {
                /* This hunk must be broken up */
                int cutAt = cut - offset;
                if (s.end < cutAt) {
                    cutAt = s.end;
                }
                int length = cut - offset - s.start;
                if (s.len() < length) {
                    length = s.len();
                }

                offset += s.start + length - cutAt;
                Fragment d = new Fragment();
                d.start = s.start;
                d.end = cutAt;

                d.data = s.data;
                d.offset = s.offset;

                d.len(length);
                dest.add(d);

                s.start = cutAt;
                s.len(s.len() - length);
                s.offset += length;
                break;
            }
        }

        if (0 < src.size() && s != src.get(0)) {
            throw new IllegalStateException("src head should be s");
        }
        return offset;
    }