public ArrayList<ArrayList<String>> partition(String s) {

    ArrayList<ArrayList<String>> results = new ArrayList<ArrayList<String>>();

    if (s.isEmpty()) {
      return results;
    }
    if (s.length() == 1) {
      ArrayList<String> e = new ArrayList<String>();
      e.add(s);
      results.add(e);
      return results;
    }

    for (int i = 1 ; i <= s.length() ; i++) {
      String head = s.substring(0, i);
      if (isPalindrome(head)) {
        ArrayList<ArrayList<String>> rst = partition(s.substring(i));
        for (ArrayList<String> al : rst) {
          al.add(0, head);
        }
        // Bug, should be very careful with edge case!
        if (i == s.length()) {
          ArrayList<String> e = new ArrayList<String>();
          e.add(head);
          results.add(e);
        }
        results.addAll(rst);
      }
    }


    return results;
  }