@Nullable
 private String expandMacroSet(
     String str, boolean firstQueueExpand, DataContext dataContext, Iterator<Macro> macros)
     throws Macro.ExecutionCancelledException {
   if (str == null) return null;
   while (macros.hasNext()) {
     Macro macro = macros.next();
     if (macro instanceof SecondQueueExpandMacro && firstQueueExpand) continue;
     String name = "$" + macro.getName() + "$";
     String macroNameWithParamStart = "$" + macro.getName() + "(";
     if (str.contains(name)) {
       String expanded = macro.expand(dataContext);
       // if (dataContext instanceof DataManagerImpl.MyDataContext) {
       //  // hack: macro.expand() can cause UI events such as showing dialogs ('Prompt' macro)
       // which may 'invalidate' the datacontext
       //  // since we know exactly that context is valid, we need to update its event count
       //
       // ((DataManagerImpl.MyDataContext)dataContext).setEventCount(IdeEventQueue.getInstance().getEventCount());
       // }
       if (expanded == null) {
         expanded = "";
       }
       str = StringUtil.replace(str, name, expanded);
     } else if (str.contains(macroNameWithParamStart)) {
       String macroNameWithParamEnd = ")$";
       Map<String, String> toReplace = null;
       int i = str.indexOf(macroNameWithParamStart);
       while (i != -1) {
         int j = str.indexOf(macroNameWithParamEnd, i + macroNameWithParamStart.length());
         if (j > i) {
           String param = str.substring(i + macroNameWithParamStart.length(), j);
           if (toReplace == null) toReplace = new THashMap<String, String>();
           String expanded = macro.expand(dataContext, param);
           if (expanded == null) {
             expanded = "";
           }
           toReplace.put(macroNameWithParamStart + param + macroNameWithParamEnd, expanded);
           i = j + macroNameWithParamEnd.length();
         } else {
           break;
         }
       }
       if (toReplace != null) {
         for (Map.Entry<String, String> entry : toReplace.entrySet()) {
           str = StringUtil.replace(str, entry.getKey(), entry.getValue());
         }
       }
     }
   }
   return str;
 }