Frag compile(Frag frag) {

        // keep circling and eating the str
        while (true) {
            // when the str is empty, return the fragment
            if (frag.str.length() == 0) {
                return frag;
            }

            int TagStart = frag.str.indexOf("<");

            if (TagStart != 0) {
                // theres a chunk of characters here, store it and go on
                int thisary = frag.ary.length();
                frag.ary.setElementAt(Node.createChardata(), thisary);
                if (TagStart == -1) {
                    frag.ary.setElementAt(entity(frag.str), thisary, JSArray.Value);
                    frag.str = "";
                } else {
                    frag.ary.setElementAt(entity(substring(frag.str, 0, TagStart)), thisary, JSArray.Value);
                    frag.str = substring(frag.str, TagStart, frag.str.length());
                }
            } else {
                // determine what the next section is, and process it
                if (substring(frag.str, 1, 2).equals("?")) {
                    frag = tagPI(frag);
                } else {
                    if (substring(frag.str, 1, 4).equals("!--")) {
                        frag = tagComment(frag);
                    } else {
                        if (substring(frag.str, 1, 9).equals("![CDATA[")) {
                            frag = tagCData(frag);
                        } else {
                            if (substring(frag.str, 1, frag.end.length() + 3).equals("/" + frag.end + ">") || strip(substring(frag.str, 1, frag.end.length() + 3)).equals("/" + frag.end)) {
                                // found the end of the current tag, end the recursive process and return
                                frag.str = substring(frag.str, frag.end.length() + 3, frag.str.length());
                                frag.end = "";
                                return frag;
                            } else {
                                frag = tagElement(frag);
                            }
                        }
                    }
                }

            }
        }
        //MC return "";
    }