public TupleFour<String, List<Object>, String, Long> getDriveElement() throws Exception    {
        String name;
        List<Object> trigger = null;
        String triggerable = null;
        long freq = 0;

        if (!match(new String[] {"LPAREN",}))
            log.error("Expected '(' to start drive element instead " +
                "of " + token.value);
        nextToken();
        if(!match(new String[] {"NAME",}))
            log.error("Expected valid drive element name instead of " + token.value);
        name = token.value;
        nextToken();
        // ( NIL | "(" <trigger> | ) NAME
        if (!match(new String[] {"NAME","LPAREN","NIL"}))
            log.error("Expected name of triggerable, '(' or 'nil' " +
                "instead of "+ token.value + " in drive element " +  name);
        // get trigger if there is one
        if (match(new String[] {"NIL","LPAREN"}))
        {
        	if (match(new String[] {"NIL",}))
                nextToken();
            else            {
                nextToken();
                trigger = getTrigger();
            }
            if (!match(new String[] {"NAME",}))
                log.error("Expected name of triggerable instead of "+token.value +
                    "in drive elements " +  name);     
        }
        // get triggerable (NAME)
        triggerable = token.value;
        nextToken();
        // check for frequency
        // ( NIL | "(" <freq> | )
        if (match(new String[] {"LPAREN","NIL"}))
            if (match(new String[] {"NIL",}))
                nextToken();
            else            {
                nextToken();
                freq = getFreq();
            }
        // <opt-comment> ")"
        getOptComment();
        if (!match(new String[] {"RPAREN",}))
            log.error("Expected ')' instead of '"+token.value+" as the end of drive " +
                "element " +  name);
        nextToken();

        return new TupleFour<String,List<Object>,String,Long>(name,trigger,triggerable,freq);
    }