public Serializable fromDOM(Document document) 
    {
        ContextFreePumpingLemma pl = (ContextFreePumpingLemma)PumpingLemmaFactory.createPumpingLemma
            (TYPE, document.getElementsByTagName(LEMMA_NAME).item(0).getTextContent());
        /*
         * Decode m, w, & i.
         */
        pl.setM(Integer.parseInt(document.getElementsByTagName(M_NAME).item(0).getTextContent()));
        pl.setW(document.getElementsByTagName(W_NAME).item(0).getTextContent());
        pl.setI(Integer.parseInt(document.getElementsByTagName(I_NAME).item(0).getTextContent()));       

        /*
         * Decode cases. 
         * 
         * Must decode cases before decoding the decomposition, otherwise 
         * the decomposition will be that of the last case. This is because,
         * when add case is called, the pumping lemma chooses the decomposition
         * to check if it's legal. 
         */
        readCases(document, pl);

        //Decode the attempts
        NodeList attempts = document.getDocumentElement().getElementsByTagName(ATTEMPT);
        for(int i = 0; i < attempts.getLength(); i++)
            pl.addAttempt(attempts.item(i).getTextContent());        
        
        //Decode the first player.         
        pl.setFirstPlayer(document.getElementsByTagName(FIRST_PLAYER).item(0).getTextContent());
             
        // Decode the decomposition.
        int uLength = Integer.parseInt(document.getElementsByTagName(U_NAME).item(0).getTextContent());
        int vLength = Integer.parseInt(document.getElementsByTagName(V_NAME).item(0).getTextContent());
        int xLength = Integer.parseInt(document.getElementsByTagName(X_NAME).item(0).getTextContent());
        int yLength = Integer.parseInt(document.getElementsByTagName(Y_NAME).item(0).getTextContent());
        
        pl.setDecomposition(new int[]{uLength, vLength, xLength, yLength});
        
        //Return!
        return pl;
    }