protected void doServletGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {

    String xml = req.getParameter("xml");
    if (xml != null) {
      if (xml.equalsIgnoreCase("yes")) {
        // output XML
        Object missedairings =
            SageApi.Api("GetAiringsThatWontBeRecorded", new Object[] {Boolean.FALSE});
        SendXmlResult(req, resp, missedairings, "recording_conflicts.xml");
        return;
      }
    }

    htmlHeaders(resp);
    noCacheHeaders(resp);
    PrintWriter out = getGzippedWriter(req, resp);
    // must catch and report all errors within Gzipped Writer
    try {
      xhtmlHeaders(out);
      out.println("<head>");
      jsCssImport(req, out);
      printMenu(out);
      out.println("<title>Recording Conflicts</title>");
      String rssurl = GetRssUrl(req, "Conflicts");
      out.println(
          "<link rel=\"alternate\" type=\"application/rss+xml\""
              + " href=\""
              + rssurl
              + "\""
              + " title=\"Sage Recording Conflicts RSS feed\"/>");

      out.println("</head>");
      out.println("<body>");
      out.println(
          String.format(
                  "<div id=\"menuContainer\"></div>%s<div id=\"title\">",
                  SageServlet.isTitleBroken(req) ? "<br/>" : "")
              + "<h1><a href=\"index.html\" title=\"home\"><img id=\"logoimg\" src=\"sagelogo.gif\" alt=\"SageTV logo\" title=\"Home Screen\" border=\"0\"/></a>Recording Conflicts\r\n"
              + "<a href=\""
              + GetXmlUrl(req)
              + "\" title=\"Return page in XML\"><img src=\"xml_button.png\" alt=\"[XML]\"/></a>\r\n"
              + "<a href=\""
              + rssurl
              + "\" title=\"RSS feed for this page\"><img src=\"rss_button.png\" alt=\"[RSS]\"/></a>\r\n"
              + "</h1></div>");
      out.println("<div id=\"content\">");

      Object UnresolvedConflicts =
          SageApi.Api("GetAiringsThatWontBeRecorded", new Object[] {Boolean.TRUE});
      Object missedairings =
          SageApi.Api("GetAiringsThatWontBeRecorded", new Object[] {Boolean.FALSE});

      if (SageApi.Size(missedairings) == 0) {
        out.println("<p>There are no conflicts to report at this time.</p>");
      } else {
        out.println(
            "<p>The following airings will not be recorded due to conflicts with other recordings:</p>");

        missedairings =
            SageApi.Api("Sort", new Object[] {missedairings, Boolean.FALSE, "GetAiringTitle"});
        missedairings =
            SageApi.Api("Sort", new Object[] {missedairings, Boolean.FALSE, "GetAiringStartTime"});

        for (int i = 0; i < SageApi.Size(missedairings); i++) {
          Object MissedAiring = SageApi.GetElement(missedairings, i);
          Airing airing = new Airing(MissedAiring);
          out.println("<div class=\"conflict\">");
          String descr = (String) SageApi.Api("PrintAiringShort", new Object[] {MissedAiring});
          Object MissedFavorite = SageApi.Api("GetFavoriteForAiring", new Object[] {MissedAiring});
          int faveid = 0;
          String favedesc = null;
          if (MissedFavorite != null) {
            faveid = SageApi.IntApi("GetFavoriteID", new Object[] {MissedFavorite});
            favedesc =
                (String) SageApi.Api("GetFavoriteDescription", new Object[] {MissedFavorite});
          }
          boolean isUnresolved = false;
          out.print("<h3><a name=\"AiringId" + airing.id + "\">");
          if (SageApi.Size(
                  SageApi.Api("DataIntersection", new Object[] {UnresolvedConflicts, MissedAiring}))
              > 0) {
            isUnresolved = true;
            out.println(
                "<img src=\"conflicticon.gif\" title=\"Unresolved Conflict\" alt=\"Unresolved Conflict\"/>");
          } else {
            out.println(
                "<img src=\"resolvedconflicticon.gif\" title=\"Resolved Conflict\" alt=\"Resolved Conflict\"/>");
          }

          out.println(
              "</a><a href=\"DetailedInfo?"
                  + airing.getIdArg()
                  + "\" title=\"Show detailed info\">"
                  + Translate.encode(descr)
                  + "</a>");
          if (MissedFavorite != null) {
            out.println(
                "<br/><a href=\"FavoriteDetails?FavoriteId="
                    + faveid
                    + "\" title=\"Show Favorite Details\">from favourite: "
                    + Translate.encode(favedesc)
                    + "</a></h3>");
          }

          // find conflicts
          Object channel = SageApi.Api("GetChannel", new Object[] {MissedAiring});
          Object starttime = SageApi.Api("GetScheduleStartTime", new Object[] {MissedAiring});
          Object endtime = SageApi.Api("GetScheduleEndTime", new Object[] {MissedAiring});

          Vector<Object> ConflictingManuals = new Vector<Object>();
          Vector<Object> ConflictingSingleFavourites = new Vector<Object>();
          Vector<Object> ConflictingFavorites = new Vector<Object>();

          Object inputs = SageApi.Api("GetConfiguredCaptureDeviceInputs");
          for (int inpnum = 0; inpnum < SageApi.Size(inputs); inpnum++) {
            Object input = SageApi.GetElement(inputs, inpnum);
            Object lineup = SageApi.Api("GetLineupForCaptureDeviceInput", new Object[] {input});
            if (SageApi.booleanApi("IsChannelViewableOnLineup", new Object[] {channel, lineup})) {
              Object capdev = SageApi.Api("GetCaptureDeviceForInput", new Object[] {input});
              // System.out.println("got capdev"+capdev.toString());
              Object overlaps =
                  SageApi.Api(
                      "GetScheduledRecordingsForDeviceForTime",
                      new Object[] {capdev, starttime, endtime});
              // System.out.println("got "+SageApi.Size(overlaps)+" overlpas");
              for (int ovlapnum = 0; ovlapnum < SageApi.Size(overlaps); ovlapnum++) {
                Object ConflictingRecord = SageApi.GetElement(overlaps, ovlapnum);
                if (((Boolean) SageApi.Api("IsManualRecord", new Object[] {ConflictingRecord}))
                    .booleanValue()) {
                  ConflictingManuals.add(ConflictingRecord);
                } else {
                  ConflictingSingleFavourites.add(ConflictingRecord);
                  Object OtherFavorite =
                      SageApi.Api("GetFavoriteForAiring", new Object[] {ConflictingRecord});
                  long OtherFavouriteTime =
                      ((Long) SageApi.Api("GetScheduleStartTime", new Object[] {ConflictingRecord}))
                          .longValue();
                  Date now = new Date();
                  if (OtherFavorite != null
                      && !OtherFavorite.equals(MissedFavorite)
                      && OtherFavouriteTime > now.getTime())
                    ConflictingFavorites.add(OtherFavorite);
                }
              }
            }
          }
          out.println("<div class=\"resolution\"><ul>");

          if (isUnresolved
              && ConflictingManuals.size() > 0
              && ConflictingSingleFavourites.size() == 0
              && ConflictingFavorites.size() == 0) {
            out.println(
                "<li>"
                    + "<form method=\"post\" action=\"ResolveConflict\">"
                    + "<input type=\"hidden\" name=\"command\" value=\"ConfirmManRecOverride\"/>"
                    + "<input type=\"hidden\" name=\"returnto\" value=\"Conflicts\"/>"
                    + "<input type=\"hidden\" name=\"missedAiringId\" value=\""
                    + airing.id
                    + "\"/>"
                    + "<input type=\"submit\" value=\"Ignore this conflict\"/></form>"
                    + "</li>");
          }
          // conflicting manuals
          for (Iterator<Object> it = ConflictingManuals.iterator(); it.hasNext(); ) {
            Object conflict = it.next();
            Airing cfair = new Airing(conflict);

            out.println(
                "<li>"
                    + "<form method=\"post\" action=\"ManualRecord\">"
                    + "<input type=\"hidden\" name=\"command\" value=\"CancelRecord\"/>"
                    + "<input type=\"hidden\" name=\"returnto\" value=\"Conflicts\"/>"
                    + "<input type=\"hidden\" name=\"AiringId\" value=\""
                    + cfair.id
                    + "\"/>"
                    + "<input type=\"submit\" value=\"Cancel the manual recording\"/>"
                    + " of <a title=\"View detailed info\" href=\"DetailedInfo?"
                    + cfair.getIdArg()
                    + "\">"
                    + Translate.encode(cfair.getAiringShortDescr())
                    + "</a>"
                    + "</form></li>");
          }
          if (MissedFavorite != null) {
            for (Iterator<Object> it = ConflictingSingleFavourites.iterator(); it.hasNext(); ) {
              Object conflict = it.next();
              Airing cfair = new Airing(conflict);

              out.println(
                  "<li>"
                      + "<form method=\"post\" action=\"ManualRecord\">"
                      + "<input type=\"hidden\" name=\"command\" value=\"Record\"/>"
                      + "<input type=\"hidden\" name=\"returnto\" value=\"Conflicts\"/>"
                      + "<input type=\"hidden\" name=\"AiringId\" value=\""
                      + airing.id
                      + "\"/>"
                      + "<input type=\"submit\" value=\"Override the single favourite recording\"/>"
                      + " of <a href=\"DetailedInfo?"
                      + cfair.getIdArg()
                      + "\">"
                      + Translate.encode(cfair.getAiringShortDescr())
                      + "</a>"
                      + "</form></li>");
            }
            for (Iterator<Object> it = ConflictingFavorites.iterator(); it.hasNext(); ) {
              Object cffave = it.next();
              int cffaveid = SageApi.IntApi("GetFavoriteID", new Object[] {cffave});
              String cffavedesc =
                  SageApi.StringApi("GetFavoriteDescription", new Object[] {cffave});

              out.println(
                  "<li>"
                      + "<form method=\"post\" action=\"ResolveConflict\">"
                      + "<input type=\"hidden\" name=\"command\" value=\"FavoriteOverride\"/>"
                      + "<input type=\"hidden\" name=\"returnto\" value=\"Conflicts\"/>"
                      + "<input type=\"hidden\" name=\"newpriofaveid\" value=\""
                      + faveid
                      + "\"/>"
                      + "<input type=\"hidden\" name=\"oldfaveid\" value=\""
                      + cffaveid
                      + "\"/>"
                      + "<input type=\"submit\" value=\"ALWAYS have\"/>"
                      + " <a href=\"FavoriteDetails?FavoriteId="
                      + faveid
                      + "\" title=\"Show Favorite Details\">favorite "
                      + Translate.encode(favedesc)
                      + "</a>"
                      + " override "
                      + "<a href=\"FavoriteDetails?FavoriteId="
                      + cffaveid
                      + "\" title=\"Show Favorite Details\">favorite "
                      + Translate.encode(cffavedesc)
                      + "</a>"
                      + "</form></li>");
              out.println(
                  "<li>"
                      + "<form method=\"post\" action=\"ResolveConflict\">"
                      + "<input type=\"hidden\" name=\"command\" value=\"FavoriteOverride\"/>"
                      + "<input type=\"hidden\" name=\"returnto\" value=\"Conflicts\"/>"
                      + "<input type=\"hidden\" name=\"newpriofaveid\" value=\""
                      + cffaveid
                      + "\"/>"
                      + "<input type=\"hidden\" name=\"oldfaveid\" value=\""
                      + faveid
                      + "\"/>"
                      + "<input type=\"submit\" value=\"ALWAYS have\"/>"
                      + " <a href=\"FavoriteDetails?FavoriteId="
                      + cffaveid
                      + "\" title=\"Show Favorite Details\">favorite "
                      + Translate.encode(cffavedesc)
                      + "</a>"
                      + " override "
                      + "<a href=\"FavoriteDetails?FavoriteId="
                      + faveid
                      + "\" title=\"Show Favorite Details\">favorite "
                      + Translate.encode(favedesc)
                      + "</a>"
                      + "</form></li>");
            }
          }
          if (((Boolean) SageApi.Api("IsManualRecord", new Object[] {MissedAiring}))
              .booleanValue()) {
            out.println(
                "<li>"
                    + "<form method=\"post\" action=\"ManualRecord\">"
                    + "<input type=\"hidden\" name=\"command\" value=\"CancelRecord\"/>"
                    + "<input type=\"hidden\" name=\"returnto\" value=\"Conflicts\"/>"
                    + "<input type=\"hidden\" name=\"AiringId\" value=\""
                    + airing.id
                    + "\"/>"
                    + "<input type=\"submit\" value=\"Cancel the manual recording\"/>"
                    + " of <a title=\"View detailed info\" href=\"DetailedInfo?"
                    + airing.getIdArg()
                    + "\">"
                    + Translate.encode(airing.getAiringShortDescr())
                    + "</a>"
                    + "</form></li>");
          }

          out.println("</ul>");
          out.println("</div>"); // resolution
          out.println("</div>"); // conflict
        }
      }
      printFooter(req, out);
      out.println("</div>"); // content
      printMenu(req, out);
      out.println("</body></html>");
      out.close();
    } catch (Throwable e) {
      if (!resp.isCommitted()) {
        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        resp.setContentType("text/html");
      }
      out.println();
      out.println();
      out.println("<body><pre>");
      out.println("Exception while processing servlet:\r\n" + e.toString());
      e.printStackTrace(out);
      out.println("</pre>");
      out.close();
      log("Exception while processing servlet", e);
    }
  }
  /* (non-Javadoc)
   * @see net.sf.sageplugins.webserver.SageServlet#doServletGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  protected void doServletGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {

    String encodername = req.getParameter("encoder");
    Object encoder = null;
    Object encoders = SageApi.Api("GetActiveCaptureDevices");
    Object filelist;

    if (encodername == null || encodername.equals("all")) {
      encodername = null;
      filelist = SageApi.Api("GetScheduledRecordings");
    } else {
      for (int i = 0; i < SageApi.Size(encoders); i++)
        if (encodername.equals(SageApi.GetElement(encoders, i).toString())) {
          encoder = SageApi.GetElement(encoders, i);
          break;
        }
      if (encoder == null) {
        filelist = SageApi.Api("GetScheduledRecordings");
      } else {
        filelist = SageApi.Api("GetScheduledRecordingsForDevice", new Object[] {encoder});
      }
    }
    /*
    FROM STV:
    Schedule = GetScheduledRecordings()
    IF Size(GetProperty("recording_schedule_filter", "")) > 0
    Schedule = FilterByBoolMethod(Schedule, GetProperty("recording_schedule_filter", ""), true)
    */

    String filter =
        GetOptionOrProfile(
            req,
            FILTER_OPTS,
            "recording_schedule_filter",
            "recording_schedule_filter",
            "##AsSageTV##",
            "");
    if (filter != null && filter.length() > 0) {
      try {
        filelist = SageApi.Api("FilterByBoolMethod", new Object[] {filelist, filter, Boolean.TRUE});
      } catch (InvocationTargetException e) {
        log("filtering on " + filter + " failed", e);
      }
    }

    String xml = req.getParameter("xml");
    if (xml != null) {
      if (xml.equalsIgnoreCase("yes")) {
        // output XML
        SendXmlResult(req, resp, filelist, "recording_schedule.xml");
        return;
      }
    }

    htmlHeaders(resp);
    noCacheHeaders(resp);
    PrintWriter out = getGzippedWriter(req, resp);
    // must catch and report all errors within Gzipped Writer
    try {
      xhtmlHeaders(out);
      out.println("<head>");
      jsCssImport(req, out);
      printMenu(out);
      String rssurl = GetRssUrl(req, "RecordingSchedule");
      out.println("<title>Recording Schedule</title>");
      out.println(
          "<link rel=\"alternate\" type=\"application/rss+xml\""
              + " href=\""
              + rssurl.toString()
              + "\""
              + " title=\"Sage Recording Schedule RSS feed\"/>");

      out.println("</head>");
      out.println("<body>");
      out.println(
          String.format(
                  "<div id=\"menuContainer\"></div>%s<div id=\"title\">",
                  SageServlet.isTitleBroken(req) ? "<br/>" : "")
              + "<h1><a href=\"index.html\" title=\"home\"><img id=\"logoimg\" src=\"sagelogo.gif\" alt=\"SageTV logo\" title=\"Home Screen\" border=\"0\"/></a>Recording Schedule\r\n"
              + "<a href=\""
              + GetXmlUrl(req)
              + "\" title=\"Return page in XML\"><img src=\"xml_button.png\" alt=\"[XML]\"/></a>\r\n"
              + "<a href=\""
              + rssurl.toString()
              + "\" title=\"RSS feed for this page\"><img src=\"rss_button.png\" alt=\"[RSS]\"/></a>\r\n"
              + "</h1></div>");

      out.println("<div id=\"content\">");
      if (encodername != null && encoder == null) {
        out.println("<h3>Error: unknown encoder: " + encodername + "</h3>");
      }

      out.println("<form action=\"" + req.getRequestURI() + "\" method=\"get\">");
      out.println(" For encoder: ");
      out.println("  <select name=\"encoder\" onchange=\"this.form.submit()\">");
      out.print("  <option value=\"all\"");
      if (encodername == null) out.print(" selected=\"selected\"");
      out.println(">all</option>");

      for (int i = 0; i < SageApi.Size(encoders); i++) {
        Object thisenc = SageApi.GetElement(encoders, i);
        out.print("  <option value=\"" + thisenc.toString() + "\"");
        if (thisenc == encoder) out.print(" selected=\"selected\"");
        out.println(">" + Translate.encode(thisenc.toString()) + "</option>");
      }
      out.println(
          "    </select>\r\n" + "      <input type=\"submit\" value=\"Refresh\"/>\r\n" + "</form>");
      out.println("<form name=\"AiringsForm\" method=\"get\" action=\"AiringCommand\">");
      out.print(
          "<input type=\"hidden\" name=\"returnto\" value=\""
              + req.getRequestURI()
              + "?"
              + req.getQueryString()
              + "\"/>");

      // get Rec sched
      boolean showFileSize = false;
      Object allConflicts =
          SageApi.Api("GetAiringsThatWontBeRecorded", new Object[] {Boolean.FALSE});
      Object unresolvedConflicts =
          SageApi.Api("GetAiringsThatWontBeRecorded", new Object[] {Boolean.TRUE});

      AiringList.PrintPagedAiringList(
          this,
          out,
          filelist,
          req,
          true,
          true,
          showFileSize,
          filelist,
          allConflicts,
          unresolvedConflicts,
          0);

      out.println("Action on selected: <select name=\"command\">\r\n");
      printOptionsList(out, AiringCommandServlet.AIRING_ACTIONS_OPT, null);
      out.println("</select><input type=\"submit\" value=\"Set\"/>");
      out.println("</form>\r\n");

      out.println(
          "<div id=\"options\" class=\"options\">\r\n"
              + "<h2><a name=\"options\">Sage Recording Schedule Display Options:</a></h2>\r\n"
              + "<form method='get' action='SetOptions'>\r\n"
              + "<input type=\"hidden\" name=\"returnto\" value=\"RecordingSchedule\"/>\r\n"
              + "<dl><dt>Filter&nbsp;by:&nbsp;</dt><dd>");
      PrintOptionsDropdown(
          req,
          out,
          "recording_schedule_filter",
          "recording_schedule_filter",
          "##AsSageTV##",
          FILTER_OPTS);
      out.println("</dd><dt>Channel&nbsp;Logos:&nbsp;</dt><dd>");
      PrintOptionsDropdown(req, out, "UseChannelLogos", "true", ENABLE_DISABLE_OPTS);
      out.println("</dd><dt>Show&nbsp;Markers:&nbsp;</dt><dd>");
      PrintOptionsDropdown(req, out, "ShowMarkers", "true", ENABLE_DISABLE_OPTS);
      out.println("</dd><dt>Show&nbsp;Ratings:&nbsp;</dt><dd>");
      PrintOptionsDropdown(req, out, "ShowRatings", "true", ENABLE_DISABLE_OPTS);
      out.println("</dd><dt>Include&nbsp;EpisodeID:&nbsp;</dt><dd>");
      PrintOptionsDropdown(req, out, "ShowEpisodeID", "false", ENABLE_DISABLE_OPTS);
      out.println("</dd><dt>Results&nbsp;Per&nbsp;Page</dt><dd>");
      PrintOptionsDropdown(
          req,
          out,
          "pagelen",
          Integer.toString(AiringList.DEF_NUM_ITEMS),
          AiringList.NUM_ITEMS_PER_PAGE_OPTS);
      out.println(
          "</dd></dl><noscript><input type=\"submit\" value=\"SetOptions\"/></noscript></form>");
      out.println(
          "</div>\r\n"
              + // options
              "<script type=\"text/javascript\">hideOptions();</script>");

      printFooter(req, out);
      out.println("</div>"); // content
      printMenu(req, out);
      out.println("</body></html>");
      out.close();
    } catch (Throwable e) {
      if (!resp.isCommitted()) {
        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        resp.setContentType("text/html");
      }
      out.println();
      out.println();
      out.println("<body><pre>");
      out.println("Exception while processing servlet:\r\n" + e.toString());
      e.printStackTrace(out);
      out.println("</pre>");
      out.close();
      log("Exception while processing servlet", e);
    }
  }