code: protected static void readAndLocalizeDesign(
          Component component,
          InputStream designStream,
          CmsMessages messages,
          Map<String, String> macros) {
  
          try {
              byte[] designBytes = CmsFileUtil.readFully(designStream, true);
              final String encoding = "UTF-8";
              String design = new String(designBytes, encoding);
              CmsMacroResolver resolver = new CmsMacroResolver() {
  
                  @Override
                  public String getMacroValue(String macro) {
  
                      String result = super.getMacroValue(macro);
                      // The macro may contain quotes or angle brackets, so we need to escape the values for insertion into the design file
                      return CmsEncoder.escapeXml(result);
  
                  }
              };
  
              if (macros != null) {
                  for (Map.Entry<String, String> entry : macros.entrySet()) {
                      resolver.addMacro(entry.getKey(), entry.getValue());
                  }
              }
              if (messages != null) {
                  resolver.setMessages(messages);
              }
              String resolvedDesign = resolver.resolveMacros(design);
              Design.read(new ByteArrayInputStream(resolvedDesign.getBytes(encoding)), component);
          } catch (IOException e) {
              throw new RuntimeException("Could not read design", e);
          } finally {
              try {
                  designStream.close();
              } catch (IOException e) {
                  LOG.warn(e.getLocalizedMessage(), e);
              }
          }
      }
docs: Reads the given design and resolves the given macros and localizations.<p>
  
  @param component the component whose design to read
  @param designStream stream to read the design from
  @param messages the message bundle to use for localization in the design (may be null)
  @param macros other macros to substitute in the macro design (may be null)