class GephiReader {

    static final String VERSION = "0.9";

    public static ProjectImpl readProject(XMLStreamReader reader, ProjectsImpl projects) throws Exception {
        ProjectImpl project = null;
        boolean end = false;
        while (reader.hasNext() && !end) {
            Integer eventType = reader.next();
            if (eventType.equals(XMLEvent.START_ELEMENT)) {
                String name = reader.getLocalName();
                if ("projectFile".equalsIgnoreCase(name) || "gephiFile".equalsIgnoreCase(name)) {
                    //Version
                    String version = reader.getAttributeValue(null, "version");
                    if (version == null || version.isEmpty() ||
                        Double.parseDouble(version) < Double.parseDouble(VERSION)) {
                        throw new GephiFormatException(
                            "Gephi project file version must be at least of version " + VERSION);
                    }
                } else if ("project".equalsIgnoreCase(name)) {
                    String projectName = reader.getAttributeValue(null, "name");
                    String projectId = reader.getAttributeValue(null, "id");
                    if (projectId == null) {
                        // Before 0.10 version we didn't have unique project ids
                        project = new ProjectImpl(projectName);
                    } else {
                        if (projects != null) {
                            project = projects.getProjectByIdentifier(projectId);
                        }
                        if (project == null) {
                            project = new ProjectImpl(projectId, projectName);
                        }
                    }

                    project.getLookup().lookup(WorkspaceProviderImpl.class);

                    if (reader.getAttributeValue(null, "ids") != null) {
                        int workspaceIds = Integer.parseInt(reader.getAttributeValue(null, "ids"));
                        project.setWorkspaceIds(workspaceIds);
                    }
                } else if ("metadata".equalsIgnoreCase(name)) {
                    readProjectMetadata(reader, project);
                }
            } else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
                if ("project".equalsIgnoreCase(reader.getLocalName())) {
                    end = true;
                }
            }
        }

        return project;
    }

    public static WorkspaceImpl readWorkspace(XMLStreamReader reader, ProjectImpl project) throws Exception {
        WorkspaceImpl workspace = null;
        boolean end = false;
        while (reader.hasNext() && !end) {
            Integer eventType = reader.next();
            if (eventType.equals(XMLEvent.START_ELEMENT)) {
                String name = reader.getLocalName();
                if ("workspace".equalsIgnoreCase(name)) {
                    //Id
                    Integer workspaceId;
                    if (reader.getAttributeValue(null, "id") == null ||
                        project.getWorkspace(Integer.parseInt(reader.getAttributeValue(null, "id"))) != null) {
                        workspaceId = project.nextWorkspaceId();
                    } else {
                        workspaceId = Integer.parseInt(reader.getAttributeValue(null, "id"));
                    }

                    workspace = project.newWorkspace(workspaceId);
                    WorkspaceInformationImpl info = workspace.getLookup().lookup(WorkspaceInformationImpl.class);

                    //Name
                    info.setName(reader.getAttributeValue(null, "name"));

                    //Status
                    String workspaceStatus = reader.getAttributeValue(null, "status");
                    if (workspaceStatus.equals("open")) {
                        info.open();
                    } else if (workspaceStatus.equals("closed")) {
                        info.close();
                    } else {
                        info.invalid();
                    }
                } else if ("metadata".equalsIgnoreCase(name)) {
                    readWorkspaceMetadata(reader, workspace);
                }
            } else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
                if ("workspace".equalsIgnoreCase(reader.getLocalName())) {
                    end = true;
                }
            }
        }

        return workspace;
    }

    private static void readWorkspaceMetadata(XMLStreamReader reader, Workspace workspace) throws Exception {
        String property = null;
        while (reader.hasNext()) {
            Integer eventType = reader.next();
            if (eventType.equals(XMLEvent.START_ELEMENT)) {
                property = reader.getLocalName();
            } else if (eventType.equals(XMLStreamReader.CHARACTERS)) {
                if (property != null && property.equals("description")) {
                    String desc = reader.getText();
                    workspace.getWorkspaceMetadata().setDescription(desc);
                } else if (property != null && property.equals("title")) {
                    String title = reader.getText();
                    workspace.getWorkspaceMetadata().setTitle(title);
                }
            } else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
                if ("metadata".equalsIgnoreCase(reader.getLocalName())) {
                    return;
                }
            }
        }
    }

    private static void readProjectMetadata(XMLStreamReader reader, ProjectImpl project) throws Exception {<FILL_FUNCTION_BODY>}

    public static void readWorkspaceChildren(Workspace workspace, XMLStreamReader reader,
                                             WorkspaceXMLPersistenceProvider persistenceProvider) throws Exception {
        String identifier = persistenceProvider.getIdentifier();
        boolean end = false;
        while (reader.hasNext() && !end) {
            Integer eventType = reader.next();
            if (eventType.equals(XMLEvent.START_ELEMENT)) {
                String name = reader.getLocalName();
                if (identifier.equals(name)) {
                    try {
                        persistenceProvider.readXML(reader, workspace);
                    } catch (UnsupportedOperationException e) {
                    }
                }
            } else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
                if (identifier.equalsIgnoreCase(reader.getLocalName())) {
                    end = true;
                }
            }
        }
    }
}

        String property = null;
        while (reader.hasNext()) {
            Integer eventType = reader.next();
            if (eventType.equals(XMLEvent.START_ELEMENT)) {
                property = reader.getLocalName();
            } else if (eventType.equals(XMLStreamReader.CHARACTERS)) {
                if (property != null) {
                    switch (property) {
                        case "title":
                            project.getProjectMetadata().setTitle(reader.getText());
                            break;
                        case "author":
                            project.getProjectMetadata().setAuthor(reader.getText());
                            break;
                        case "description":
                            project.getProjectMetadata().setDescription(reader.getText());
                            break;
                        case "keywords":
                            project.getProjectMetadata().setKeywords(reader.getText());
                            break;
                    }
                }
            } else if (eventType.equals(XMLStreamReader.END_ELEMENT)) {
                if ("metadata".equalsIgnoreCase(reader.getLocalName())) {
                    return;
                }
            }
        }
    
<no_super_class>