void processTask(ETask task, ObjectMessage msg, EntityManager em) {
    EMethod method;
    EModel model;
    Collection<EBounds> bounds;
    TaskMessage tm;

    System.out.println("Processing task [id=" + String.valueOf(task.getId()) + "]...");

    method = task.getMethod();
    model = task.getModel();
    bounds = getBoundsForModel(model, em);

    try {
      tm = (TaskMessage) msg.getObject();
      if (method.getIdent().equals(EMethod.fba)) {
        FbaMethod.run(task, model, bounds);
      } else if (method.getIdent().equals(EMethod.fva)) {
        FvaMethod.run(task, model, bounds, (MultipleReactionsTaskMessage) tm);
      } else if (method.getIdent().equals(EMethod.rscan)) {
        RscanMethod.run(task, model, bounds, (MultipleReactionsTaskMessage) tm);
      } else if (method.getIdent().equals(EMethod.kgene)) {
        KgeneMethod.run(task, model, bounds);
      }
      msg.acknowledge();
    } catch (AmkfbaException e) {
      AcornLogger.logError("AmkfbaException: " + e.getMessage());
      markAsBroken(task, em);
    } catch (JMSException e) {
      e.printStackTrace(System.err);
      throw new Error("JMSException, aborting...");
    }
  }
  void markAsBroken(ETask task, EntityManager em) {
    EntityTransaction et = em.getTransaction();

    et.begin();
    task.setStatus(ETask.statusSysError);
    et.commit();
  }
  public void run() throws Exception {
    EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
    EntityManager em = emf.createEntityManager();

    setupMessageListener();

    ETask task;
    try {
      while (true) {
        ObjectMessage msg;
        TaskMessage tm;
        Message mm;

        System.out.println("Waiting for message...");
        mm = receiver.receive();

        System.out.println("Message received");

        if (mm instanceof ObjectMessage) {
          msg = (ObjectMessage) mm;
          tm = (TaskMessage) msg.getObject();
          try {
            task =
                (ETask)
                    em.createNamedQuery("ETask.findById")
                        .setParameter("id", tm.getTaskId())
                        .setHint("toplink.refresh", true)
                        .getSingleResult();

            if (!task.getStatus().equals(ETask.statusSysError)) {
              processTask(task, msg, em);
            } else {
              System.out.println("Task marked as broken, omitting.");
            }

          } catch (NoResultException e) {
            System.out.println("Task has been deleted");
          }
        }
        mm.acknowledge();
      }
    } finally {
      closeReceiver();
      PersistenceManager.getInstance().closeEntityManagerFactory();
    }
  }