public <B> void write(XElement element, ModeSettingsConverter<Location, B> converter) {
    Set<String> keys = new HashSet<String>();
    if (lastMaximizedLocation != null) {
      keys.addAll(lastMaximizedLocation.keySet());
    }
    if (lastMaximizedMode != null) {
      keys.addAll(lastMaximizedMode.keySet());
    }

    if (!keys.isEmpty()) {
      XElement xmaximized = element.addElement("maximized");

      for (String key : keys) {
        Path mode = lastMaximizedMode.get(key);
        Location location = lastMaximizedLocation.get(key);

        if (mode != null || location != null) {
          XElement xitem = xmaximized.addElement("item");
          xitem.addString("id", key);
          if (mode != null) {
            xitem.addElement("mode").setString(mode.toString());
          }
          if (location != null) {
            converter.writePropertyXML(
                converter.convertToSetting(location), xitem.addElement("location"));
          }
        }
      }
    }
  }
  public <B> void write(DataOutputStream out, ModeSettingsConverter<Location, B> converter)
      throws IOException {
    Version.write(out, Version.VERSION_1_0_8);
    if (lastMaximizedMode == null) {
      out.writeInt(0);
    } else {
      int count = 0;
      for (Path check : lastMaximizedMode.values()) {
        if (check != null) {
          count++;
        }
      }

      out.writeInt(count);
      for (Map.Entry<String, Path> entry : lastMaximizedMode.entrySet()) {
        if (entry.getValue() != null) {
          out.writeUTF(entry.getKey());
          out.writeUTF(entry.getValue().toString());
        }
      }
    }

    if (lastMaximizedLocation == null) {
      out.writeInt(0);
    } else {
      int count = 0;
      for (Location location : lastMaximizedLocation.values()) {
        if (location != null) {
          count++;
        }
      }

      out.writeInt(count);
      for (Map.Entry<String, Location> entry : lastMaximizedLocation.entrySet()) {
        if (entry.getValue() != null) {
          out.writeUTF(entry.getKey());
          converter.writeProperty(converter.convertToSetting(entry.getValue()), out);
        }
      }
    }
  }
  public <B> void read(DataInputStream in, ModeSettingsConverter<Location, B> converter)
      throws IOException {
    Version version = Version.read(in);
    version.checkCurrent();

    lastMaximizedLocation = new HashMap<String, Location>();
    lastMaximizedMode = new HashMap<String, Path>();

    int count = in.readInt();
    for (int i = 0; i < count; i++) {
      String key = in.readUTF();
      String value = in.readUTF();
      lastMaximizedMode.put(key, new Path(value));
    }

    count = in.readInt();
    for (int i = 0; i < count; i++) {
      String key = in.readUTF();
      Location location = converter.convertToWorld(converter.readProperty(in));
      lastMaximizedLocation.put(key, location);
    }
  }
  public <B> void read(XElement element, ModeSettingsConverter<Location, B> converter) {
    lastMaximizedLocation = new HashMap<String, Location>();
    lastMaximizedMode = new HashMap<String, Path>();

    XElement xmaximized = element.getElement("maximized");

    if (xmaximized != null) {
      for (XElement xitem : xmaximized.getElements("item")) {
        String key = xitem.getString("id");

        XElement xmode = xitem.getElement("mode");
        if (xmode != null) {
          lastMaximizedMode.put(key, new Path(xmode.getString()));
        }

        XElement xlocation = xitem.getElement("location");
        if (xlocation != null) {
          lastMaximizedLocation.put(
              key, converter.convertToWorld(converter.readPropertyXML(xlocation)));
        }
      }
    }
  }