@Override
  public Element getState() {
    synchronized (myMappings) {
      if (myDeferredMappings != null) {
        return PerFileMappingState.write(myDeferredMappings, getValueAttribute());
      }

      cleanup();
      Element element = new Element("x");
      List<VirtualFile> files = new ArrayList<>(myMappings.keySet());
      files.sort((o1, o2) -> {
        if (o1 == null || o2 == null) return o1 == null ? o2 == null ? 0 : 1 : -1;
        return o1.getPath().compareTo(o2.getPath());
      });
      for (VirtualFile file : files) {
        MappingValue<T> mappingValue = myMappings.get(file);
        T value = mappingValue != null ? mappingValue.value() : null;
        String valueStr = mappingValue != null && mappingValue.unknownValue() != null ? mappingValue.unknownValue() :
                          value == null ? null :
                          serialize(value);
        if (valueStr == null) continue;
        Element child = new Element("file");
        element.addContent(child);
        child.setAttribute("url", file == null ? "PROJECT" : file.getUrl());
        child.setAttribute(getValueAttribute(), valueStr);
      }
      return element;
    }
  }
@Override
  public Element getState()