import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
import javax.swing.tree.*;
class main {
static > JTree jDynamicTree(A root, IF1 makeChildren, Object... __) {
  return jDynamicTree(root, toF1(makeChildren), __);
}
static > JTree jDynamicTree(final A root, final F1 makeChildren, final Object... __) {
  return swing(new F0() { public JTree get() { try { 
    IF1 valueToText =  (IF1) (optPar("valueToText",__));
    DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(root);
    rootNode.add(new DefaultMutableTreeNode(jDynamicTree_dummy()));
    final JTree tree = new JTree(rootNode) {
      public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        if (valueToText != null) {
          Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
          try { return str(valueToText.get((A) userObject)); } catch (Throwable __e) { _handleException(__e); }
        }
        return super.convertValueToText(value, selected, expanded, leaf, row, hasFocus);
      }
    };
    tree.setShowsRootHandles(true);
    tree.collapseRow(0);
    final boolean keepChildrenOnCollapse = optParam(__, "keepChildrenOnCollapse", false);
    boolean makeChildrenIsFast = boolParam("makeChildrenIsFast",__) || makeChildren == null;
    boolean debug = boolPar("debug",__);
    
    class jDynamicTree_Listener implements TreeWillExpandListener {
      public void treeWillCollapse(TreeExpansionEvent e) {}
      public void treeWillExpand(TreeExpansionEvent e) { try {
        if (debug) print("treeWillExpand");
        DefaultMutableTreeNode node =  (DefaultMutableTreeNode) (e.getPath().getLastPathComponent());
        if (!keepChildrenOnCollapse || jDynamicTree_isInDummyState(node)) {
          List l = asList(callF(makeChildren, (A) node.getUserObject()));
          if (makeChildrenIsFast
            ? replaceTreeNodeChildren_withDummyChild2(node, l, jDynamicTree_dummy(), makeChildren)
            : replaceTreeNodeChildren_withDummyChild(node, l, jDynamicTree_dummy()))
            ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node);
        }
      } catch (Throwable __e) { _handleException(__e); }}
    }
    tree.addTreeWillExpandListener(new jDynamicTree_Listener());
    
    return tree;
   } catch (Exception __e) { throw rethrow(__e); } }
  public String toString() { return "optPar IF1 valueToText;\r\n    DefaultMutableTreeNode rootNode = new(root..."; }});
}
static F1 toF1(final Object f) {
  return functionToF1(f);
}
static Object swing(Object f) {
  return swingAndWait(f);
}
static  A swing(F0 f) {
  return (A) swingAndWait(f);
}
static  A swing(IF0 f) {
  return (A) swingAndWait(f);
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static  A get(List l, int idx) {
  return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static  B get(Map map, A key) {
  ret map != null ? map.get(key) : null;
}*/
static  A get(A[] l, int idx) {
  return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
  return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
  try {
    if (o == null) return null;
    if (o instanceof Class) return get((Class) o, field);
    
    if (o instanceof Map)
      return ((Map) o).get(field);
      
    Field f = getOpt_findField(o.getClass(), field);
    if (f != null) {
      makeAccessible(f);
      return f.get(o);
    }
      
    
  } catch (Exception e) {
    throw asRuntimeException(e);
  }
  throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
  return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
  if (o == null) return null;
  Field f = get_findField(o.getClass(), field);
  makeAccessible(f);
  return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
  try {
    Field f = get_findStaticField(c, field);
    makeAccessible(f);
    return f.get(null);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}
static Field get_findStaticField(Class> c, String field) {
  Class _c = c;
  do {
    for (Field f : _c.getDeclaredFields())
      if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
        return f;
    _c = _c.getSuperclass();
  } while (_c != null);
  throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
  Class _c = c;
  do {
    for (Field f : _c.getDeclaredFields())
      if (f.getName().equals(field))
        return f;
    _c = _c.getSuperclass();
  } while (_c != null);
  throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
  return get(o, field);
}
static  A optPar(ThreadLocal tl, A defaultValue) {
  A a = tl.get();
  if (a != null) {
    tl.set(null);
    return a;
  }
  return defaultValue;
}
static  A optPar(ThreadLocal tl) {
  return optPar(tl, null);
}
static Object optPar(Object[] params, String name) {
  return optParam(params, name);
}
static Object optPar(String name, Object[] params) {
  return optParam(params, name);
}
static Object optPar(String name, Map params) {
  return optParam(name, params);
}
static  A optPar(Object[] params, String name, A defaultValue) {
  return optParam(params, name, defaultValue);
}
static  A optPar(String name, Object[] params, A defaultValue) {
  return optParam(params, name, defaultValue);
}
// dummy text you can use as a temporary child for a lazy-filled node
static String jDynamicTree_dummy_value = new String("");
static String jDynamicTree_dummy() {
  return jDynamicTree_dummy_value;
}
static String str(Object o) {
  return o == null ? "null" : o.toString();
}
static String str(char[] c) {
  return new String(c);
}
static volatile PersistableThrowable _handleException_lastException;
static List _handleException_onException = synchroList(ll("printStackTrace2"));
static void _handleException(Throwable e) {
  _handleException_lastException = persistableThrowable(e);
  
  Throwable e2 = innerException(e);
  if (e2.getClass() == RuntimeException.class && eq(e2.getMessage(), "Thread cancelled.") || e2 instanceof InterruptedException)
    return;
    
  for (Object f : cloneList(_handleException_onException)) try {
    callF(f, e);
  } catch (Throwable e3) {
    printStackTrace2(e3); // not using pcall here - it could lead to endless loops
  }
}
static  A optParam(ThreadLocal tl, A defaultValue) {
  return optPar(tl, defaultValue);
}
static  A optParam(ThreadLocal tl) {
  return optPar(tl);
}
static Object optParam(String name, Map params) {
  return mapGet(params, name);
}
// now also takes a map as single array entry
static  A optParam(Object[] opt, String name, A defaultValue) {
  int n = l(opt);
  if (n == 1 && opt[0] instanceof Map) {
    Map map =  (Map) (opt[0]);
    return map.containsKey(name) ? (A) map.get(name) : defaultValue;
  }
  if (!even(l(opt))) throw fail("Odd parameter length");
  for (int i = 0; i < l(opt); i += 2)
    if (eq(opt[i], name))
      return (A) opt[i+1];
  return defaultValue;
}
static Object optParam(Object[] opt, String name) {
  return optParam(opt, name, null);
}
static Object optParam(String name, Object[] params) {
  return optParam(params, name);
}
static boolean boolParam(ThreadLocal tl) {
  return boolOptParam(tl);
}
// defaults to false
static boolean boolParam(Object[] __, String name) {
  return boolOptParam(__, name);
}
static boolean boolParam(String name, Object[] __) {
  return boolOptParam(name, __);
}
static boolean boolPar(ThreadLocal tl) {
  return boolOptParam(tl);
}
// defaults to false
static boolean boolPar(Object[] __, String name) {
  return boolOptParam(__, name);
}
static boolean boolPar(String name, Object[] __) {
  return boolOptParam(__, name);
}
static boolean boolPar(String name, Map __) {
  return boolOptParam(name, __);
}
static boolean boolPar(String name, Object[] params, boolean defaultValue) {
  return optParam(params, name, defaultValue);
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal