@Override
  public Response serve(String uri, String method, Properties header, Properties parms) {
    if (!uri.equals("/mediaserver")) {
      return super.serve(uri, method, header, parms); // this way we can
      // also serve up
      // normal files and
      // content
    }

    logger.fine(method + " '" + uri + "' ");

    Enumeration<?> e = header.propertyNames();
    while (e.hasMoreElements()) {
      String value = (String) e.nextElement();
      logger.fine("  HDR: '" + value + "' = '" + header.getProperty(value) + "'");
    }
    e = parms.propertyNames();
    while (e.hasMoreElements()) {
      String value = (String) e.nextElement();
      logger.fine("  PRM: '" + value + "' = '" + parms.getProperty(value) + "'");
    }

    // TODO: check the actual path...

    final String mediaPath = parms.getProperty("media");
    final String outputFormatStr = parms.getProperty("format");
    final String mimeType = parms.getProperty("mime");
    logger.info("requested media: " + mediaPath);
    logger.info("requested mime type: " + mimeType);
    if (mediaPath == null)
      return new Response(HTTP_FORBIDDEN, "text/plain", "mediaPath parameter not specified");
    if (mimeType == null)
      return new Response(HTTP_FORBIDDEN, "text/plain", "mimeType parameter not specified");

    // TODO: if we aren't performing any transcoding, just serve the file up
    // directly.
    // TODO: capture sources need to be treated as singletons, with some
    // kind of broadcasting/cloning to ensure
    // that multiple connections can be made.

    final String serverSideUrlStr = mediaPath; // URLUtils.createUrlStr(new
    // File(mediaPath)); // TODO:
    // enforce that we can't just
    // serve up anything anywhere
    final ContentDescriptor outputContentDescriptor =
        new FileTypeDescriptor(ContentDescriptor.mimeTypeToPackageName(mimeType));

    final Format outputFormat;
    if (outputFormatStr == null) {
      outputFormat = null;
    } else {
      try {
        outputFormat = FormatArgUtils.parse(outputFormatStr);
      } catch (ParseException e1) {
        logger.log(Level.WARNING, "" + e1, e1);
        return new Response(HTTP_FORBIDDEN, "text/plain", "" + e1);
      }
    }

    logger.info("serverSideUrlStr: " + serverSideUrlStr);
    logger.info("outputContentDescriptor: " + outputContentDescriptor);
    logger.info("outputFormat: " + outputFormat);

    final InputStream is;
    try {
      is = getInputStream(serverSideUrlStr, outputFormat, outputContentDescriptor);
    } catch (Exception e1) {
      return new Response(HTTP_FORBIDDEN, "text/plain", "" + e1);
    }

    final String responseMimeType;
    // workaround for the problem that the multipart/x-mixed-replace
    // boundary is not stored anywhere.
    // this assumes that if we are serving multipart/x-mixed-replace data,
    // that MultipartMixedReplaceMux is being used.
    if (mimeType.equals("multipart/x-mixed-replace"))
      responseMimeType = mimeType + ";boundary=" + MultipartMixedReplaceMux.BOUNDARY;
    else responseMimeType = mimeType;
    logger.info("Response mime type: " + responseMimeType);
    return new Response(HTTP_OK, responseMimeType, is);
  }
  public WebcamCaptureAndFadePanel(String saveDir, String layout) {

    System.out.println("Using " + saveDir + " as directory for the images.");
    saveDirectory = saveDir;

    getImages();
    images_used = new ArrayList<Integer>();
    images_lastadded = new ArrayList<Integer>();
    images_nevershown = new ArrayList<Integer>();

    Vector devices = (Vector) CaptureDeviceManager.getDeviceList(null).clone();
    Enumeration enumeration = devices.elements();
    System.out.println("- Available cameras -");
    ArrayList<String> names = new ArrayList<String>();
    while (enumeration.hasMoreElements()) {
      CaptureDeviceInfo cdi = (CaptureDeviceInfo) enumeration.nextElement();
      String name = cdi.getName();
      if (name.startsWith("vfw:")) {
        names.add(name);
        System.out.println(name);
      }
    }

    // String str1 = "vfw:Logitech USB Video Camera:0";
    // String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    if (names.size() == 0) {
      JOptionPane.showMessageDialog(
          null,
          "Ingen kamera funnet. " + "Du må koble til et kamera for å kjøre programmet.",
          "Feil",
          JOptionPane.ERROR_MESSAGE);
      System.exit(0);
    } else if (names.size() > 1) {

      JOptionPane.showMessageDialog(
          null,
          "Fant mer enn 1 kamera. " + "Velger da:\n" + names.get(0),
          "Advarsel",
          JOptionPane.WARNING_MESSAGE);
    }

    String str2 = names.get(0);
    di = CaptureDeviceManager.getDevice(str2);
    ml = di.getLocator();

    try {
      player = Manager.createRealizedPlayer(ml);
      formatControl = (FormatControl) player.getControl("javax.media.control.FormatControl");

      /*
      Format[] formats = formatControl.getSupportedFormats();
      for (int i=0; i<formats.length; i++)
      	System.out.println(formats[i].toString());
      */

      player.start();
    } catch (javax.media.NoPlayerException e) {
      JOptionPane.showMessageDialog(
          null,
          "Klarer ikke å starte" + " programmet pga. feil med kamera. Sjekk at det er koblet til.",
          "IOException",
          JOptionPane.ERROR_MESSAGE);
      System.exit(0);
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(0);
    }

    /*
     * Layout
     *
     * Add
     * - comp
     * - imagepanels
     */

    if (layout.equals("1024v2")) {
      layout1024v2();
    } else if (layout.equals("1280")) {
      layout1280();
    } else {
      layout1024();
    }

    // Capture Window
    if (captureWindow) {
      cw = new JFrame("Capture from webcam");
      cw.setAlwaysOnTop(true);
      cw.setSize(sizeCaptureWindow_x, sizeCaptureWindow_y);
      cw.addKeyListener(new captureWindowKeyListner());
      cw.setUndecorated(true);

      // Add webcam
      if ((comp = player.getVisualComponent()) != null) {
        cw.add(comp);
      }

      // Add panel to window and set location of window
      cw.setLocation(cwLocation_x, cwLocation_y);
    }

    // Text window
    cwText = new rotatedText("");

    /*
     * Timer for update
     */
    Timer thread = new Timer();
    thread.schedule(new frameUpdateTask(), 0, (1000 / fps));
  }