예제 #1
0
  /**
   * Parses an annotation type definition
   *
   * @param docClass
   * @return
   */
  protected static Annotation ParseAnnotation(ClassDoc docClass) {
    AnnotationTypeDoc docAnnotation = (AnnotationTypeDoc) docClass;

    assert (docAnnotation != null);

    Annotation xmlAnnotation = new Annotation();

    xmlAnnotation.name = docClass.name();
    xmlAnnotation.qualifiedName = docClass.qualifiedName();
    xmlAnnotation.comment = docClass.commentText();
    xmlAnnotation.isIncluded = docClass.isIncluded();
    xmlAnnotation.scope = DetermineScope(docClass);

    AnnotationTypeElementDoc[] elements = docAnnotation.elements();

    if (elements != null && elements.length > 0) {
      ArrayList<AnnotationElement> elementList = new ArrayList<AnnotationElement>();

      for (AnnotationTypeElementDoc element : elements) {
        elementList.add(ParseAnnotationElement(element));
      }

      xmlAnnotation.elements = elementList.toArray(new AnnotationElement[] {});
    } else {
      log.debug("No elements in annotation: " + docClass.name());
    }

    xmlAnnotation.annotationInstances =
        ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName());
    return xmlAnnotation;
  }
예제 #2
0
  /**
   * Parse a method declaration. The declaration should be in the following format:
   *
   * <p>fully-qualified-method-name (args)
   *
   * <p>where the arguments are comma separated and all arguments other than primitives should have
   * fully qualified names. Arrays are indicating by trailing brackets. For example:
   *
   * <p>int int[] int[][] java.lang.String java.util.Date[]
   *
   * <p>The arguments are translated into BCEL types and a MethodDef is returned.
   */
  private MethodDef parse_method(StrTok st) {

    // Get the method name
    String method_name = st.need_word();

    // Get the opening paren
    st.need("(");

    // Read the arguments
    ArrayList<String> args = new ArrayList<String>();
    String tok = st.nextToken();
    if (tok != ")") {
      st.pushBack();
      do {
        tok = st.need_word();
        args.add(tok);
      } while (st.nextToken() == ",");
      st.pushBack();
      st.need(")");
    }

    // Convert the arguments to Type
    Type[] targs = new Type[args.size()];
    for (int ii = 0; ii < args.size(); ii++) {
      targs[ii] = BCELUtil.classname_to_type(args.get(ii));
    }

    return new MethodDef(method_name, targs);
  }
예제 #3
0
 private static ArrayList parseDNchain(String dnChain) {
   if (dnChain == null) {
     throw new IllegalArgumentException("The DN chain must not be null."); // $NON-NLS-1$
   }
   ArrayList parsed = new ArrayList();
   int startIndex = 0;
   startIndex = skipSpaces(dnChain, startIndex);
   while (startIndex < dnChain.length()) {
     int endIndex = startIndex;
     boolean inQuote = false;
     out:
     while (endIndex < dnChain.length()) {
       char c = dnChain.charAt(endIndex);
       switch (c) {
         case '"':
           inQuote = !inQuote;
           break;
         case '\\':
           endIndex++; // skip the escaped char
           break;
         case ';':
           if (!inQuote) break out;
       }
       endIndex++;
     }
     if (endIndex > dnChain.length()) {
       throw new IllegalArgumentException("unterminated escape");
     }
     parsed.add(dnChain.substring(startIndex, endIndex));
     startIndex = endIndex + 1;
     startIndex = skipSpaces(dnChain, startIndex);
   }
   return parsed;
 }
  protected void checkRoot(SimulatedArchivalUnit sau) {
    log.debug("checkRoot()");
    CachedUrlSet set = sau.getAuCachedUrlSet();
    Iterator setIt = set.flatSetIterator();
    ArrayList childL = new ArrayList(1);
    CachedUrlSet cus = null;
    while (setIt.hasNext()) {
      cus = (CachedUrlSet) setIt.next();
      childL.add(cus.getUrl());
    }

    String urlRoot = sau.getUrlRoot();

    String[] expectedA = new String[1];
    expectedA[0] = urlRoot;
    assertIsomorphic(expectedA, childL);

    setIt = cus.flatSetIterator();
    childL = new ArrayList(7);
    while (setIt.hasNext()) {
      childL.add(((CachedUrlSetNode) setIt.next()).getUrl());
    }

    expectedA =
        new String[] {
          urlRoot + "/001file.html",
          urlRoot + "/001file.txt",
          urlRoot + "/002file.html",
          urlRoot + "/002file.txt",
          urlRoot + "/branch1",
          urlRoot + "/branch2",
          urlRoot + "/index.html"
        };
    assertIsomorphic(expectedA, childL);
  }
 protected void checkLeaf(SimulatedArchivalUnit sau) {
   log.debug("checkLeaf()");
   String parent = sau.getUrlRoot() + "/branch1";
   CachedUrlSetSpec spec = new RangeCachedUrlSetSpec(parent);
   CachedUrlSet set = sau.makeCachedUrlSet(spec);
   Iterator setIt = set.contentHashIterator();
   ArrayList childL = new ArrayList(16);
   while (setIt.hasNext()) {
     childL.add(((CachedUrlSetNode) setIt.next()).getUrl());
   }
   String[] expectedA =
       new String[] {
         parent,
         parent + "/001file.html",
         parent + "/001file.txt",
         parent + "/002file.html",
         parent + "/002file.txt",
         parent + "/branch1",
         parent + "/branch1/001file.html",
         parent + "/branch1/001file.txt",
         parent + "/branch1/002file.html",
         parent + "/branch1/002file.txt",
         parent + "/branch1/index.html",
         parent + "/branch2",
         parent + "/branch2/001file.html",
         parent + "/branch2/001file.txt",
         parent + "/branch2/002file.html",
         parent + "/branch2/002file.txt",
         parent + "/branch2/index.html",
         parent + "/index.html",
       };
   assertIsomorphic(expectedA, childL);
 }
예제 #6
0
  /**
   * Get the active cipher suites.
   *
   * <p>In TLS 1.1, many weak or vulnerable cipher suites were obsoleted, such as
   * TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT negotiate these cipher suites in
   * TLS 1.1 or later mode.
   *
   * <p>Therefore, when the active protocols only include TLS 1.1 or later, the client cannot
   * request to negotiate those obsoleted cipher suites. That is, the obsoleted suites should not be
   * included in the client hello. So we need to create a subset of the enabled cipher suites, the
   * active cipher suites, which does not contain obsoleted cipher suites of the minimum active
   * protocol.
   *
   * <p>Return empty list instead of null if no active cipher suites.
   */
  CipherSuiteList getActiveCipherSuites() {
    if (activeCipherSuites == null) {
      if (activeProtocols == null) {
        activeProtocols = getActiveProtocols();
      }

      ArrayList<CipherSuite> suites = new ArrayList<>();
      if (!(activeProtocols.collection().isEmpty())
          && activeProtocols.min.v != ProtocolVersion.NONE.v) {
        for (CipherSuite suite : enabledCipherSuites.collection()) {
          if (suite.obsoleted > activeProtocols.min.v && suite.supported <= activeProtocols.max.v) {
            if (algorithmConstraints.permits(
                EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
              suites.add(suite);
            }
          } else if (debug != null && Debug.isOn("verbose")) {
            if (suite.obsoleted <= activeProtocols.min.v) {
              System.out.println("Ignoring obsoleted cipher suite: " + suite);
            } else {
              System.out.println("Ignoring unsupported cipher suite: " + suite);
            }
          }
        }
      }
      activeCipherSuites = new CipherSuiteList(suites);
    }

    return activeCipherSuites;
  }
예제 #7
0
 static Method[] getOverridableMethods(Class c) {
   ArrayList<Method> list = new ArrayList<Method>();
   HashSet<String> skip = new HashSet<String>();
   while (c != null) {
     Method[] methods = c.getDeclaredMethods();
     for (int i = 0; i < methods.length; i++) {
       String methodKey =
           methods[i].getName() + getMethodSignature(methods[i], methods[i].getParameterTypes());
       if (skip.contains(methodKey)) continue; // skip this method
       int mods = methods[i].getModifiers();
       if (Modifier.isStatic(mods)) continue;
       if (Modifier.isFinal(mods)) {
         // Make sure we don't add a final method to the list
         // of overridable methods.
         skip.add(methodKey);
         continue;
       }
       if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
         list.add(methods[i]);
         skip.add(methodKey);
       }
     }
     c = c.getSuperclass();
   }
   return list.toArray(new Method[list.size()]);
 }
예제 #8
0
  /*
   * Get the active protocol versions.
   *
   * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
   * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
   * negotiate these cipher suites in TLS 1.1 or later mode.
   *
   * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
   * only enabled cipher suite, the client cannot request TLS 1.1 or
   * later, even though TLS 1.1 or later is enabled.  We need to create a
   * subset of the enabled protocols, called the active protocols, which
   * contains protocols appropriate to the list of enabled Ciphersuites.
   *
   * Return empty list instead of null if no active protocol versions.
   */
  ProtocolList getActiveProtocols() {
    if (activeProtocols == null) {
      ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
      for (ProtocolVersion protocol : enabledProtocols.collection()) {
        boolean found = false;
        for (CipherSuite suite : enabledCipherSuites.collection()) {
          if (suite.isAvailable()
              && suite.obsoleted > protocol.v
              && suite.supported <= protocol.v) {
            if (algorithmConstraints.permits(
                EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
              protocols.add(protocol);
              found = true;
              break;
            } else if (debug != null && Debug.isOn("verbose")) {
              System.out.println("Ignoring disabled cipher suite: " + suite + " for " + protocol);
            }
          } else if (debug != null && Debug.isOn("verbose")) {
            System.out.println("Ignoring unsupported cipher suite: " + suite + " for " + protocol);
          }
        }
        if (!found && (debug != null) && Debug.isOn("handshake")) {
          System.out.println("No available cipher suite for " + protocol);
        }
      }
      activeProtocols = new ProtocolList(protocols);
    }

    return activeProtocols;
  }
예제 #9
0
파일: Tester.java 프로젝트: edemairy/TC
 String[] readFile(String fn) throws IOException {
   BufferedReader br = new BufferedReader(new FileReader(fn));
   String s;
   ArrayList al = new ArrayList();
   while ((s = br.readLine()) != null) {
     al.add(s);
   }
   return (String[]) al.toArray(new String[0]);
 }
예제 #10
0
  void isConnectable(SelectionKey k) {
    EventableSocketChannel ec = (EventableSocketChannel) k.attachment();
    long b = ec.getBinding();

    try {
      if (ec.finishConnecting()) eventCallback(b, EM_CONNECTION_COMPLETED, null);
      else UnboundConnections.add(b);
    } catch (IOException e) {
      UnboundConnections.add(b);
    }
  }
예제 #11
0
  void isWritable(SelectionKey k) {
    EventableChannel ec = (EventableChannel) k.attachment();
    long b = ec.getBinding();

    if (ec.isWatchOnly()) {
      if (ec.isNotifyWritable()) eventCallback(b, EM_CONNECTION_NOTIFY_WRITABLE, null);
    } else {
      try {
        if (!ec.writeOutboundData()) UnboundConnections.add(b);
      } catch (IOException e) {
        UnboundConnections.add(b);
      }
    }
  }
예제 #12
0
  /*
   * Convert an array of signers into an array of concatenated certificate
   * arrays.
   */
  private static java.security.cert.Certificate[] mapSignersToCertArray(CodeSigner[] signers) {

    if (signers != null) {
      ArrayList certChains = new ArrayList();
      for (int i = 0; i < signers.length; i++) {
        certChains.addAll(signers[i].getSignerCertPath().getCertificates());
      }

      // Convert into a Certificate[]
      return (java.security.cert.Certificate[])
          certChains.toArray(new java.security.cert.Certificate[certChains.size()]);
    }
    return null;
  }
예제 #13
0
  public long installOneshotTimer(int milliseconds) {
    long s = createBinding();
    long deadline = new Date().getTime() + milliseconds;

    if (Timers.containsKey(deadline)) {
      Timers.get(deadline).add(s);
    } else {
      ArrayList<Long> callbacks = new ArrayList<Long>();
      callbacks.add(s);
      Timers.put(deadline, callbacks);
    }

    return s;
  }
예제 #14
0
 static Method[] getOverridableMethods(Class<?> clazz) {
   ArrayList<Method> list = new ArrayList<Method>();
   HashSet<String> skip = new HashSet<String>();
   // Check superclasses before interfaces so we always choose
   // implemented methods over abstract ones, even if a subclass
   // re-implements an interface already implemented in a superclass
   // (e.g. java.util.ArrayList)
   for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
     appendOverridableMethods(c, list, skip);
   }
   for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
     for (Class<?> intf : c.getInterfaces()) appendOverridableMethods(intf, list, skip);
   }
   return list.toArray(new Method[list.size()]);
 }
예제 #15
0
  static String[] getFontList() {
    init();

    ArrayList fontNames = new ArrayList();
    Iterator fonts = fontNameMap.keySet().iterator();
    int dotidx;

    while (fonts.hasNext()) {
      String fontname = (String) fonts.next();
      if ((dotidx = fontname.indexOf('.')) == -1) dotidx = fontname.length();
      fontname = fontname.substring(0, dotidx);
      if (!fontNames.contains(fontname)) fontNames.add(fontname);
    }
    return (String[]) fontNames.toArray(new String[fontNames.size()]);
  }
예제 #16
0
  public static String[] getZipList(String zipFile) throws ZipException, IOException {
    File file = new File(zipFile);
    ZipFile zip = new ZipFile(file);
    Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
    ArrayList<String> files = new ArrayList<String>();

    // Process each entry
    while (zipFileEntries.hasMoreElements()) {
      // grab a zip file entry
      ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
      String currentEntry = entry.getName();
      files.add(currentEntry);
    }
    return files.toArray(new String[files.size()]);
  }
예제 #17
0
 /** Execute the system command 'cmd' and fill an ArrayList with the results. */
 public static ArrayList<String> executeSystemCommand(String cmd) {
   if (debug) System.out.println("cmd: " + cmd);
   ArrayList<String> list = new ArrayList<>();
   try (BufferedReader br =
       new BufferedReader(
           new InputStreamReader(RUNTIME.exec(/*comSpec +*/ cmd).getInputStream()))) {
     for (String line = null; (line = br.readLine()) != null; ) {
       if (debug) System.out.println(line);
       list.add(line);
     }
   } catch (IOException e) {
     e.printStackTrace();
   }
   return list;
 }
예제 #18
0
  /**
   * Parses a constructor type definition
   *
   * @param docConstructor
   * @return
   */
  protected static Constructor ParseConstructor(ConstructorDoc docConstructor) {
    assert (docConstructor != null);

    Constructor xmlConstructor = new Constructor();

    xmlConstructor.name = docConstructor.name();
    xmlConstructor.comment = docConstructor.commentText();
    xmlConstructor.scope = DetermineScope(docConstructor);
    xmlConstructor.isVarArgs = docConstructor.isVarArgs();
    xmlConstructor.isDefault =
        docConstructor.position().line() == docConstructor.containingClass().position().line();

    Parameter[] parameters = docConstructor.parameters();

    if (parameters != null && parameters.length > 0) {
      ParamTag[] paramComments = docConstructor.paramTags();

      ArrayList<Param> methodList = new ArrayList<Param>();

      for (Parameter parameter : parameters) {
        ParamTag paramComment = null;

        // look to see if this parameter has comments
        // if so, paramComment will be set
        for (ParamTag testParam : paramComments) {
          String testParamName = testParam.parameterName();
          if (testParamName != null) {
            if (testParamName.compareTo(parameter.name()) == 0) {
              paramComment = testParam;
              break;
            }
          }
        }

        methodList.add(ParseParameter(parameter, paramComment));
      }

      xmlConstructor.parameters = methodList.toArray(new Param[] {});
    } else {
      log.debug("No parameters for method: " + docConstructor.name());
    }

    // parse annotations for the constructor
    xmlConstructor.annotationInstances =
        ParseAnnotationInstances(docConstructor.annotations(), docConstructor.qualifiedName());

    return xmlConstructor;
  }
예제 #19
0
  void isReadable(SelectionKey k) {
    EventableChannel ec = (EventableChannel) k.attachment();
    long b = ec.getBinding();

    if (ec.isWatchOnly()) {
      if (ec.isNotifyReadable()) eventCallback(b, EM_CONNECTION_NOTIFY_READABLE, null);
    } else {
      myReadBuffer.clear();

      try {
        ec.readInboundData(myReadBuffer);
        myReadBuffer.flip();
        if (myReadBuffer.limit() > 0) {
          if (ProxyConnections != null) {
            EventableChannel target = ProxyConnections.get(b);
            if (target != null) {
              ByteBuffer myWriteBuffer = ByteBuffer.allocate(myReadBuffer.limit());
              myWriteBuffer.put(myReadBuffer);
              myWriteBuffer.flip();
              target.scheduleOutboundData(myWriteBuffer);
            } else {
              eventCallback(b, EM_CONNECTION_READ, myReadBuffer);
            }
          } else {
            eventCallback(b, EM_CONNECTION_READ, myReadBuffer);
          }
        }
      } catch (IOException e) {
        UnboundConnections.add(b);
      }
    }
  }
예제 #20
0
  void removeUnboundConnections() {
    ListIterator<Long> iter = UnboundConnections.listIterator(0);
    while (iter.hasNext()) {
      long b = iter.next();

      EventableChannel ec = Connections.remove(b);
      if (ec != null) {
        eventCallback(b, EM_CONNECTION_UNBOUND, null);
        ec.close();

        EventableSocketChannel sc = (EventableSocketChannel) ec;
        if (sc != null && sc.isAttached()) DetachedConnections.add(sc);
      }
    }
    UnboundConnections.clear();
  }
예제 #21
0
  void runTimers() {
    long now = new Date().getTime();
    while (!Timers.isEmpty()) {
      long k = Timers.firstKey();
      if (k > now) break;

      ArrayList<Long> callbacks = Timers.get(k);
      Timers.remove(k);

      // Fire all timers at this timestamp
      ListIterator<Long> iter = callbacks.listIterator(0);
      while (iter.hasNext()) {
        eventCallback(0, EM_TIMER_FIRED, null, iter.next().longValue());
      }
    }
  }
예제 #22
0
 /**
  * Checks for the next item.
  *
  * @return result of check
  * @throws IOException I/O exception
  */
 public boolean more() throws IOException {
   if (cache == null) {
     out.write(4);
     send(id);
     cache = new ArrayList<byte[]>();
     final ByteArrayOutputStream os = new ByteArrayOutputStream();
     while (in.read() > 0) {
       receive(in, os);
       cache.add(os.toByteArray());
       os.reset();
     }
     if (!ok()) throw new IOException(receive());
     pos = 0;
   }
   if (pos < cache.size()) return true;
   cache = null;
   return false;
 }
예제 #23
0
 public SocketChannel detachChannel(long sig) {
   EventableSocketChannel ec = (EventableSocketChannel) Connections.get(sig);
   if (ec != null) {
     UnboundConnections.add(sig);
     return ec.getChannel();
   } else {
     return null;
   }
 }
예제 #24
0
  private static PermissionInfo[] getPermissionInfos(URL resource, Framework framework) {
    if (resource == null) return null;
    PermissionInfo[] info = EMPTY_PERM_INFO;
    DataInputStream in = null;
    try {
      in = new DataInputStream(resource.openStream());
      ArrayList permissions = new ArrayList();
      BufferedReader reader;
      try {
        reader = new BufferedReader(new InputStreamReader(in, "UTF8")); // $NON-NLS-1$
      } catch (UnsupportedEncodingException e) {
        reader = new BufferedReader(new InputStreamReader(in));
      }

      while (true) {
        String line = reader.readLine();
        if (line == null) /* EOF */ break;
        line = line.trim();
        if ((line.length() == 0)
            || line.startsWith("#")
            || line.startsWith("//")) /* comments */ // $NON-NLS-1$ //$NON-NLS-2$
        continue;

        try {
          permissions.add(new PermissionInfo(line));
        } catch (IllegalArgumentException iae) {
          /* incorrectly encoded permission */
          if (framework != null)
            framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.getBundle(0), iae);
        }
      }
      int size = permissions.size();
      if (size > 0) info = (PermissionInfo[]) permissions.toArray(new PermissionInfo[size]);
    } catch (IOException e) {
      // do nothing
    } finally {
      try {
        if (in != null) in.close();
      } catch (IOException ee) {
        // do nothing
      }
    }
    return info;
  }
예제 #25
0
 private void invokeLater(Runnable task) {
   synchronized (taskWorkerLock) {
     if (isRunning() && mainThread != Thread.currentThread()) {
       tasks.add(task);
       taskWorkerLock.notifyAll();
     } else {
       // if !running or isEDTThread, do it right away
       task.run();
     }
   }
 }
예제 #26
0
  void removeUnboundConnections() {
    if (UnboundConnections.size() == 0) {
      return;
    }
    ArrayList<Long> currentUnboundConnections = UnboundConnections;
    // fix concurrent modification exception
    UnboundConnections = new ArrayList<Long>();
    for (long b : currentUnboundConnections) {
      EventableChannel ec = Connections.remove(b);
      if (ec != null) {
        if (ProxyConnections != null) {
          ProxyConnections.remove(b);
        }
        eventCallback(b, EM_CONNECTION_UNBOUND, null);
        ec.close();

        EventableSocketChannel sc = (EventableSocketChannel) ec;
        if (sc != null && sc.isAttached()) DetachedConnections.add(sc);
      }
    }
  }
예제 #27
0
  /**
   * Parse type variables for generics
   *
   * @param variables
   * @return
   */
  protected static TypeVar[] ParseTypeVariables(TypeVariable[] variables, ParamTag[] tags) {
    TypeVar[] vars = null;

    if (variables != null && variables.length > 0) {
      ArrayList<TypeVar> varsList = new ArrayList<TypeVar>();

      for (TypeVariable variable : variables) {
        TypeVar var = new TypeVar();
        var.name = variable.typeName();
        Type[] bounds = variable.bounds();
        if (bounds != null && bounds.length > 0) {
          ArrayList<String> list = new ArrayList<String>();

          for (Type bound : bounds) {
            list.add(bound.qualifiedTypeName());
          }

          var.bounds = list.toArray(new String[] {});
        }
        for (ParamTag tag : tags)
          if (tag.parameterName().equals(var.name)) var.comment = tag.parameterComment();

        varsList.add(var);
      }

      vars = varsList.toArray(new TypeVar[] {});
    }

    return vars;
  }
예제 #28
0
  private boolean invokeMethod(String line, PrintWriter out, Method method, String[] fields)
      throws IllegalAccessException, InvocationTargetException {
    ArrayList<Object> methodArguments = new ArrayList<Object>();

    Class<?>[] parameterTypes = method.getParameterTypes();
    if (parameterTypes.length == 2
        && parameterTypes[0] == PrintWriter.class
        && parameterTypes[1] == String.class) {
      // FIXME: there must be a better way to say "I want to parse the line myself."
      methodArguments.add(out);
      methodArguments.add(line);
    } else {
      int nextField = 1;
      for (Class<?> parameterType : parameterTypes) {
        if (parameterType == PrintWriter.class) {
          methodArguments.add(out);
        } else if (parameterType == String.class) {
          methodArguments.add(fields[nextField++]);
        }
        // FIXME: support other common types. "int" seems a likely first candidate.
      }
    }

    method.invoke(handler, methodArguments.toArray());
    return true;
  }
예제 #29
0
  public long attachChannel(SocketChannel sc, boolean watch_mode) {
    long b = createBinding();

    EventableSocketChannel ec = new EventableSocketChannel(sc, b, mySelector);

    ec.setAttached();
    if (watch_mode) ec.setWatchOnly();

    Connections.put(b, ec);
    NewConnections.add(b);

    return b;
  }
예제 #30
0
  public void run() {
    if (DEBUG) System.err.println("MainThread.run(): " + Thread.currentThread().getName());
    synchronized (taskWorkerLock) {
      isRunning = true;
      taskWorkerLock.notifyAll();
    }
    while (!shouldStop) {
      try {
        // wait for something todo ..
        synchronized (taskWorkerLock) {
          while (!shouldStop && tasks.size() == 0) {
            try {
              taskWorkerLock.wait();
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }

          // take over the tasks ..
          if (!shouldStop && tasks.size() > 0) {
            Runnable task = (Runnable) tasks.remove(0);
            task.run(); // FIXME: could be run outside of lock
          }
          taskWorkerLock.notifyAll();
        }
      } catch (Throwable t) {
        // handle errors ..
        t.printStackTrace();
      } finally {
        // epilog - unlock locked stuff
      }
    }
    if (DEBUG) System.err.println("MainThread.run(): " + Thread.currentThread().getName() + " fin");
    synchronized (taskWorkerLock) {
      isRunning = false;
      isExit = true;
      taskWorkerLock.notifyAll();
    }
  }