public boolean write(OutputStream out, ProgressReporter progressReporter)
      throws SerializerException {
    CityModel cityModel = new CityModel();
    cityModel.setName(createNameList(getModel().getModelMetaData().getName()));
    JAXBBuilder builder = null;
    try {
      builder = ctx.createJAXBBuilder(getClass().getClassLoader());
    } catch (JAXBException e) {
      LOGGER.error("", e);
    }
    for (IfcProject ifcProject : getModel().getAll(IfcProject.class)) {
      for (IfcRelDecomposes ifcRelDecomposes : ifcProject.getIsDecomposedBy()) {
        for (IfcObjectDefinition ifcObjectDefinition : ifcRelDecomposes.getRelatedObjects()) {
          if (ifcObjectDefinition instanceof IfcBuilding) {
            IfcBuilding ifcBuilding = (IfcBuilding) ifcObjectDefinition;
            processBuilding(cityModel, ifcBuilding);
          } else if (ifcObjectDefinition instanceof IfcSite) {
            IfcSite ifcSite = (IfcSite) ifcObjectDefinition;
            for (IfcRelDecomposes siteComposites : ifcSite.getIsDecomposedBy()) {
              for (IfcObjectDefinition siteCompositeObject : siteComposites.getRelatedObjects()) {
                if (siteCompositeObject instanceof IfcBuilding) {
                  processBuilding(cityModel, (IfcBuilding) siteCompositeObject);
                }
              }
            }
          }
        }
      }
    }
    for (EObject eObject : model.getValues()) {
      if (eObject instanceof IfcProduct) {
        if (!convertedObjects.containsKey(eObject)) {
          //						System.out.println("Not converted: " + eObject);
        }
      }
    }
    try {
      CityGMLOutputFactory outputFactory =
          builder.createCityGMLOutputFactory(CityGMLVersion.v2_0_0);
      PrintWriter writer = new PrintWriter(out);
      CityGMLWriter cityGmlWriter = outputFactory.createCityGMLWriter(writer);

      cityGmlWriter.setPrefixes(CityGMLVersion.v2_0_0);
      cityGmlWriter.setWriteEncoding(true);
      cityGmlWriter.setSchemaLocations(CityGMLVersion.v2_0_0);
      cityGmlWriter.setIndentString("  ");
      cityGmlWriter.write(cityModel);
      cityGmlWriter.close();
      writer.flush();
    } catch (CityGMLWriteException e) {
      LOGGER.error("", e);
    }
    setMode(Mode.FINISHED);
    return false;
  }
  private void processBuilding(CityModel cityModel, IfcBuilding ifcBuilding)
      throws SerializerException {
    Building building = new Building();
    setGlobalId(building, ifcBuilding);
    setName(building.getName(), ifcBuilding.getName());

    CityObjectMember cityObjectMember = new CityObjectMember();
    cityObjectMember.setCityObject(building);
    cityModel.addCityObjectMember(cityObjectMember);

    IfcPostalAddress ifcBuildingAddress = ifcBuilding.getBuildingAddress();
    if (ifcBuildingAddress != null) {
      building.addAddress(createAddress(ifcBuildingAddress));
    }

    for (IfcRelContainedInSpatialStructure ifcRelContainedInSpatialStructure :
        ifcBuilding.getContainsElements()) {
      for (IfcProduct ifcProduct : ifcRelContainedInSpatialStructure.getRelatedElements()) {
        processBoundary(building, createFakeRoom(building), ifcProduct, null);
      }
    }

    for (IfcRelDecomposes ifcRelDecomposes : ifcBuilding.getIsDecomposedBy()) {
      for (IfcObjectDefinition ifcObjectDefinition : ifcRelDecomposes.getRelatedObjects()) {
        if (ifcObjectDefinition instanceof IfcBuildingStorey) {
          IfcBuildingStorey ifcBuildingStorey = (IfcBuildingStorey) ifcObjectDefinition;
          processStorey(building, ifcBuildingStorey);
        }
      }
    }
  }