public boolean packetArrived(PacketArrivedEvent evt) throws MathLinkException {
    KernelLink ml = (KernelLink) evt.getSource();

    if (evt.getPktType() == MathLink.TEXTPKT) {
      resources.add(new Resource(evt.getPktType(), ml.getString()));
    }

    if (evt.getPktType() == MathLink.MESSAGEPKT) {
      resources.add(new Resource(evt.getPktType(), ml.getString()));
    }

    for (Field field : MathLink.class.getFields()) {
      if (field.getName().endsWith("PKT")) {
        try {
          if (evt.getPktType() == field.getInt(field)) {
            System.out.println(
                "Received Mathematica Packet: " + field.getName() + " (" + evt.getPktType() + ")");
          }
        } catch (IllegalArgumentException e) {
          System.out.println(e.getMessage());
        } catch (IllegalAccessException e) {
          System.out.println(e.getMessage());
        }
      }
    }

    return true;
  }
  public void reconnect() throws MathLinkException {
    kernelLink.removePacketListener(this);
    kernelLink.close();

    kernelLink = MathLinkFactory.createKernelLink(mlargs);
    kernelLink.addPacketListener(this);
    kernelLink.discardAnswer();
  }
  public void evaluate(String query, boolean evalToImage, Session session)
      throws MathLinkException, IOException {
    int currentResource = -1;
    long mark = System.currentTimeMillis();

    session.sendInline("<div id='resource_" + currentCount + "' class='cellgroup'>");

    // Log the input
    Resource input = new Resource(query);
    resources.add(input);
    currentResource = resources.size();
    session.sendInline(input.render(true));

    kernelLink.evaluate(query);
    kernelLink.waitForAnswer();
    Expr result = kernelLink.getExpr();

    // Append intermediate packets received by listener callback
    while (currentResource < resources.size()) {
      session.sendInline(resources.get(currentResource).render(true));
      currentResource++;
    }

    if (!result.equals(NULLEXPR)) {
      // Log the output as fullform text
      Resource textResource = new Resource(MathLink.RETURNPKT, result);
      byte[] data = null;

      if (evalToImage || textResource.isGraphics()) data = kernelLink.evaluateToImage(result, 0, 0);

      if (data != null) {
        Resource graphicsResource = new Resource(MathLink.DISPLAYPKT, data);
        resources.add(graphicsResource);
        session.sendInline(graphicsResource.render(true));
        textResource.subdue();
        session.sendInline(textResource.render(false));
      } else {
        session.sendInline(textResource.render(true));
      }

      resources.add(textResource);
    }

    // Done with this. Move on...
    kernelLink.newPacket();
    currentCount++;

    input.setTime(System.currentTimeMillis() - mark);
    session.sendInline("<div class='time'>" + commify(input.getTime()) + "ms</div></div>");
  }
  public Resources(String sessionId, String cacheFolder, String[] mlargs)
      throws MathLinkException, IOException {
    this.sessionId = sessionId;
    this.cacheFolder = cacheFolder;
    this.mlargs = mlargs;
    this.resources = new ArrayList<Resources.Resource>();

    // Allocate the kernel link and register packet listener
    kernelLink = MathLinkFactory.createKernelLink(mlargs);
    kernelLink.addPacketListener(this);
    kernelLink.discardAnswer();

    // Create cache folder
    File sessionFolderPointer = getSessionFolder();
    if (sessionFolderPointer.exists()) delete(sessionFolderPointer);
    sessionFolderPointer.mkdir();
  }
  public void close() {
    // Close the kernel link
    kernelLink.close();

    // Release all allocated resources
    release();

    // Delete the cache folder (it should be empty now)
    File cacheFp = getSessionFolder();
    if (cacheFp.exists()) cacheFp.delete();
  }
  public String getSuggestions() throws MathLinkException, ExprFormatException {
    StringBuilder result = new StringBuilder();
    result.append("[");

    kernelLink.evaluate("$ContextPath");
    kernelLink.waitForAnswer();
    Expr contexts = kernelLink.getExpr();

    for (int j = 1; j <= contexts.length(); j++) {
      String context = contexts.part(j).asString();
      kernelLink.evaluate("Names[\"" + context + "*\"]");
      kernelLink.waitForAnswer();
      Expr symbols = kernelLink.getExpr();

      for (int i = 1; i <= symbols.length(); i++) {
        result.append('"');
        result.append(symbols.part(i).asString());
        result.append('"');
        result.append(",");
      }
    }

    result.append("]");
    return result.toString();
  }