public String[] getCategoryMembers(String name, int... ns) throws IOException
    {
        StringBuilder url = new StringBuilder(query);
        url.append("list=categorymembers&cmprop=title&cmlimit=30&cmtitle=Category:");
        url.append(URLEncoder.encode(normalize(name), "UTF-8"));
        constructNamespaceString(url, "cm", ns);

        // work around an arbitrary and silly limitation
        ArrayList<String> members = new ArrayList<String>(6667); // enough for most cats
        String next = "";
        do
        {
            if (!members.isEmpty())
                next = "&cmcontinue=" + URLEncoder.encode(next, "UTF-8");
            String line = fetch(url.toString() + next, "getCategoryMembers");

            // parse
            if (line.contains("cmcontinue"))
            {
                int a = line.indexOf("cmcontinue") + 12;
                next = line.substring(a, line.indexOf("\" />", a));
            }
            else
                next = "done";

            // parse
            for (int x = line.indexOf("title=\""); x >= 0; x = line.indexOf("title=\"", x))
            {
                int y = line.indexOf("\" />", x);
                String s = decode(line.substring(x + 7, y));
                
                if(!s.equals(name)) members.add(s);
                x = y;
            }
        }
        while (!next.equals("done"));
        log(Level.INFO, "Successfully retrieved contents of Category:" + name + " (" + members.size() + " items)", "getCategoryMembers");
        return members.toArray(new String[0]);
    }