@Override
 public void startElement(
     String nsURI, String strippedName, String tagName, Attributes attributes)
     throws SAXException {
   strippedName = strippedName.trim();
   String name = strippedName.length() == 0 ? tagName.trim() : strippedName;
   if (inAcross) {
     int clueNum = Integer.parseInt(attributes.getValue("cn"));
     if (clueNum > maxClueNum) {
       maxClueNum = clueNum;
     }
     try {
       acrossNumToClueMap.put(
           clueNum, URLDecoder.decode(attributes.getValue("c"), CHARSET_NAME));
     } catch (UnsupportedEncodingException e) {
       acrossNumToClueMap.put(clueNum, attributes.getValue("c"));
     }
   } else if (inDown) {
     int clueNum = Integer.parseInt(attributes.getValue("cn"));
     if (clueNum > maxClueNum) {
       maxClueNum = clueNum;
     }
     try {
       downNumToClueMap.put(clueNum, URLDecoder.decode(attributes.getValue("c"), CHARSET_NAME));
     } catch (UnsupportedEncodingException e) {
       downNumToClueMap.put(clueNum, attributes.getValue("c"));
     }
   } else if (name.equalsIgnoreCase("title")) {
     puz.setTitle(attributes.getValue("v"));
   } else if (name.equalsIgnoreCase("author")) {
     puz.setAuthor(attributes.getValue("v"));
   } else if (name.equalsIgnoreCase("width")) {
     puz.setWidth(Integer.parseInt(attributes.getValue("v")));
   } else if (name.equalsIgnoreCase("height")) {
     puz.setHeight(Integer.parseInt(attributes.getValue("v")));
   } else if (name.equalsIgnoreCase("allanswer")) {
     String rawGrid = attributes.getValue("v");
     Box[] boxesList = new Box[puz.getHeight() * puz.getWidth()];
     for (int i = 0; i < rawGrid.length(); i++) {
       char sol = rawGrid.charAt(i);
       if (sol != '-') {
         boxesList[i] = new Box();
         boxesList[i].setSolution(sol);
         boxesList[i].setResponse(' ');
       }
     }
     puz.setBoxesList(boxesList);
     puz.setBoxes(puz.buildBoxes());
   } else if (name.equalsIgnoreCase("across")) {
     inAcross = true;
   } else if (name.equalsIgnoreCase("down")) {
     inDown = true;
   }
 }