class CfakeRipper extends AbstractHTMLRipper {

    public CfakeRipper(URL url) throws IOException {
    super(url);
    }

        @Override
        public String getHost() {
            return "cfake";
        }

        @Override
        public String getDomain() {
            return "cfake.com";
        }

        @Override
        public String getGID(URL url) throws MalformedURLException {
            Pattern p = Pattern.compile("https?://cfake\\.com/picture/([a-zA-Z1-9_-]*)/\\d+/?$");
            Matcher m = p.matcher(url.toExternalForm());
            if (m.matches()) {
                return m.group(1);
            }
            throw new MalformedURLException("Expected cfake URL format: " +
                            "cfake.com/picture/MODEL/ID - got " + url + " instead");
        }

        @Override
        public Document getFirstPage() throws IOException {
            // "url" is an instance field of the superclass
            return Http.url(url).get();
        }

        @Override
        public Document getNextPage(Document doc) throws IOException {<FILL_FUNCTION_BODY>}

        @Override
        public List<String> getURLsFromPage(Document doc) {
            List<String> result = new ArrayList<>();
                for (Element el : doc.select("table.display > tbody > tr > td > table > tbody > tr > td > a")) {
                    if (el.attr("href").contains("upload")) {
                        return result;
                    } else {
                        String imageSource = el.select("img").attr("src");
                        // We remove the .md from images so we download the full size image
                        // not the thumbnail ones
                        imageSource = imageSource.replace("thumbs", "photos");
                        result.add("http://cfake.com" + imageSource);
                    }
                }
                return result;
        }

        @Override
        public void downloadURL(URL url, int index) {
            addURLToDownload(url, getPrefix(index));
        }
    }

            // Find next page
            String nextUrl = "";
            // We use comic-nav-next to the find the next page
            Element elem = doc.select("td > div.next > a").first();
                if (elem == null) {
                    throw new IOException("No more pages");
                }
                String nextPage = elem.attr("href");
                // Some times this returns a empty string
                // This for stops that
                if (nextPage.equals("")) {
                    return null;
                }
                else {
                    return Http.url("http://cfake.com" + nextPage).get();
                }
            
<methods>public boolean addURLToDownload(java.net.URL, java.io.File, java.lang.String, Map<java.lang.String,java.lang.String>, java.lang.Boolean) ,public boolean addURLToDownload(java.net.URL, java.io.File) ,public boolean canRip(java.net.URL) ,public void downloadCompleted(java.net.URL, java.io.File) ,public void downloadErrored(java.net.URL, java.lang.String) ,public void downloadExists(java.net.URL, java.io.File) ,public int getCompletionPercentage() ,public int getCount() ,public abstract java.lang.String getHost() ,public Document getNextPage(Document) throws java.io.IOException,public java.lang.String getStatusText() ,public void rip() throws java.io.IOException,public java.net.URL sanitizeURL(java.net.URL) throws java.net.MalformedURLException,public boolean saveText(java.net.URL, java.lang.String, java.lang.String, int) ,public void setWorkingDir(java.net.URL) throws java.io.IOException<variables>private Map<java.net.URL,java.io.File> itemsCompleted,private Map<java.net.URL,java.lang.String> itemsErrored,private Map<java.net.URL,java.io.File> itemsPending