@Override
    public DataForm parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
        DataForm.Type dataFormType = DataForm.Type.fromString(parser.getAttributeValue("", "type"));
        DataForm.Builder dataForm = DataForm.builder(dataFormType);

        String formType = null;
        DataForm.ReportedData reportedData = null;

        outerloop: while (true) {
            XmlPullParser.Event eventType = parser.next();
            switch (eventType) {
            case START_ELEMENT:
                String name = parser.getName();
                String namespace = parser.getNamespace();
                XmlEnvironment elementXmlEnvironment = XmlEnvironment.from(parser, xmlEnvironment);
                switch (name) {
                case "instructions":
                    dataForm.addInstruction(parser.nextText());
                    break;
                case "title":
                    dataForm.setTitle(parser.nextText());
                    break;
                case "field":
                    // Note that we parse this form field without any potential reportedData. We only use reportedData
                    // to lookup form field types of fields under <item/>.
                    FormField formField = parseField(parser, elementXmlEnvironment, formType);

                    TextSingleFormField hiddenFormTypeField = formField.asHiddenFormTypeFieldIfPossible();
                    if (hiddenFormTypeField != null) {
                        if (formType != null) {
                            throw new SmackParsingException("Multiple hidden form type fields");
                        }
                        formType = hiddenFormTypeField.getValue();
                    }

                    dataForm.addField(formField);
                    break;
                case "item":
                    DataForm.Item item = parseItem(parser, elementXmlEnvironment, formType, reportedData);
                    dataForm.addItem(item);
                    break;
                case "reported":
                    if (reportedData != null) {
                        throw new SmackParsingException("Data form with multiple <reported/> elements");
                    }
                    reportedData = parseReported(parser, elementXmlEnvironment, formType);
                    dataForm.setReportedData(reportedData);
                    break;
                // See XEP-133 Example 32 for a corner case where the data form contains this extension.
                case RosterPacket.ELEMENT:
                    if (namespace.equals(RosterPacket.NAMESPACE)) {
                        dataForm.addExtensionElement(RosterPacketProvider.INSTANCE.parse(parser, null));
                    }
                    break;
                // See XEP-141 Data Forms Layout
                case DataLayout.ELEMENT:
                    if (namespace.equals(DataLayout.NAMESPACE)) {
                        dataForm.addExtensionElement(DataLayoutProvider.parse(parser));
                    }
                    break;
                }
                break;
            case END_ELEMENT:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
            default:
                // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
                break;
            }
        }
        return dataForm.build();
    }
@Test
    public void testRetrieveFieldTypeFromReported() throws XmlPullParserException, IOException, SmackParsingException {

        String firstForm =
                        "<x xmlns='jabber:x:data' type='form'>" +
                        "  <title>Advanced User Search</title>" +
                        "  <instructions>The following fields are available for searching. Wildcard (*) characters are allowed as part of the query.</instructions>" +
                        "  <field var='FORM_TYPE' type='hidden'>" +
                        "    <value>jabber:iq:search</value>" +
                        "  </field>" +
                        "  <field label='Search' var='search'>" +
                        "    <required/>" +
                        "  </field>" +
                        "  <field label='Username' var='Username' type='boolean'>" +
                        "    <value>true</value>" +
                        "  </field>" +
                        "  <field label='Name' var='Name' type='boolean'>" +
                        "    <value>true</value>" +
                        "  </field>" +
                        "  <field label='Email' var='Email' type='boolean'>" +
                        "    <value>true</value>" +
                        "  </field>" +
                        "</x>";
        XmlPullParser parser = PacketParserUtils.getParserFor(firstForm);
        DataForm firstDataForm = DataFormProvider.INSTANCE.parse(parser);
        FormField usernameFormField = firstDataForm.getField("Username");
        assertEquals(FormField.Type.bool, usernameFormField.getType());

        String secondForm =
                        "<x xmlns='jabber:x:data' type='result'>" +
                        "  <field var='FORM_TYPE' type='hidden'/>" +
                        "  <reported>" +
                        "    <field var='jid' type='jid-single' label='JID'/>" +
                        "    <field var='Username' type='text-single' label='Username'/>" +
                        "    <field var='Name' type='text-single' label='Name'/>" +
                        "    <field var='Email' type='text-single' label='Email'/>" +
                        "  </reported>" +
                        "  <item>" +
                        "    <field var='Email'>" +
                        "      <value>" +
                        "        0" +
                        "      </value>" +
                        "    </field>" +
                        "    <field var='jid'>" +
                        "      <value>frank@orphu</value>" +
                        "    </field>" +
                        "    <field var='Username'>" +
                        "      <value>" +
                        "        frank" +
                        "      </value>" +
                        "    </field>" +
                        "    <field var='Name'>" +
                        "      <value>" +
                        "        0" +
                        "      </value>" +
                        "    </field>" +
                        "  </item>" +
                        "  <item>" +
                        "    <field var='Email'>" +
                        "      <value>" +
                        "      </value>" +
                        "    </field>" +
                        "    <field var='jid'>" +
                        "      <value>frank2@orphu</value>" +
                        "    </field>" +
                        "    <field var='Username'>" +
                        "      <value>" +
                        "        frank2" +
                        "      </value>" +
                        "    </field>" +
                        "    <field var='Name'>" +
                        "      <value>" +
                        "      </value>" +
                        "    </field>" +
                        "  </item>" +
                        "</x>";
        parser = PacketParserUtils.getParserFor(secondForm);
        DataForm secondDataForm = DataFormProvider.INSTANCE.parse(parser);
        List<DataForm.Item> items = secondDataForm.getItems();
        assertEquals(2, items.size());
    }